diff --git a/.gitignore b/.gitignore index 090b293b87792a815cf51aeccb590ec37c90cfa3..9c0d650385bea274a551eae45b032f2cdfeb925b 100644 --- a/.gitignore +++ b/.gitignore @@ -54,6 +54,5 @@ series cscope.* *.orig -*.rej *~ \#*# diff --git a/Documentation/cgroups.txt b/Documentation/cgroups.txt index c298a6690e0d67700b08b933a65a3eb4fd97cd96..824fc02744719ecb02b29177c11c55034229af35 100644 --- a/Documentation/cgroups.txt +++ b/Documentation/cgroups.txt @@ -310,8 +310,8 @@ and then start a subshell 'sh' in that cgroup: cd /dev/cgroup mkdir Charlie cd Charlie - /bin/echo 2-3 > cpus - /bin/echo 1 > mems + /bin/echo 2-3 > cpuset.cpus + /bin/echo 1 > cpuset.mems /bin/echo $$ > tasks sh # The subshell 'sh' is now running in cgroup Charlie diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 3c35d452b1a968439cdbb2b270bcaa75b26b762d..5b3f31faed56872b84fbd293494613f6d627a987 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -289,6 +289,14 @@ Who: Glauber Costa --------------------------- +What: old style serial driver for ColdFire (CONFIG_SERIAL_COLDFIRE) +When: 2.6.28 +Why: This driver still uses the old interface and has been replaced + by CONFIG_SERIAL_MCF. +Who: Sebastian Siewior + +--------------------------- + What: /sys/o2cb symlink When: January 2010 Why: /sys/fs/o2cb is the proper location for this information - /sys/o2cb diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index c2992bc54f2f49f0f7caee130acf19205df7511a..8b22d7d8b99166b6db2e037644e9c5d7ff03695e 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking @@ -92,7 +92,6 @@ prototypes: void (*destroy_inode)(struct inode *); void (*dirty_inode) (struct inode *); int (*write_inode) (struct inode *, int); - void (*put_inode) (struct inode *); void (*drop_inode) (struct inode *); void (*delete_inode) (struct inode *); void (*put_super) (struct super_block *); @@ -115,7 +114,6 @@ alloc_inode: no no no destroy_inode: no dirty_inode: no (must not sleep) write_inode: no -put_inode: no drop_inode: no !!!inode_lock!!! delete_inode: no put_super: yes yes no diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index 81e5be6e6e356e8ab3feb4e92b972fd0862db1a9..b7522c6cbae3758f77cb12e22b78825e43a3796d 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt @@ -205,7 +205,6 @@ struct super_operations { void (*dirty_inode) (struct inode *); int (*write_inode) (struct inode *, int); - void (*put_inode) (struct inode *); void (*drop_inode) (struct inode *); void (*delete_inode) (struct inode *); void (*put_super) (struct super_block *); @@ -246,9 +245,6 @@ or bottom half). inode to disc. The second parameter indicates whether the write should be synchronous or not, not all filesystems check this flag. - put_inode: called when the VFS inode is removed from the inode - cache. - drop_inode: called when the last access to the inode is dropped, with the inode_lock spinlock held. diff --git a/Documentation/hwmon/adt7473 b/Documentation/hwmon/adt7473 index 22d8b19046abcac7a7222daa9a916c895f975f71..2126de34c71161a3e6f22ddbfe082725b01cfc24 100644 --- a/Documentation/hwmon/adt7473 +++ b/Documentation/hwmon/adt7473 @@ -69,7 +69,8 @@ point2: Set the pwm speed at a higher temperature bound. The ADT7473 will scale the pwm between the lower and higher pwm speed when the temperature is between the two temperature boundaries. PWM values range -from 0 (off) to 255 (full speed). +from 0 (off) to 255 (full speed). Fan speed will be set to maximum when the +temperature sensor associated with the PWM control exceeds temp#_max. Notes ----- diff --git a/Documentation/i2c/functionality b/Documentation/i2c/functionality index 60cca249e452d759fcfa9dde1e04c0c431480773..42c17c1fb3cdf74e25a12e11d4416dd41e5f1f9a 100644 --- a/Documentation/i2c/functionality +++ b/Documentation/i2c/functionality @@ -51,26 +51,38 @@ A few combinations of the above flags are also defined for your convenience: the transparent emulation layer) -ALGORITHM/ADAPTER IMPLEMENTATION --------------------------------- +ADAPTER IMPLEMENTATION +---------------------- -When you write a new algorithm driver, you will have to implement a -function callback `functionality', that gets an i2c_adapter structure -pointer as its only parameter: +When you write a new adapter driver, you will have to implement a +function callback `functionality'. Typical implementations are given +below. - struct i2c_algorithm { - /* Many other things of course; check ! */ - u32 (*functionality) (struct i2c_adapter *); +A typical SMBus-only adapter would list all the SMBus transactions it +supports. This example comes from the i2c-piix4 driver: + + static u32 piix4_func(struct i2c_adapter *adapter) + { + return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | + I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | + I2C_FUNC_SMBUS_BLOCK_DATA; } -A typically implementation is given below, from i2c-algo-bit.c: +A typical full-I2C adapter would use the following (from the i2c-pxa +driver): - static u32 bit_func(struct i2c_adapter *adap) + static u32 i2c_pxa_functionality(struct i2c_adapter *adap) { - return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | - I2C_FUNC_PROTOCOL_MANGLING; + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; } +I2C_FUNC_SMBUS_EMUL includes all the SMBus transactions (with the +addition of I2C block transactions) which i2c-core can emulate using +I2C_FUNC_I2C without any help from the adapter driver. The idea is +to let the client drivers check for the support of SMBus functions +without having to care whether the said functions are implemented in +hardware by the adapter, or emulated in software by i2c-core on top +of an I2C adapter. CLIENT CHECKING @@ -78,36 +90,33 @@ CLIENT CHECKING Before a client tries to attach to an adapter, or even do tests to check whether one of the devices it supports is present on an adapter, it should -check whether the needed functionality is present. There are two functions -defined which should be used instead of calling the functionality hook -in the algorithm structure directly: - - /* Return the functionality mask */ - extern u32 i2c_get_functionality (struct i2c_adapter *adap); - - /* Return 1 if adapter supports everything we need, 0 if not. */ - extern int i2c_check_functionality (struct i2c_adapter *adap, u32 func); +check whether the needed functionality is present. The typical way to do +this is (from the lm75 driver): -This is a typical way to use these functions (from the writing-clients -document): - int foo_detect_client(struct i2c_adapter *adapter, int address, - unsigned short flags, int kind) + static int lm75_detect(...) { - /* Define needed variables */ - - /* As the very first action, we check whether the adapter has the - needed functionality: we need the SMBus read_word_data, - write_word_data and write_byte functions in this example. */ - if (!i2c_check_functionality(adapter,I2C_FUNC_SMBUS_WORD_DATA | - I2C_FUNC_SMBUS_WRITE_BYTE)) - goto ERROR0; - - /* Now we can do the real detection */ - - ERROR0: - /* Return an error */ + (...) + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_WORD_DATA)) + goto exit; + (...) } +Here, the lm75 driver checks if the adapter can do both SMBus byte data +and SMBus word data transactions. If not, then the driver won't work on +this adapter and there's no point in going on. If the check above is +successful, then the driver knows that it can call the following +functions: i2c_smbus_read_byte_data(), i2c_smbus_write_byte_data(), +i2c_smbus_read_word_data() and i2c_smbus_write_word_data(). As a rule of +thumb, the functionality constants you test for with +i2c_check_functionality() should match exactly the i2c_smbus_* functions +which you driver is calling. + +Note that the check above doesn't tell whether the functionalities are +implemented in hardware by the underlying adapter or emulated in +software by i2c-core. Client drivers don't have to care about this, as +i2c-core will transparently implement SMBus transactions on top of I2C +adapters. CHECKING THROUGH /DEV @@ -116,19 +125,19 @@ CHECKING THROUGH /DEV If you try to access an adapter from a userspace program, you will have to use the /dev interface. You will still have to check whether the functionality you need is supported, of course. This is done using -the I2C_FUNCS ioctl. An example, adapted from the lm_sensors i2cdetect -program, is below: +the I2C_FUNCS ioctl. An example, adapted from the i2cdetect program, is +below: int file; - if (file = open("/dev/i2c-0",O_RDWR) < 0) { + if (file = open("/dev/i2c-0", O_RDWR) < 0) { /* Some kind of error handling */ exit(1); } - if (ioctl(file,I2C_FUNCS,&funcs) < 0) { + if (ioctl(file, I2C_FUNCS, &funcs) < 0) { /* Some kind of error handling */ exit(1); } - if (! (funcs & I2C_FUNC_SMBUS_QUICK)) { + if (!(funcs & I2C_FUNC_SMBUS_QUICK)) { /* Oops, the needed functionality (SMBus write_quick function) is not available! */ exit(1); diff --git a/Documentation/i2c/smbus-protocol b/Documentation/i2c/smbus-protocol index 8a653c60d25a22d1bde489b947e58b0847d6e324..03f08fb491ccca6edcbcc6ce6fd1e0dda6eae2ad 100644 --- a/Documentation/i2c/smbus-protocol +++ b/Documentation/i2c/smbus-protocol @@ -1,5 +1,6 @@ SMBus Protocol Summary ====================== + The following is a summary of the SMBus protocol. It applies to all revisions of the protocol (1.0, 1.1, and 2.0). Certain protocol features which are not supported by @@ -8,6 +9,7 @@ this package are briefly described at the end of this document. Some adapters understand only the SMBus (System Management Bus) protocol, which is a subset from the I2C protocol. Fortunately, many devices use only the same subset, which makes it possible to put them on an SMBus. + If you write a driver for some I2C device, please try to use the SMBus commands if at all possible (if the device uses only that subset of the I2C protocol). This makes it possible to use the device driver on both @@ -15,7 +17,12 @@ SMBus adapters and I2C adapters (the SMBus command set is automatically translated to I2C on I2C adapters, but plain I2C commands can not be handled at all on most pure SMBus adapters). -Below is a list of SMBus commands. +Below is a list of SMBus protocol operations, and the functions executing +them. Note that the names used in the SMBus protocol specifications usually +don't match these function names. For some of the operations which pass a +single data byte, the functions using SMBus protocol operation names execute +a different protocol operation entirely. + Key to symbols ============== @@ -35,17 +42,16 @@ Count (8 bits): A data byte containing the length of a block operation. [..]: Data sent by I2C device, as opposed to data sent by the host adapter. -SMBus Write Quick -================= +SMBus Quick Command: i2c_smbus_write_quick() +============================================= This sends a single bit to the device, at the place of the Rd/Wr bit. -There is no equivalent Read Quick command. A Addr Rd/Wr [A] P -SMBus Read Byte -=============== +SMBus Receive Byte: i2c_smbus_read_byte() +========================================== This reads a single byte from a device, without specifying a device register. Some devices are so simple that this interface is enough; for @@ -55,17 +61,17 @@ the previous SMBus command. S Addr Rd [A] [Data] NA P -SMBus Write Byte -================ +SMBus Send Byte: i2c_smbus_write_byte() +======================================== -This is the reverse of Read Byte: it sends a single byte to a device. -See Read Byte for more information. +This operation is the reverse of Receive Byte: it sends a single byte +to a device. See Receive Byte for more information. S Addr Wr [A] Data [A] P -SMBus Read Byte Data -==================== +SMBus Read Byte: i2c_smbus_read_byte_data() +============================================ This reads a single byte from a device, from a designated register. The register is specified through the Comm byte. @@ -73,30 +79,30 @@ The register is specified through the Comm byte. S Addr Wr [A] Comm [A] S Addr Rd [A] [Data] NA P -SMBus Read Word Data -==================== +SMBus Read Word: i2c_smbus_read_word_data() +============================================ -This command is very like Read Byte Data; again, data is read from a +This operation is very like Read Byte; again, data is read from a device, from a designated register that is specified through the Comm byte. But this time, the data is a complete word (16 bits). S Addr Wr [A] Comm [A] S Addr Rd [A] [DataLow] A [DataHigh] NA P -SMBus Write Byte Data -===================== +SMBus Write Byte: i2c_smbus_write_byte_data() +============================================== This writes a single byte to a device, to a designated register. The register is specified through the Comm byte. This is the opposite of -the Read Byte Data command. +the Read Byte operation. S Addr Wr [A] Comm [A] Data [A] P -SMBus Write Word Data -===================== +SMBus Write Word: i2c_smbus_write_word_data() +============================================== -This is the opposite operation of the Read Word Data command. 16 bits +This is the opposite of the Read Word operation. 16 bits of data is written to a device, to the designated register that is specified through the Comm byte. @@ -113,8 +119,8 @@ S Addr Wr [A] Comm [A] DataLow [A] DataHigh [A] S Addr Rd [A] [DataLow] A [DataHigh] NA P -SMBus Block Read -================ +SMBus Block Read: i2c_smbus_read_block_data() +============================================== This command reads a block of up to 32 bytes from a device, from a designated register that is specified through the Comm byte. The amount @@ -124,8 +130,8 @@ S Addr Wr [A] Comm [A] S Addr Rd [A] [Count] A [Data] A [Data] A ... A [Data] NA P -SMBus Block Write -================= +SMBus Block Write: i2c_smbus_write_block_data() +================================================ The opposite of the Block Read command, this writes up to 32 bytes to a device, to a designated register that is specified through the @@ -134,10 +140,11 @@ Comm byte. The amount of data is specified in the Count byte. S Addr Wr [A] Comm [A] Count [A] Data [A] Data [A] ... [A] Data [A] P -SMBus Block Process Call -======================== +SMBus Block Write - Block Read Process Call +=========================================== -SMBus Block Process Call was introduced in Revision 2.0 of the specification. +SMBus Block Write - Block Read Process Call was introduced in +Revision 2.0 of the specification. This command selects a device register (through the Comm byte), sends 1 to 31 bytes of data to it, and reads 1 to 31 bytes of data in return. @@ -159,13 +166,16 @@ alerting device's address. Packet Error Checking (PEC) =========================== + Packet Error Checking was introduced in Revision 1.1 of the specification. -PEC adds a CRC-8 error-checking byte to all transfers. +PEC adds a CRC-8 error-checking byte to transfers using it, immediately +before the terminating STOP. Address Resolution Protocol (ARP) ================================= + The Address Resolution Protocol was introduced in Revision 2.0 of the specification. It is a higher-layer protocol which uses the messages above. @@ -177,14 +187,17 @@ require PEC checksums. I2C Block Transactions ====================== + The following I2C block transactions are supported by the SMBus layer and are described here for completeness. +They are *NOT* defined by the SMBus specification. + I2C block transactions do not limit the number of bytes transferred but the SMBus layer places a limit of 32 bytes. -I2C Block Read -============== +I2C Block Read: i2c_smbus_read_i2c_block_data() +================================================ This command reads a block of bytes from a device, from a designated register that is specified through the Comm byte. @@ -203,8 +216,8 @@ S Addr Wr [A] Comm1 [A] Comm2 [A] S Addr Rd [A] [Data] A [Data] A ... A [Data] NA P -I2C Block Write -=============== +I2C Block Write: i2c_smbus_write_i2c_block_data() +================================================== The opposite of the Block Read command, this writes bytes to a device, to a designated register that is specified through the @@ -212,5 +225,3 @@ Comm byte. Note that command lengths of 0, 2, or more bytes are supported as they are indistinguishable from data. S Addr Wr [A] Comm [A] Data [A] Data [A] ... [A] Data [A] P - - diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index cdd5b934f43ea89865f1f605ecc5f295b03192d3..e07c432c731ff9a516fe8b23228af0fe6fa1d29a 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -398,9 +398,6 @@ and is between 256 and 4096 characters. It is defined in the file cio_ignore= [S390] See Documentation/s390/CommonIO for details. - cio_msg= [S390] - See Documentation/s390/CommonIO for details. - clock= [BUGS=X86-32, HW] gettimeofday clocksource override. [Deprecated] Forces specified clocksource (if available) to be used @@ -689,6 +686,12 @@ and is between 256 and 4096 characters. It is defined in the file floppy= [HW] See Documentation/floppy.txt. + force_pal_cache_flush + [IA-64] Avoid check_sal_cache_flush which may hang on + buggy SAL_CACHE_FLUSH implementations. Using this + parameter will force ia64_sal_cache_flush to call + ia64_pal_cache_flush instead of SAL_CACHE_FLUSH. + gamecon.map[2|3]= [HW,JOY] Multisystem joystick and NES/SNES/PSX pad support via parallel port (up to 5 devices per port) diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt index e5a819a4f0c99588fecaef9f96632e5922b5c4b4..f5b7127f54acb6af1d9f997a40e099b60c0b7571 100644 --- a/Documentation/memory-barriers.txt +++ b/Documentation/memory-barriers.txt @@ -994,7 +994,17 @@ The Linux kernel has eight basic CPU memory barriers: DATA DEPENDENCY read_barrier_depends() smp_read_barrier_depends() -All CPU memory barriers unconditionally imply compiler barriers. +All memory barriers except the data dependency barriers imply a compiler +barrier. Data dependencies do not impose any additional compiler ordering. + +Aside: In the case of data dependencies, the compiler would be expected to +issue the loads in the correct order (eg. `a[b]` would have to load the value +of b before loading a[b]), however there is no guarantee in the C specification +that the compiler may not speculate the value of b (eg. is equal to 1) and load +a before b (eg. tmp = a[1]; if (b != 1) tmp = a[b]; ). There is also the +problem of a compiler reloading b after having loaded a[b], thus having a newer +copy of b than a[b]. A consensus has not yet been reached about these problems, +however the ACCESS_ONCE macro is a good place to start looking. SMP memory barriers are reduced to compiler barriers on uniprocessor compiled systems because it is assumed that a CPU will appear to be self-consistent, diff --git a/Documentation/s390/CommonIO b/Documentation/s390/CommonIO index 8fbc0a852870f2a972b4d17adae71ba866bc5975..bf0baa19ec24e875716e09490a2afeaecb86b5e2 100644 --- a/Documentation/s390/CommonIO +++ b/Documentation/s390/CommonIO @@ -8,17 +8,6 @@ Command line parameters Enable logging of debug information in case of ccw device timeouts. - -* cio_msg = yes | no - - Determines whether information on found devices and sensed device - characteristics should be shown during startup or when new devices are - found, i. e. messages of the types "Detected device 0.0.4711 on subchannel - 0.0.0042" and "SenseID: Device 0.0.4711 reports: ...". - - Default is off. - - * cio_ignore = {all} | { | } | {! | !} diff --git a/Documentation/video4linux/CARDLIST.cx23885 b/Documentation/video4linux/CARDLIST.cx23885 index 929b90c8387fafc30ed3e0715171a504e257b0e7..191194ea1e25ce694217259eb64fe0f583a33462 100644 --- a/Documentation/video4linux/CARDLIST.cx23885 +++ b/Documentation/video4linux/CARDLIST.cx23885 @@ -5,6 +5,6 @@ 4 -> DViCO FusionHDTV5 Express [18ac:d500] 5 -> Hauppauge WinTV-HVR1500Q [0070:7790,0070:7797] 6 -> Hauppauge WinTV-HVR1500 [0070:7710,0070:7717] - 7 -> Hauppauge WinTV-HVR1200 [0070:71d1] + 7 -> Hauppauge WinTV-HVR1200 [0070:71d1,0070:71d3] 8 -> Hauppauge WinTV-HVR1700 [0070:8101] 9 -> Hauppauge WinTV-HVR1400 [0070:8010] diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx index f40e09296f306152aa5c89b4cfef0d3edf02d851..1d6a245c828f45f7b9c9c6ea4de824feb1990520 100644 --- a/Documentation/video4linux/CARDLIST.em28xx +++ b/Documentation/video4linux/CARDLIST.em28xx @@ -14,4 +14,4 @@ 13 -> Terratec Prodigy XS (em2880) [0ccd:0047] 14 -> Pixelview Prolink PlayTV USB 2.0 (em2820/em2840) 15 -> V-Gear PocketTV (em2800) - 16 -> Hauppauge WinTV HVR 950 (em2880) [2040:6513] + 16 -> Hauppauge WinTV HVR 950 (em2880) [2040:6513,2040:6517,2040:651b,2040:651f] diff --git a/Kbuild b/Kbuild index 32f19c5c9bb07e106ee06de49e7f72c1ead9dd3b..e750e9c3fe59862e377a568e0758ca838e11c6f1 100644 --- a/Kbuild +++ b/Kbuild @@ -96,5 +96,4 @@ missing-syscalls: scripts/checksyscalls.sh FORCE $(call cmd,syscalls) # Delete all targets during make clean -clean-files := $(addprefix $(objtree)/,$(targets)) - +clean-files := $(addprefix $(objtree)/,$(filter-out $(bounds-file) $(offsets-file),$(targets))) diff --git a/MAINTAINERS b/MAINTAINERS index abe27871ad6a54c56b48789aa4480a020e863fee..a0291616a35f9429d08ef76de80459e2202d170e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -367,12 +367,12 @@ S: Maintained for 2.4; PCI support for 2.6. AMD GEODE CS5536 USB DEVICE CONTROLLER DRIVER P: Thomas Dahlmann M: thomas.dahlmann@amd.com -L: info-linux@geode.amd.com (subscribers-only) +L: linux-geode@lists.infradead.org (moderated for non-subscribers) S: Supported AMD GEODE PROCESSOR/CHIPSET SUPPORT P: Jordan Crouse -L: info-linux@geode.amd.com (subscribers-only) +L: linux-geode@lists.infradead.org (moderated for non-subscribers) W: http://www.amd.com/us-en/ConnectivitySolutions/TechnicalResources/0,,50_2334_2452_11363,00.html S: Supported @@ -1230,6 +1230,15 @@ P: Jaya Kumar M: jayakumar.alsa@gmail.com S: Maintained +CX18 VIDEO4LINUX DRIVER +P: Hans Verkuil, Andy Walls +M: hverkuil@xs4all.nl, awalls@radix.net +L: ivtv-devel@ivtvdriver.org +L: ivtv-users@ivtvdriver.org +L: video4linux-list@redhat.com +W: http://linuxtv.org +S: Maintained + CYBERPRO FB DRIVER P: Russell King M: rmk@arm.linux.org.uk @@ -1931,8 +1940,10 @@ L: lm-sensors@lm-sensors.org S: Maintained I2C SUBSYSTEM -P: Jean Delvare +P: Jean Delvare (PC drivers, core) M: khali@linux-fr.org +P: Ben Dooks (embedded platforms) +M: ben-linux@fluff.org L: i2c@lm-sensors.org T: quilt http://khali.linux-fr.org/devel/linux-2.6/jdelvare-i2c/ S: Maintained @@ -2112,12 +2123,10 @@ L: netdev@vger.kernel.org S: Maintained INTEL ETHERNET DRIVERS (e100/e1000/e1000e/igb/ixgb/ixgbe) -P: Auke Kok -M: auke-jan.h.kok@intel.com -P: Jesse Brandeburg -M: jesse.brandeburg@intel.com P: Jeff Kirsher M: jeffrey.t.kirsher@intel.com +P: Jesse Brandeburg +M: jesse.brandeburg@intel.com P: Bruce Allan M: bruce.w.allan@intel.com P: John Ronciak @@ -2320,7 +2329,8 @@ S: Maintained KERNEL BUILD (kbuild: Makefile, scripts/Makefile.*) P: Sam Ravnborg M: sam@ravnborg.org -T: git kernel.org:/pub/scm/linux/kernel/git/sam/kbuild.git +T: git kernel.org:/pub/scm/linux/kernel/git/sam/kbuild-next.git +T: git kernel.org:/pub/scm/linux/kernel/git/sam/kbuild-fixes.git L: linux-kbuild@vger.kernel.org S: Maintained @@ -2342,24 +2352,24 @@ S: Supported KERNEL VIRTUAL MACHINE (KVM) P: Avi Kivity M: avi@qumranet.com -L: kvm-devel@lists.sourceforge.net -W: kvm.sourceforge.net +L: kvm@vger.kernel.org +W: http://kvm.qumranet.com S: Supported KERNEL VIRTUAL MACHINE (KVM) FOR POWERPC P: Hollis Blanchard M: hollisb@us.ibm.com -L: kvm-ppc-devel@lists.sourceforge.net -W: kvm.sourceforge.net +L: kvm-ppc@vger.kernel.org +W: http://kvm.qumranet.com S: Supported -KERNEL VIRTUAL MACHINE For Itanium(KVM/IA64) +KERNEL VIRTUAL MACHINE For Itanium (KVM/IA64) P: Anthony Xu M: anthony.xu@intel.com P: Xiantao Zhang M: xiantao.zhang@intel.com -L: kvm-ia64-devel@lists.sourceforge.net -W: kvm.sourceforge.net +L: kvm-ia64@vger.kernel.org +W: http://kvm.qumranet.com S: Supported KERNEL VIRTUAL MACHINE for s390 (KVM/s390) @@ -2810,6 +2820,15 @@ M: jirislaby@gmail.com L: linux-kernel@vger.kernel.org S: Maintained +MYRICOM MYRI-10G 10GbE DRIVER (MYRI10GE) +P: Andrew Gallatin +M: gallatin@myri.com +P: Brice Goglin +M: brice@myri.com +L: netdev@vger.kernel.org +W: http://www.myri.com/scs/download-Myri10GE.html +S: Supported + NATSEMI ETHERNET DRIVER (DP8381x) P: Tim Hockin M: thockin@hockin.org @@ -4012,12 +4031,41 @@ M: ballabio_dario@emc.com L: linux-scsi@vger.kernel.org S: Maintained +UCLINUX (AND M68KNOMMU) +P: Greg Ungerer +M: gerg@uclinux.org +W: http://www.uclinux.org/ +L: uclinux-dev@uclinux.org (subscribers-only) +S: Maintained + +UCLINUX FOR NEC V850 +P: Miles Bader + +UCLINUX FOR RENESAS H8/300 +P: Yoshinori Sato +M: ysato@users.sourceforge.jp +W: http://uclinux-h8.sourceforge.jp/ +S: Supported + UDF FILESYSTEM P: Jan Kara M: jack@suse.cz W: http://linux-udf.sourceforge.net S: Maintained +UFS FILESYSTEM +P: Evgeniy Dushistov +M: dushistov@mail.ru +L: linux-kernel@vger.kernel.org +S: Maintained + +UltraSPARC (sparc64): +P: David S. Miller +M: davem@davemloft.net +L: sparclinux@vger.kernel.org +T: git kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6.git +S: Maintained + UNIFORM CDROM DRIVER P: Jens Axboe M: axboe@kernel.dk @@ -4064,6 +4112,13 @@ L: netdev@vger.kernel.org W: http://www.linux-usb.org/usbnet S: Maintained +USB DIAMOND RIO500 DRIVER +P: Cesar Miquel +M: miquel@df.uba.ar +L: rio500-users@lists.sourceforge.net +W: http://rio500.sourceforge.net +S: Maintained + USB EHCI DRIVER P: David Brownell M: dbrownell@users.sourceforge.net @@ -4318,42 +4373,6 @@ M: romieu@fr.zoreil.com L: netdev@vger.kernel.org S: Maintained -UCLINUX (AND M68KNOMMU) -P: Greg Ungerer -M: gerg@uclinux.org -W: http://www.uclinux.org/ -L: uclinux-dev@uclinux.org (subscribers-only) -S: Maintained - -UCLINUX FOR NEC V850 -P: Miles Bader - -UCLINUX FOR RENESAS H8/300 -P: Yoshinori Sato -M: ysato@users.sourceforge.jp -W: http://uclinux-h8.sourceforge.jp/ -S: Supported - -UFS FILESYSTEM -P: Evgeniy Dushistov -M: dushistov@mail.ru -L: linux-kernel@vger.kernel.org -S: Maintained - -UltraSPARC (sparc64): -P: David S. Miller -M: davem@davemloft.net -L: sparclinux@vger.kernel.org -T: git kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6.git -S: Maintained - -USB DIAMOND RIO500 DRIVER -P: Cesar Miquel -M: miquel@df.uba.ar -L: rio500-users@lists.sourceforge.net -W: http://rio500.sourceforge.net -S: Maintained - VIDEO FOR LINUX P: Mauro Carvalho Chehab M: mchehab@infradead.org diff --git a/Makefile b/Makefile index 4492984efc09ab72ff6219a7bc21fb6a957c4cd5..20b32351906b72fb7e6282418aaf87e8644367f1 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 26 -EXTRAVERSION = -rc1 +EXTRAVERSION = -rc3 NAME = Funky Weasel is Jiggy wit it # *DOCUMENTATION* @@ -1114,6 +1114,7 @@ MRPROPER_DIRS += include/config include2 usr/include MRPROPER_FILES += .config .config.old include/asm .version .old_version \ include/linux/autoconf.h include/linux/version.h \ include/linux/utsrelease.h \ + include/linux/bounds.h include/asm*/asm-offsets.h \ Module.symvers tags TAGS cscope* # clean - Delete most, but leave enough to build external modules @@ -1431,7 +1432,7 @@ define xtags elif $1 --version 2>&1 | grep -iq emacs; then \ $(all-sources) | xargs $1 -a; \ $(all-kconfigs) | xargs $1 -a \ - --regex='/^[ \t]*(menu|)config[ \t]+\([a-zA-Z0-9_]+\)/\2/'; \ + --regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/\3/'; \ $(all-defconfigs) | xargs -r $1 -a \ --regex='/^#?[ \t]?\(CONFIG_[a-zA-Z0-9_]+\)/\1/'; \ else \ diff --git a/arch/alpha/kernel/init_task.c b/arch/alpha/kernel/init_task.c index 835d09a7b332b9ba369b23a8e07693f24ddb8b8e..1f762189fa64f1f158e6d1d1664cabb14f58264e 100644 --- a/arch/alpha/kernel/init_task.c +++ b/arch/alpha/kernel/init_task.c @@ -9,7 +9,6 @@ static struct fs_struct init_fs = INIT_FS; -static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS(init_signals); static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); struct mm_struct init_mm = INIT_MM(init_mm); diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c index ae21755872ed2c8e8d6ad4bdaef3207d1fcb09f9..d973c986f721aec8822f8ef0db8eeb97b0ec199e 100644 --- a/arch/arm/common/locomo.c +++ b/arch/arm/common/locomo.c @@ -321,11 +321,42 @@ static void locomo_gpio_unmask_irq(unsigned int irq) locomo_writel(r, mapbase + LOCOMO_GIE); } +static int GPIO_IRQ_rising_edge; +static int GPIO_IRQ_falling_edge; + +static int locomo_gpio_type(unsigned int irq, unsigned int type) +{ + unsigned int mask; + void __iomem *mapbase = get_irq_chip_data(irq); + + mask = 1 << (irq - LOCOMO_IRQ_GPIO_START); + + if (type == IRQT_PROBE) { + if ((GPIO_IRQ_rising_edge | GPIO_IRQ_falling_edge) & mask) + return 0; + type = __IRQT_RISEDGE | __IRQT_FALEDGE; + } + + if (type & __IRQT_RISEDGE) + GPIO_IRQ_rising_edge |= mask; + else + GPIO_IRQ_rising_edge &= ~mask; + if (type & __IRQT_FALEDGE) + GPIO_IRQ_falling_edge |= mask; + else + GPIO_IRQ_falling_edge &= ~mask; + locomo_writel(GPIO_IRQ_rising_edge, mapbase + LOCOMO_GRIE); + locomo_writel(GPIO_IRQ_falling_edge, mapbase + LOCOMO_GFIE); + + return 0; +} + static struct irq_chip locomo_gpio_chip = { - .name = "LOCOMO-gpio", - .ack = locomo_gpio_ack_irq, - .mask = locomo_gpio_mask_irq, - .unmask = locomo_gpio_unmask_irq, + .name = "LOCOMO-gpio", + .ack = locomo_gpio_ack_irq, + .mask = locomo_gpio_mask_irq, + .unmask = locomo_gpio_unmask_irq, + .set_type = locomo_gpio_type, }; static void locomo_lt_handler(unsigned int irq, struct irq_desc *desc) @@ -450,22 +481,18 @@ static void locomo_setup_irq(struct locomo *lchip) set_irq_chip(IRQ_LOCOMO_KEY_BASE, &locomo_chip); set_irq_chip_data(IRQ_LOCOMO_KEY_BASE, irqbase); set_irq_chained_handler(IRQ_LOCOMO_KEY_BASE, locomo_key_handler); - set_irq_flags(IRQ_LOCOMO_KEY_BASE, IRQF_VALID | IRQF_PROBE); set_irq_chip(IRQ_LOCOMO_GPIO_BASE, &locomo_chip); set_irq_chip_data(IRQ_LOCOMO_GPIO_BASE, irqbase); set_irq_chained_handler(IRQ_LOCOMO_GPIO_BASE, locomo_gpio_handler); - set_irq_flags(IRQ_LOCOMO_GPIO_BASE, IRQF_VALID | IRQF_PROBE); set_irq_chip(IRQ_LOCOMO_LT_BASE, &locomo_chip); set_irq_chip_data(IRQ_LOCOMO_LT_BASE, irqbase); set_irq_chained_handler(IRQ_LOCOMO_LT_BASE, locomo_lt_handler); - set_irq_flags(IRQ_LOCOMO_LT_BASE, IRQF_VALID | IRQF_PROBE); set_irq_chip(IRQ_LOCOMO_SPI_BASE, &locomo_chip); set_irq_chip_data(IRQ_LOCOMO_SPI_BASE, irqbase); set_irq_chained_handler(IRQ_LOCOMO_SPI_BASE, locomo_spi_handler); - set_irq_flags(IRQ_LOCOMO_SPI_BASE, IRQF_VALID | IRQF_PROBE); /* install handlers for IRQ_LOCOMO_KEY_BASE generated interrupts */ set_irq_chip(LOCOMO_IRQ_KEY_START, &locomo_key_chip); @@ -488,7 +515,7 @@ static void locomo_setup_irq(struct locomo *lchip) set_irq_flags(LOCOMO_IRQ_LT_START, IRQF_VALID | IRQF_PROBE); /* install handlers for IRQ_LOCOMO_SPI_BASE generated interrupts */ - for (irq = LOCOMO_IRQ_SPI_START; irq < LOCOMO_IRQ_SPI_START + 3; irq++) { + for (irq = LOCOMO_IRQ_SPI_START; irq < LOCOMO_IRQ_SPI_START + 4; irq++) { set_irq_chip(irq, &locomo_spi_chip); set_irq_chip_data(irq, irqbase); set_irq_handler(irq, handle_edge_irq); @@ -574,20 +601,20 @@ static int locomo_suspend(struct platform_device *dev, pm_message_t state) save->LCM_GPO = locomo_readl(lchip->base + LOCOMO_GPO); /* GPIO */ locomo_writel(0x00, lchip->base + LOCOMO_GPO); - save->LCM_SPICT = locomo_readl(lchip->base + LOCOMO_SPICT); /* SPI */ + save->LCM_SPICT = locomo_readl(lchip->base + LOCOMO_SPI + LOCOMO_SPICT); /* SPI */ locomo_writel(0x40, lchip->base + LOCOMO_SPICT); save->LCM_GPE = locomo_readl(lchip->base + LOCOMO_GPE); /* GPIO */ locomo_writel(0x00, lchip->base + LOCOMO_GPE); save->LCM_ASD = locomo_readl(lchip->base + LOCOMO_ASD); /* ADSTART */ locomo_writel(0x00, lchip->base + LOCOMO_ASD); - save->LCM_SPIMD = locomo_readl(lchip->base + LOCOMO_SPIMD); /* SPI */ - locomo_writel(0x3C14, lchip->base + LOCOMO_SPIMD); + save->LCM_SPIMD = locomo_readl(lchip->base + LOCOMO_SPI + LOCOMO_SPIMD); /* SPI */ + locomo_writel(0x3C14, lchip->base + LOCOMO_SPI + LOCOMO_SPIMD); locomo_writel(0x00, lchip->base + LOCOMO_PAIF); locomo_writel(0x00, lchip->base + LOCOMO_DAC); locomo_writel(0x00, lchip->base + LOCOMO_BACKLIGHT + LOCOMO_TC); - if ( (locomo_readl(lchip->base + LOCOMO_LED + LOCOMO_LPT0) & 0x88) && (locomo_readl(lchip->base + LOCOMO_LED + LOCOMO_LPT1) & 0x88) ) + if ((locomo_readl(lchip->base + LOCOMO_LED + LOCOMO_LPT0) & 0x88) && (locomo_readl(lchip->base + LOCOMO_LED + LOCOMO_LPT1) & 0x88)) locomo_writel(0x00, lchip->base + LOCOMO_C32K); /* CLK32 off */ else /* 18MHz already enabled, so no wait */ @@ -616,10 +643,10 @@ static int locomo_resume(struct platform_device *dev) spin_lock_irqsave(&lchip->lock, flags); locomo_writel(save->LCM_GPO, lchip->base + LOCOMO_GPO); - locomo_writel(save->LCM_SPICT, lchip->base + LOCOMO_SPICT); + locomo_writel(save->LCM_SPICT, lchip->base + LOCOMO_SPI + LOCOMO_SPICT); locomo_writel(save->LCM_GPE, lchip->base + LOCOMO_GPE); locomo_writel(save->LCM_ASD, lchip->base + LOCOMO_ASD); - locomo_writel(save->LCM_SPIMD, lchip->base + LOCOMO_SPIMD); + locomo_writel(save->LCM_SPIMD, lchip->base + LOCOMO_SPI + LOCOMO_SPIMD); locomo_writel(0x00, lchip->base + LOCOMO_C32K); locomo_writel(0x90, lchip->base + LOCOMO_TADC); @@ -688,9 +715,9 @@ __locomo_probe(struct device *me, struct resource *mem, int irq) /* GPIO */ locomo_writel(0, lchip->base + LOCOMO_GPO); - locomo_writel( (LOCOMO_GPIO(2) | LOCOMO_GPIO(3) | LOCOMO_GPIO(13) | LOCOMO_GPIO(14)) + locomo_writel((LOCOMO_GPIO(1) | LOCOMO_GPIO(2) | LOCOMO_GPIO(13) | LOCOMO_GPIO(14)) , lchip->base + LOCOMO_GPE); - locomo_writel( (LOCOMO_GPIO(2) | LOCOMO_GPIO(3) | LOCOMO_GPIO(13) | LOCOMO_GPIO(14)) + locomo_writel((LOCOMO_GPIO(1) | LOCOMO_GPIO(2) | LOCOMO_GPIO(13) | LOCOMO_GPIO(14)) , lchip->base + LOCOMO_GPD); locomo_writel(0, lchip->base + LOCOMO_GIE); @@ -833,7 +860,10 @@ void locomo_gpio_set_dir(struct device *dev, unsigned int bits, unsigned int dir spin_lock_irqsave(&lchip->lock, flags); r = locomo_readl(lchip->base + LOCOMO_GPD); - r &= ~bits; + if (dir) + r |= bits; + else + r &= ~bits; locomo_writel(r, lchip->base + LOCOMO_GPD); r = locomo_readl(lchip->base + LOCOMO_GPE); diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index f73d62e8ab606473b4cc69e4f25775493f3a8af8..688b7b1ee416c54987239740680ffbd29fdeb3b0 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c @@ -179,3 +179,5 @@ EXPORT_SYMBOL(_find_next_zero_bit_be); EXPORT_SYMBOL(_find_first_bit_be); EXPORT_SYMBOL(_find_next_bit_be); #endif + +EXPORT_SYMBOL(copy_page); diff --git a/arch/arm/kernel/arthur.c b/arch/arm/kernel/arthur.c index 0ee2e98196313a6dffaf46e38faaf5b426d80144..321c5291d05f0aea77f326fd05bbb2cd2a5a3b2a 100644 --- a/arch/arm/kernel/arthur.c +++ b/arch/arm/kernel/arthur.c @@ -90,3 +90,5 @@ static void __exit arthur_exit(void) module_init(arthur_init); module_exit(arthur_exit); + +MODULE_LICENSE("GPL"); diff --git a/arch/arm/kernel/init_task.c b/arch/arm/kernel/init_task.c index bd4ef53bc6b95ee03f8eac412e03563146a27a4f..8b8c9d38a7611daaad9ddd2af7de18ec2176e374 100644 --- a/arch/arm/kernel/init_task.c +++ b/arch/arm/kernel/init_task.c @@ -13,7 +13,6 @@ #include static struct fs_struct init_fs = INIT_FS; -static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS(init_signals); static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); struct mm_struct init_mm = INIT_MM(init_mm); diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c index 728bb8f394415fc683d3e8b4620cdaec984992a8..0babb645b83c055ea1120706b2344c9c286d3ca2 100644 --- a/arch/arm/mach-at91/at91sam9261_devices.c +++ b/arch/arm/mach-at91/at91sam9261_devices.c @@ -544,10 +544,10 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) struct resource *fb_res = &lcdc_resources[2]; size_t fb_len = fb_res->end - fb_res->start + 1; - fb = ioremap_writecombine(fb_res->start, fb_len); + fb = ioremap(fb_res->start, fb_len); if (fb) { memset(fb, 0, fb_len); - iounmap(fb, fb_len); + iounmap(fb); } } lcdc_data = *data; diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c index 054689804e77571213012852f4dc771f5f70501e..450db304936ffea07453e4319d51fa7b5eb2244b 100644 --- a/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/arch/arm/mach-at91/at91sam9rl_devices.c @@ -332,13 +332,6 @@ static struct resource lcdc_resources[] = { .end = AT91SAM9RL_ID_LCDC, .flags = IORESOURCE_IRQ, }, -#if defined(CONFIG_FB_INTSRAM) - [2] = { - .start = AT91SAM9RL_SRAM_BASE, - .end = AT91SAM9RL_SRAM_BASE + AT91SAM9RL_SRAM_SIZE - 1, - .flags = IORESOURCE_MEM, - }, -#endif }; static struct platform_device at91_lcdc_device = { @@ -381,20 +374,6 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) at91_set_B_periph(AT91_PIN_PC24, 0); /* LCDD22 */ at91_set_B_periph(AT91_PIN_PC25, 0); /* LCDD23 */ -#ifdef CONFIG_FB_INTSRAM - { - void __iomem *fb; - struct resource *fb_res = &lcdc_resources[2]; - size_t fb_len = fb_res->end - fb_res->start + 1; - - fb = ioremap_writecombine(fb_res->start, fb_len); - if (fb) { - memset(fb, 0, fb_len); - iounmap(fb, fb_len); - } - } -#endif - lcdc_data = *data; platform_device_register(&at91_lcdc_device); } diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c index 8bc187240542e6611f051809c233796f331fcfef..1d7bca6aa441e3a092a87933a3d87e9c9a2f245f 100644 --- a/arch/arm/mach-ep93xx/core.c +++ b/arch/arm/mach-ep93xx/core.c @@ -280,7 +280,7 @@ static int ep93xx_gpio_irq_type(unsigned int irq, unsigned int type) const int port = gpio >> 3; const int port_mask = 1 << (gpio & 7); - gpio_direction_output(gpio, gpio_get_value(gpio)); + gpio_direction_input(gpio); switch (type) { case IRQT_RISING: diff --git a/arch/arm/mach-ns9xxx/irq.c b/arch/arm/mach-ns9xxx/irq.c index 36e5835e60975127b798b28b8fe756238f354feb..ca85d24cf39f1f11553c2ac856d08b71bb9a9ff9 100644 --- a/arch/arm/mach-ns9xxx/irq.c +++ b/arch/arm/mach-ns9xxx/irq.c @@ -62,7 +62,7 @@ static struct irq_chip ns9xxx_chip = { #if 0 #define handle_irq handle_level_irq #else -void handle_prio_irq(unsigned int irq, struct irq_desc *desc) +static void handle_prio_irq(unsigned int irq, struct irq_desc *desc) { unsigned int cpu = smp_processor_id(); struct irqaction *action; @@ -70,27 +70,35 @@ void handle_prio_irq(unsigned int irq, struct irq_desc *desc) spin_lock(&desc->lock); - if (unlikely(desc->status & IRQ_INPROGRESS)) - goto out_unlock; + BUG_ON(desc->status & IRQ_INPROGRESS); desc->status &= ~(IRQ_REPLAY | IRQ_WAITING); kstat_cpu(cpu).irqs[irq]++; action = desc->action; if (unlikely(!action || (desc->status & IRQ_DISABLED))) - goto out_unlock; + goto out_mask; desc->status |= IRQ_INPROGRESS; spin_unlock(&desc->lock); action_ret = handle_IRQ_event(irq, action); + /* XXX: There is no direct way to access noirqdebug, so check + * unconditionally for spurious irqs... + * Maybe this function should go to kernel/irq/chip.c? */ + note_interrupt(irq, desc, action_ret); + spin_lock(&desc->lock); desc->status &= ~IRQ_INPROGRESS; - if (!(desc->status & IRQ_DISABLED) && desc->chip->ack) - desc->chip->ack(irq); -out_unlock: + if (desc->status & IRQ_DISABLED) +out_mask: + desc->chip->mask(irq); + + /* ack unconditionally to unmask lower prio irqs */ + desc->chip->ack(irq); + spin_unlock(&desc->lock); } #define handle_irq handle_prio_irq diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c index ca1a4bf78a106bb4489866ba82574680d0823bd0..a0b16a7e8a046b8a0f63b9ea506ae4c2c183413c 100644 --- a/arch/arm/mach-omap1/board-palmte.c +++ b/arch/arm/mach-omap1/board-palmte.c @@ -63,7 +63,7 @@ static const int palmte_keymap[] = { KEY(1, 1, KEY_DOWN), KEY(1, 2, KEY_UP), KEY(1, 3, KEY_RIGHT), - KEY(1, 4, KEY_CENTER), + KEY(1, 4, KEY_ENTER), 0, }; diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-omap1/board-palmz71.c index 156510777ffe569be987480be3197dbd92e01c80..e020c2774606884e1dfcfa8f5dbd76f94887ca6e 100644 --- a/arch/arm/mach-omap1/board-palmz71.c +++ b/arch/arm/mach-omap1/board-palmz71.c @@ -65,7 +65,7 @@ static int palmz71_keymap[] = { KEY(1, 1, KEY_DOWN), KEY(1, 2, KEY_UP), KEY(1, 3, KEY_RIGHT), - KEY(1, 4, KEY_CENTER), + KEY(1, 4, KEY_ENTER), KEY(2, 0, KEY_CAMERA), 0, }; diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c index 1c12d7c6c7fc82cc4734d625b4c6bdc0c3cfbe23..1682eb77c46d85246236b6e8f0e6b9769db0795d 100644 --- a/arch/arm/mach-omap2/board-2430sdp.c +++ b/arch/arm/mach-omap2/board-2430sdp.c @@ -208,6 +208,7 @@ static void __init omap_2430sdp_init(void) static void __init omap_2430sdp_map_io(void) { + omap2_set_globals_243x(); omap2_map_common_io(); } diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c index a1e1e6765b5be9d79b3f194c7e1c55a04a4a99bd..620fa0f120ee8a67df40fe95b5f5e2b569127f11 100644 --- a/arch/arm/mach-omap2/board-apollon.c +++ b/arch/arm/mach-omap2/board-apollon.c @@ -394,6 +394,7 @@ static void __init omap_apollon_init(void) static void __init omap_apollon_map_io(void) { + omap2_set_globals_242x(); omap2_map_common_io(); } diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c index 90938151bcf1340df536283c8b1053c5f0b50655..df8be081e1591cd7ebd89005baa7f1fb55bbd5b7 100644 --- a/arch/arm/mach-omap2/board-generic.c +++ b/arch/arm/mach-omap2/board-generic.c @@ -65,6 +65,7 @@ static void __init omap_generic_init(void) static void __init omap_generic_map_io(void) { + omap2_set_globals_242x(); /* should be 242x, 243x, or 343x */ omap2_map_common_io(); } diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c index d1915f99a5fa9c09a96a900b78c27fe8ea3f4385..0d28f6897c8e743916e400e1fa74a28082323112 100644 --- a/arch/arm/mach-omap2/board-h4.c +++ b/arch/arm/mach-omap2/board-h4.c @@ -420,6 +420,7 @@ static void __init omap_h4_init(void) static void __init omap_h4_map_io(void) { + omap2_set_globals_242x(); omap2_map_common_io(); } diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index b57ffb5a22a521d44aa91bdf368f7433f9ca3591..ab9fc57d25f16e56abc6b59ec9559ebb77bc2ee4 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c @@ -205,7 +205,9 @@ static void omap2_clk_wait_ready(struct clk *clk) /* REVISIT: What are the appropriate exclusions for 34XX? */ /* OMAP3: ignore DSS-mod clocks */ if (cpu_is_omap34xx() && - (((u32)reg & ~0xff) == (u32)OMAP_CM_REGADDR(OMAP3430_DSS_MOD, 0))) + (((u32)reg & ~0xff) == (u32)OMAP_CM_REGADDR(OMAP3430_DSS_MOD, 0) || + ((((u32)reg & ~0xff) == (u32)OMAP_CM_REGADDR(CORE_MOD, 0)) && + clk->enable_bit == OMAP3430_EN_SSI_SHIFT))) return; /* Check if both functional and interface clocks diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h index cf4644a94b9b8428c777c150c1ea1e8daa8119f8..c9c5972a2e259c6f26384342608c02eeaaa26e55 100644 --- a/arch/arm/mach-omap2/clock34xx.h +++ b/arch/arm/mach-omap2/clock34xx.h @@ -836,7 +836,8 @@ static struct clk dpll5_m2_ck = { .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKSEL5), .clksel_mask = OMAP3430ES2_DIV_120M_MASK, .clksel = div16_dpll5_clksel, - .flags = CLOCK_IN_OMAP3430ES2 | RATE_PROPAGATES, + .flags = CLOCK_IN_OMAP3430ES2 | RATE_PROPAGATES | + PARENT_CONTROLS_CLOCK, .recalc = &omap2_clksel_recalc, }; @@ -1046,12 +1047,13 @@ static struct clk iva2_ck = { .name = "iva2_ck", .parent = &dpll2_m2_ck, .init = &omap2_init_clksel_parent, + .enable_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, CM_FCLKEN), + .enable_bit = OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_SHIFT, .clksel_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_IDLEST_PLL), .clksel_mask = OMAP3430_ST_IVA2_CLK_MASK, .clksel = iva2_clksel, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, + .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES, .recalc = &omap2_clksel_recalc, }; @@ -1836,7 +1838,8 @@ static struct clk omapctrl_ick = { static struct clk ssi_l4_ick = { .name = "ssi_l4_ick", .parent = &l4_ick, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES, + .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | + PARENT_CONTROLS_CLOCK, .recalc = &followparent_recalc, }; @@ -2344,7 +2347,7 @@ static struct clk gpio6_fck = { .name = "gpio6_fck", .parent = &per_32k_alwon_fck, .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), - .enable_bit = OMAP3430_EN_GPT6_SHIFT, + .enable_bit = OMAP3430_EN_GPIO6_SHIFT, .flags = CLOCK_IN_OMAP343X, .recalc = &followparent_recalc, }; @@ -2353,7 +2356,7 @@ static struct clk gpio5_fck = { .name = "gpio5_fck", .parent = &per_32k_alwon_fck, .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), - .enable_bit = OMAP3430_EN_GPT5_SHIFT, + .enable_bit = OMAP3430_EN_GPIO5_SHIFT, .flags = CLOCK_IN_OMAP343X, .recalc = &followparent_recalc, }; @@ -2362,7 +2365,7 @@ static struct clk gpio4_fck = { .name = "gpio4_fck", .parent = &per_32k_alwon_fck, .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), - .enable_bit = OMAP3430_EN_GPT4_SHIFT, + .enable_bit = OMAP3430_EN_GPIO4_SHIFT, .flags = CLOCK_IN_OMAP343X, .recalc = &followparent_recalc, }; @@ -2371,7 +2374,7 @@ static struct clk gpio3_fck = { .name = "gpio3_fck", .parent = &per_32k_alwon_fck, .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), - .enable_bit = OMAP3430_EN_GPT3_SHIFT, + .enable_bit = OMAP3430_EN_GPIO3_SHIFT, .flags = CLOCK_IN_OMAP343X, .recalc = &followparent_recalc, }; @@ -2380,7 +2383,7 @@ static struct clk gpio2_fck = { .name = "gpio2_fck", .parent = &per_32k_alwon_fck, .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), - .enable_bit = OMAP3430_EN_GPT2_SHIFT, + .enable_bit = OMAP3430_EN_GPIO2_SHIFT, .flags = CLOCK_IN_OMAP343X, .recalc = &followparent_recalc, }; diff --git a/arch/arm/mach-omap2/cm-regbits-34xx.h b/arch/arm/mach-omap2/cm-regbits-34xx.h index 9249129a5f460c4654738e5cc3527ce60a4e4ce5..3c38395f6442cff0e4b425303737aad9eb59d45e 100644 --- a/arch/arm/mach-omap2/cm-regbits-34xx.h +++ b/arch/arm/mach-omap2/cm-regbits-34xx.h @@ -56,6 +56,7 @@ /* CM_FCLKEN_IVA2 */ #define OMAP3430_CM_FCLKEN_IVA2_EN_IVA2 (1 << 0) +#define OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_SHIFT 0 /* CM_CLKEN_PLL_IVA2 */ #define OMAP3430_IVA2_DPLL_RAMPTIME_SHIFT 8 diff --git a/arch/arm/mach-omap2/mailbox.c b/arch/arm/mach-omap2/mailbox.c index b03cd06e055ba193cf7c0906076d69588f97efe5..4799561c5a9ec048f46bdfb9cf53d437c04e82ff 100644 --- a/arch/arm/mach-omap2/mailbox.c +++ b/arch/arm/mach-omap2/mailbox.c @@ -70,6 +70,9 @@ struct omap_mbox2_priv { static struct clk *mbox_ick_handle; +static void omap2_mbox_enable_irq(struct omap_mbox *mbox, + omap_mbox_type_t irq); + static inline unsigned int mbox_read_reg(unsigned int reg) { return __raw_readl(mbox_base + reg); @@ -81,7 +84,7 @@ static inline void mbox_write_reg(unsigned int val, unsigned int reg) } /* Mailbox H/W preparations */ -static inline int omap2_mbox_startup(struct omap_mbox *mbox) +static int omap2_mbox_startup(struct omap_mbox *mbox) { unsigned int l; @@ -97,38 +100,40 @@ static inline int omap2_mbox_startup(struct omap_mbox *mbox) l |= 0x00000011; mbox_write_reg(l, MAILBOX_SYSCONFIG); + omap2_mbox_enable_irq(mbox, IRQ_RX); + return 0; } -static inline void omap2_mbox_shutdown(struct omap_mbox *mbox) +static void omap2_mbox_shutdown(struct omap_mbox *mbox) { clk_disable(mbox_ick_handle); clk_put(mbox_ick_handle); } /* Mailbox FIFO handle functions */ -static inline mbox_msg_t omap2_mbox_fifo_read(struct omap_mbox *mbox) +static mbox_msg_t omap2_mbox_fifo_read(struct omap_mbox *mbox) { struct omap_mbox2_fifo *fifo = &((struct omap_mbox2_priv *)mbox->priv)->rx_fifo; return (mbox_msg_t) mbox_read_reg(fifo->msg); } -static inline void omap2_mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg) +static void omap2_mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg) { struct omap_mbox2_fifo *fifo = &((struct omap_mbox2_priv *)mbox->priv)->tx_fifo; mbox_write_reg(msg, fifo->msg); } -static inline int omap2_mbox_fifo_empty(struct omap_mbox *mbox) +static int omap2_mbox_fifo_empty(struct omap_mbox *mbox) { struct omap_mbox2_fifo *fifo = &((struct omap_mbox2_priv *)mbox->priv)->rx_fifo; return (mbox_read_reg(fifo->msg_stat) == 0); } -static inline int omap2_mbox_fifo_full(struct omap_mbox *mbox) +static int omap2_mbox_fifo_full(struct omap_mbox *mbox) { struct omap_mbox2_fifo *fifo = &((struct omap_mbox2_priv *)mbox->priv)->tx_fifo; @@ -136,7 +141,7 @@ static inline int omap2_mbox_fifo_full(struct omap_mbox *mbox) } /* Mailbox IRQ handle functions */ -static inline void omap2_mbox_enable_irq(struct omap_mbox *mbox, +static void omap2_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_type_t irq) { struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox->priv; @@ -147,7 +152,7 @@ static inline void omap2_mbox_enable_irq(struct omap_mbox *mbox, mbox_write_reg(l, p->irqenable); } -static inline void omap2_mbox_disable_irq(struct omap_mbox *mbox, +static void omap2_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_type_t irq) { struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox->priv; @@ -158,7 +163,7 @@ static inline void omap2_mbox_disable_irq(struct omap_mbox *mbox, mbox_write_reg(l, p->irqenable); } -static inline void omap2_mbox_ack_irq(struct omap_mbox *mbox, +static void omap2_mbox_ack_irq(struct omap_mbox *mbox, omap_mbox_type_t irq) { struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox->priv; @@ -167,7 +172,7 @@ static inline void omap2_mbox_ack_irq(struct omap_mbox *mbox, mbox_write_reg(bit, p->irqstatus); } -static inline int omap2_mbox_is_irq(struct omap_mbox *mbox, +static int omap2_mbox_is_irq(struct omap_mbox *mbox, omap_mbox_type_t irq) { struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox->priv; diff --git a/arch/arm/mach-omap2/prm.h b/arch/arm/mach-omap2/prm.h index ab7649afd8913cc587821036e0aa0a543e35a940..618f8111658a1dc4be748429b9ba9b08f1d53782 100644 --- a/arch/arm/mach-omap2/prm.h +++ b/arch/arm/mach-omap2/prm.h @@ -30,7 +30,7 @@ /* * Architecture-specific global PRM registers - * Use prm_{read,write}_reg() with these registers. + * Use __raw_{read,write}l() with these registers. * * With a few exceptions, these are the register names beginning with * PRCM_* on 24xx, and PRM_* on 34xx. (The exceptions are the diff --git a/arch/arm/mach-orion5x/addr-map.c b/arch/arm/mach-orion5x/addr-map.c index 9608503d67f5475eda40eaea8efc252f5c123a9d..e63fb05dc8931e637bbec1f6c0f7398e79ebc09a 100644 --- a/arch/arm/mach-orion5x/addr-map.c +++ b/arch/arm/mach-orion5x/addr-map.c @@ -34,11 +34,7 @@ * Non-CPU Masters address decoding -- * Unlike the CPU, we setup the access from Orion's master interfaces to DDR * banks only (the typical use case). - * Setup access for each master to DDR is issued by common.c. - * - * Note: although orion_setbits() and orion_clrbits() are not atomic - * no locking is necessary here since code in this file is only called - * at boot time when there is no concurrency issues. + * Setup access for each master to DDR is issued by platform device setup. */ /* @@ -48,10 +44,6 @@ #define TARGET_DEV_BUS 1 #define TARGET_PCI 3 #define TARGET_PCIE 4 -#define ATTR_DDR_CS(n) (((n) ==0) ? 0xe : \ - ((n) == 1) ? 0xd : \ - ((n) == 2) ? 0xb : \ - ((n) == 3) ? 0x7 : 0xf) #define ATTR_PCIE_MEM 0x59 #define ATTR_PCIE_IO 0x51 #define ATTR_PCIE_WA 0x79 @@ -61,17 +53,12 @@ #define ATTR_DEV_CS1 0x1d #define ATTR_DEV_CS2 0x1b #define ATTR_DEV_BOOT 0xf -#define WIN_EN 1 /* * Helpers to get DDR bank info */ -#define DDR_BASE_CS(n) ORION5X_DDR_REG(0x1500 + ((n) * 8)) -#define DDR_SIZE_CS(n) ORION5X_DDR_REG(0x1504 + ((n) * 8)) -#define DDR_MAX_CS 4 -#define DDR_REG_TO_SIZE(reg) (((reg) | 0xffffff) + 1) -#define DDR_REG_TO_BASE(reg) ((reg) & 0xff000000) -#define DDR_BANK_EN 1 +#define DDR_BASE_CS(n) ORION5X_DDR_REG(0x1500 + ((n) << 3)) +#define DDR_SIZE_CS(n) ORION5X_DDR_REG(0x1504 + ((n) << 3)) /* * CPU Address Decode Windows registers @@ -81,17 +68,6 @@ #define CPU_WIN_REMAP_LO(n) ORION5X_BRIDGE_REG(0x008 | ((n) << 4)) #define CPU_WIN_REMAP_HI(n) ORION5X_BRIDGE_REG(0x00c | ((n) << 4)) -/* - * Gigabit Ethernet Address Decode Windows registers - */ -#define ETH_WIN_BASE(win) ORION5X_ETH_REG(0x200 + ((win) * 8)) -#define ETH_WIN_SIZE(win) ORION5X_ETH_REG(0x204 + ((win) * 8)) -#define ETH_WIN_REMAP(win) ORION5X_ETH_REG(0x280 + ((win) * 4)) -#define ETH_WIN_EN ORION5X_ETH_REG(0x290) -#define ETH_WIN_PROT ORION5X_ETH_REG(0x294) -#define ETH_MAX_WIN 6 -#define ETH_MAX_REMAP_WIN 4 - struct mbus_dram_target_info orion5x_mbus_dram_info; @@ -202,39 +178,3 @@ void __init orion5x_setup_pcie_wa_win(u32 base, u32 size) { setup_cpu_win(7, base, size, TARGET_PCIE, ATTR_PCIE_WA, -1); } - -void __init orion5x_setup_eth_wins(void) -{ - int i; - - /* - * First, disable and clear windows - */ - for (i = 0; i < ETH_MAX_WIN; i++) { - orion5x_write(ETH_WIN_BASE(i), 0); - orion5x_write(ETH_WIN_SIZE(i), 0); - orion5x_setbits(ETH_WIN_EN, 1 << i); - orion5x_clrbits(ETH_WIN_PROT, 0x3 << (i * 2)); - if (i < ETH_MAX_REMAP_WIN) - orion5x_write(ETH_WIN_REMAP(i), 0); - } - - /* - * Setup windows for DDR banks. - */ - for (i = 0; i < DDR_MAX_CS; i++) { - u32 base, size; - size = orion5x_read(DDR_SIZE_CS(i)); - base = orion5x_read(DDR_BASE_CS(i)); - if (size & DDR_BANK_EN) { - base = DDR_REG_TO_BASE(base); - size = DDR_REG_TO_SIZE(size); - orion5x_write(ETH_WIN_SIZE(i), (size-1) & 0xffff0000); - orion5x_write(ETH_WIN_BASE(i), (base & 0xffff0000) | - (ATTR_DDR_CS(i) << 8) | - TARGET_DDR); - orion5x_clrbits(ETH_WIN_EN, 1 << i); - orion5x_setbits(ETH_WIN_PROT, 0x3 << (i * 2)); - } - } -} diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c index 968deb58be01f7c9dd42905c486897feb5634928..4f13fd037f0421ef039bddd38d47a712abd0a05e 100644 --- a/arch/arm/mach-orion5x/common.c +++ b/arch/arm/mach-orion5x/common.c @@ -190,6 +190,11 @@ static struct platform_device orion5x_ehci1 = { * (The Orion and Discovery (MV643xx) families use the same Ethernet driver) ****************************************************************************/ +struct mv643xx_eth_shared_platform_data orion5x_eth_shared_data = { + .dram = &orion5x_mbus_dram_info, + .t_clk = ORION5X_TCLK, +}; + static struct resource orion5x_eth_shared_resources[] = { { .start = ORION5X_ETH_PHYS_BASE + 0x2000, @@ -201,6 +206,9 @@ static struct resource orion5x_eth_shared_resources[] = { static struct platform_device orion5x_eth_shared = { .name = MV643XX_ETH_SHARED_NAME, .id = 0, + .dev = { + .platform_data = &orion5x_eth_shared_data, + }, .num_resources = 1, .resource = orion5x_eth_shared_resources, }; @@ -223,7 +231,9 @@ static struct platform_device orion5x_eth = { void __init orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data) { + eth_data->shared = &orion5x_eth_shared; orion5x_eth.dev.platform_data = eth_data; + platform_device_register(&orion5x_eth_shared); platform_device_register(&orion5x_eth); } @@ -360,7 +370,6 @@ void __init orion5x_init(void) * Setup Orion address map */ orion5x_setup_cpu_mbus_bridge(); - orion5x_setup_eth_wins(); /* * Register devices. diff --git a/arch/arm/mach-orion5x/common.h b/arch/arm/mach-orion5x/common.h index 14adf8d1a54ac8d96f33e23a8a92b98369faab72..bd0f05de6e18d2698087a5c72393101798477b26 100644 --- a/arch/arm/mach-orion5x/common.h +++ b/arch/arm/mach-orion5x/common.h @@ -22,7 +22,6 @@ void orion5x_setup_dev0_win(u32 base, u32 size); void orion5x_setup_dev1_win(u32 base, u32 size); void orion5x_setup_dev2_win(u32 base, u32 size); void orion5x_setup_pcie_wa_win(u32 base, u32 size); -void orion5x_setup_eth_wins(void); /* * Shared code used internally by other Orion core functions. diff --git a/arch/arm/mach-orion5x/dns323-setup.c b/arch/arm/mach-orion5x/dns323-setup.c index f9430f5ca9a8891d01ea4a5f2ea57894af0e923e..27ce967ab9e5c3792420bd47badd441ff527950f 100644 --- a/arch/arm/mach-orion5x/dns323-setup.c +++ b/arch/arm/mach-orion5x/dns323-setup.c @@ -58,7 +58,7 @@ static int __init dns323_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) } static struct hw_pci dns323_pci __initdata = { - .nr_controllers = 1, + .nr_controllers = 2, .swizzle = pci_std_swizzle, .setup = orion5x_pci_sys_setup, .scan = orion5x_pci_sys_scan_bus, diff --git a/arch/arm/mach-orion5x/kurobox_pro-setup.c b/arch/arm/mach-orion5x/kurobox_pro-setup.c index 88410862feefa6d7b3c2d75b546ad80de62c485e..f5074b877b7fbfbc6dfcfe7eb8d7a1852c66e3cb 100644 --- a/arch/arm/mach-orion5x/kurobox_pro-setup.c +++ b/arch/arm/mach-orion5x/kurobox_pro-setup.c @@ -138,7 +138,7 @@ static int __init kurobox_pro_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) } static struct hw_pci kurobox_pro_pci __initdata = { - .nr_controllers = 1, + .nr_controllers = 2, .swizzle = pci_std_swizzle, .setup = orion5x_pci_sys_setup, .scan = orion5x_pci_sys_scan_bus, diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index 6a830853aa6a610e532c33040f0ab96544dc8c3e..0e6d05bb81aa9ae806ea6461078dea57679e1445 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile @@ -5,6 +5,13 @@ # Common support (must be linked before board specific support) obj-y += clock.o devices.o generic.o irq.o dma.o \ time.o gpio.o +obj-$(CONFIG_PM) += pm.o sleep.o standby.o +obj-$(CONFIG_CPU_FREQ) += cpu-pxa.o + +# Generic drivers that other drivers may depend upon +obj-$(CONFIG_PXA_SSP) += ssp.o + +# SoC-specific code obj-$(CONFIG_PXA25x) += mfp-pxa2xx.o pxa25x.o obj-$(CONFIG_PXA27x) += mfp-pxa2xx.o pxa27x.o obj-$(CONFIG_PXA3xx) += mfp-pxa3xx.o pxa3xx.o smemc.o @@ -48,11 +55,6 @@ led-$(CONFIG_MACH_TRIZEPS4) += leds-trizeps4.o obj-$(CONFIG_LEDS) += $(led-y) -# Misc features -obj-$(CONFIG_PM) += pm.o sleep.o standby.o -obj-$(CONFIG_CPU_FREQ) += cpu-pxa.o -obj-$(CONFIG_PXA_SSP) += ssp.o - ifeq ($(CONFIG_PCI),y) obj-$(CONFIG_MACH_ARMCORE) += cm-x270-pci.o endif diff --git a/arch/arm/mach-pxa/colibri.c b/arch/arm/mach-pxa/colibri.c index 43bf5a183e90da539d757505a4031d482ed4deb1..574839d7c1328c1c83f4c354b7cb51800c3f8516 100644 --- a/arch/arm/mach-pxa/colibri.c +++ b/arch/arm/mach-pxa/colibri.c @@ -98,7 +98,7 @@ static struct resource dm9000_resources[] = { [2] = { .start = COLIBRI_ETH_IRQ, .end = COLIBRI_ETH_IRQ, - .flags = IORESOURCE_IRQ, + .flags = IORESOURCE_IRQ | IRQF_TRIGGER_RISING, }, }; @@ -119,7 +119,6 @@ static void __init colibri_init(void) /* DM9000 LAN */ pxa_gpio_mode(GPIO78_nCS_2_MD); pxa_gpio_mode(GPIO_DM9000 | GPIO_IN); - set_irq_type(COLIBRI_ETH_IRQ, IRQT_FALLING); platform_add_devices(colibri_devices, ARRAY_SIZE(colibri_devices)); } diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c index 259ca821e464444d3ae02b0d1bbad9031697cad1..b757dd7566552e6a547eaf1137f1ea3563ed5820 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c @@ -493,8 +493,6 @@ static struct platform_device *devices[] __initdata = { static void corgi_poweroff(void) { - RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR; - if (!machine_is_corgi()) /* Green LED off tells the bootloader to halt */ reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_LED_GREEN); @@ -503,8 +501,6 @@ static void corgi_poweroff(void) static void corgi_restart(char mode) { - RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR; - if (!machine_is_corgi()) /* Green LED on tells the bootloader to reboot */ set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_LED_GREEN); diff --git a/arch/arm/mach-pxa/cpu-pxa.c b/arch/arm/mach-pxa/cpu-pxa.c index 4b21479332ae40c073c1f184b1980a502aca4c40..fb9ba1ab28269bddf4dc938f000f691bdaee1d29 100644 --- a/arch/arm/mach-pxa/cpu-pxa.c +++ b/arch/arm/mach-pxa/cpu-pxa.c @@ -49,125 +49,216 @@ MODULE_PARM_DESC(freq_debug, "Set the debug messages to on=1/off=0"); #define freq_debug 0 #endif +static unsigned int pxa27x_maxfreq; +module_param(pxa27x_maxfreq, uint, 0); +MODULE_PARM_DESC(pxa27x_maxfreq, "Set the pxa27x maxfreq in MHz" + "(typically 624=>pxa270, 416=>pxa271, 520=>pxa272)"); + typedef struct { unsigned int khz; unsigned int membus; unsigned int cccr; unsigned int div2; + unsigned int cclkcfg; } pxa_freqs_t; /* Define the refresh period in mSec for the SDRAM and the number of rows */ -#define SDRAM_TREF 64 /* standard 64ms SDRAM */ -#define SDRAM_ROWS 4096 /* 64MB=8192 32MB=4096 */ -#define MDREFR_DRI(x) (((x) * SDRAM_TREF) / (SDRAM_ROWS * 32)) - -#define CCLKCFG_TURBO 0x1 -#define CCLKCFG_FCS 0x2 -#define PXA25x_MIN_FREQ 99500 -#define PXA25x_MAX_FREQ 398100 -#define MDREFR_DB2_MASK (MDREFR_K2DB2 | MDREFR_K1DB2) -#define MDREFR_DRI_MASK 0xFFF +#define SDRAM_TREF 64 /* standard 64ms SDRAM */ +#define SDRAM_ROWS 4096 /* 64MB=8192 32MB=4096 */ +#define CCLKCFG_TURBO 0x1 +#define CCLKCFG_FCS 0x2 +#define CCLKCFG_HALFTURBO 0x4 +#define CCLKCFG_FASTBUS 0x8 +#define MDREFR_DB2_MASK (MDREFR_K2DB2 | MDREFR_K1DB2) +#define MDREFR_DRI_MASK 0xFFF +/* + * PXA255 definitions + */ /* Use the run mode frequencies for the CPUFREQ_POLICY_PERFORMANCE policy */ +#define CCLKCFG CCLKCFG_TURBO | CCLKCFG_FCS + static pxa_freqs_t pxa255_run_freqs[] = { - /* CPU MEMBUS CCCR DIV2*/ - { 99500, 99500, 0x121, 1}, /* run= 99, turbo= 99, PXbus=50, SDRAM=50 */ - {132700, 132700, 0x123, 1}, /* run=133, turbo=133, PXbus=66, SDRAM=66 */ - {199100, 99500, 0x141, 0}, /* run=199, turbo=199, PXbus=99, SDRAM=99 */ - {265400, 132700, 0x143, 1}, /* run=265, turbo=265, PXbus=133, SDRAM=66 */ - {331800, 165900, 0x145, 1}, /* run=331, turbo=331, PXbus=166, SDRAM=83 */ - {398100, 99500, 0x161, 0}, /* run=398, turbo=398, PXbus=196, SDRAM=99 */ - {0,} + /* CPU MEMBUS CCCR DIV2 CCLKCFG run turbo PXbus SDRAM */ + { 99500, 99500, 0x121, 1, CCLKCFG}, /* 99, 99, 50, 50 */ + {132700, 132700, 0x123, 1, CCLKCFG}, /* 133, 133, 66, 66 */ + {199100, 99500, 0x141, 0, CCLKCFG}, /* 199, 199, 99, 99 */ + {265400, 132700, 0x143, 1, CCLKCFG}, /* 265, 265, 133, 66 */ + {331800, 165900, 0x145, 1, CCLKCFG}, /* 331, 331, 166, 83 */ + {398100, 99500, 0x161, 0, CCLKCFG}, /* 398, 398, 196, 99 */ }; -#define NUM_RUN_FREQS ARRAY_SIZE(pxa255_run_freqs) - -static struct cpufreq_frequency_table pxa255_run_freq_table[NUM_RUN_FREQS+1]; /* Use the turbo mode frequencies for the CPUFREQ_POLICY_POWERSAVE policy */ static pxa_freqs_t pxa255_turbo_freqs[] = { - /* CPU MEMBUS CCCR DIV2*/ - { 99500, 99500, 0x121, 1}, /* run=99, turbo= 99, PXbus=50, SDRAM=50 */ - {199100, 99500, 0x221, 0}, /* run=99, turbo=199, PXbus=50, SDRAM=99 */ - {298500, 99500, 0x321, 0}, /* run=99, turbo=287, PXbus=50, SDRAM=99 */ - {298600, 99500, 0x1c1, 0}, /* run=199, turbo=287, PXbus=99, SDRAM=99 */ - {398100, 99500, 0x241, 0}, /* run=199, turbo=398, PXbus=99, SDRAM=99 */ - {0,} + /* CPU MEMBUS CCCR DIV2 CCLKCFG run turbo PXbus SDRAM */ + { 99500, 99500, 0x121, 1, CCLKCFG}, /* 99, 99, 50, 50 */ + {199100, 99500, 0x221, 0, CCLKCFG}, /* 99, 199, 50, 99 */ + {298500, 99500, 0x321, 0, CCLKCFG}, /* 99, 287, 50, 99 */ + {298600, 99500, 0x1c1, 0, CCLKCFG}, /* 199, 287, 99, 99 */ + {398100, 99500, 0x241, 0, CCLKCFG}, /* 199, 398, 99, 99 */ +}; + +#define NUM_PXA25x_RUN_FREQS ARRAY_SIZE(pxa255_run_freqs) +#define NUM_PXA25x_TURBO_FREQS ARRAY_SIZE(pxa255_turbo_freqs) + +static struct cpufreq_frequency_table + pxa255_run_freq_table[NUM_PXA25x_RUN_FREQS+1]; +static struct cpufreq_frequency_table + pxa255_turbo_freq_table[NUM_PXA25x_TURBO_FREQS+1]; + +/* + * PXA270 definitions + * + * For the PXA27x: + * Control variables are A, L, 2N for CCCR; B, HT, T for CLKCFG. + * + * A = 0 => memory controller clock from table 3-7, + * A = 1 => memory controller clock = system bus clock + * Run mode frequency = 13 MHz * L + * Turbo mode frequency = 13 MHz * L * N + * System bus frequency = 13 MHz * L / (B + 1) + * + * In CCCR: + * A = 1 + * L = 16 oscillator to run mode ratio + * 2N = 6 2 * (turbo mode to run mode ratio) + * + * In CCLKCFG: + * B = 1 Fast bus mode + * HT = 0 Half-Turbo mode + * T = 1 Turbo mode + * + * For now, just support some of the combinations in table 3-7 of + * PXA27x Processor Family Developer's Manual to simplify frequency + * change sequences. + */ +#define PXA27x_CCCR(A, L, N2) (A << 25 | N2 << 7 | L) +#define CCLKCFG2(B, HT, T) \ + (CCLKCFG_FCS | \ + ((B) ? CCLKCFG_FASTBUS : 0) | \ + ((HT) ? CCLKCFG_HALFTURBO : 0) | \ + ((T) ? CCLKCFG_TURBO : 0)) + +static pxa_freqs_t pxa27x_freqs[] = { + {104000, 104000, PXA27x_CCCR(1, 8, 2), 0, CCLKCFG2(1, 0, 1)}, + {156000, 104000, PXA27x_CCCR(1, 8, 6), 0, CCLKCFG2(1, 1, 1)}, + {208000, 208000, PXA27x_CCCR(0, 16, 2), 1, CCLKCFG2(0, 0, 1)}, + {312000, 208000, PXA27x_CCCR(1, 16, 3), 1, CCLKCFG2(1, 0, 1)}, + {416000, 208000, PXA27x_CCCR(1, 16, 4), 1, CCLKCFG2(1, 0, 1)}, + {520000, 208000, PXA27x_CCCR(1, 16, 5), 1, CCLKCFG2(1, 0, 1)}, + {624000, 208000, PXA27x_CCCR(1, 16, 6), 1, CCLKCFG2(1, 0, 1)} }; -#define NUM_TURBO_FREQS ARRAY_SIZE(pxa255_turbo_freqs) -static struct cpufreq_frequency_table pxa255_turbo_freq_table[NUM_TURBO_FREQS+1]; +#define NUM_PXA27x_FREQS ARRAY_SIZE(pxa27x_freqs) +static struct cpufreq_frequency_table + pxa27x_freq_table[NUM_PXA27x_FREQS+1]; extern unsigned get_clk_frequency_khz(int info); +static void find_freq_tables(struct cpufreq_policy *policy, + struct cpufreq_frequency_table **freq_table, + pxa_freqs_t **pxa_freqs) +{ + if (cpu_is_pxa25x()) { + if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) { + *pxa_freqs = pxa255_run_freqs; + *freq_table = pxa255_run_freq_table; + } else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) { + *pxa_freqs = pxa255_turbo_freqs; + *freq_table = pxa255_turbo_freq_table; + } else { + printk("CPU PXA: Unknown policy found. " + "Using CPUFREQ_POLICY_PERFORMANCE\n"); + *pxa_freqs = pxa255_run_freqs; + *freq_table = pxa255_run_freq_table; + } + } + if (cpu_is_pxa27x()) { + *pxa_freqs = pxa27x_freqs; + *freq_table = pxa27x_freq_table; + } +} + +static void pxa27x_guess_max_freq(void) +{ + if (!pxa27x_maxfreq) { + pxa27x_maxfreq = 416000; + printk(KERN_INFO "PXA CPU 27x max frequency not defined " + "(pxa27x_maxfreq), assuming pxa271 with %dkHz maxfreq\n", + pxa27x_maxfreq); + } else { + pxa27x_maxfreq *= 1000; + } +} + +static u32 mdrefr_dri(unsigned int freq) +{ + u32 dri = 0; + + if (cpu_is_pxa25x()) + dri = ((freq * SDRAM_TREF) / (SDRAM_ROWS * 32)); + if (cpu_is_pxa27x()) + dri = ((freq * SDRAM_TREF) / (SDRAM_ROWS - 31)) / 32; + return dri; +} + /* find a valid frequency point */ static int pxa_verify_policy(struct cpufreq_policy *policy) { struct cpufreq_frequency_table *pxa_freqs_table; + pxa_freqs_t *pxa_freqs; int ret; - if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) { - pxa_freqs_table = pxa255_run_freq_table; - } else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) { - pxa_freqs_table = pxa255_turbo_freq_table; - } else { - printk("CPU PXA: Unknown policy found. " - "Using CPUFREQ_POLICY_PERFORMANCE\n"); - pxa_freqs_table = pxa255_run_freq_table; - } - + find_freq_tables(policy, &pxa_freqs_table, &pxa_freqs); ret = cpufreq_frequency_table_verify(policy, pxa_freqs_table); if (freq_debug) pr_debug("Verified CPU policy: %dKhz min to %dKhz max\n", - policy->min, policy->max); + policy->min, policy->max); return ret; } +static unsigned int pxa_cpufreq_get(unsigned int cpu) +{ + return get_clk_frequency_khz(0); +} + static int pxa_set_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) + unsigned int target_freq, + unsigned int relation) { struct cpufreq_frequency_table *pxa_freqs_table; pxa_freqs_t *pxa_freq_settings; struct cpufreq_freqs freqs; unsigned int idx; unsigned long flags; - unsigned int unused, preset_mdrefr, postset_mdrefr; - void *ramstart = phys_to_virt(0xa0000000); + unsigned int new_freq_cpu, new_freq_mem; + unsigned int unused, preset_mdrefr, postset_mdrefr, cclkcfg; /* Get the current policy */ - if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) { - pxa_freq_settings = pxa255_run_freqs; - pxa_freqs_table = pxa255_run_freq_table; - } else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) { - pxa_freq_settings = pxa255_turbo_freqs; - pxa_freqs_table = pxa255_turbo_freq_table; - } else { - printk("CPU PXA: Unknown policy found. " - "Using CPUFREQ_POLICY_PERFORMANCE\n"); - pxa_freq_settings = pxa255_run_freqs; - pxa_freqs_table = pxa255_run_freq_table; - } + find_freq_tables(policy, &pxa_freqs_table, &pxa_freq_settings); /* Lookup the next frequency */ if (cpufreq_frequency_table_target(policy, pxa_freqs_table, - target_freq, relation, &idx)) { + target_freq, relation, &idx)) { return -EINVAL; } + new_freq_cpu = pxa_freq_settings[idx].khz; + new_freq_mem = pxa_freq_settings[idx].membus; freqs.old = policy->cur; - freqs.new = pxa_freq_settings[idx].khz; + freqs.new = new_freq_cpu; freqs.cpu = policy->cpu; if (freq_debug) - pr_debug(KERN_INFO "Changing CPU frequency to %d Mhz, (SDRAM %d Mhz)\n", - freqs.new / 1000, (pxa_freq_settings[idx].div2) ? - (pxa_freq_settings[idx].membus / 2000) : - (pxa_freq_settings[idx].membus / 1000)); + pr_debug(KERN_INFO "Changing CPU frequency to %d Mhz, " + "(SDRAM %d Mhz)\n", + freqs.new / 1000, (pxa_freq_settings[idx].div2) ? + (new_freq_mem / 2000) : (new_freq_mem / 1000)); /* * Tell everyone what we're about to do... @@ -177,16 +268,16 @@ static int pxa_set_target(struct cpufreq_policy *policy, cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); /* Calculate the next MDREFR. If we're slowing down the SDRAM clock - * we need to preset the smaller DRI before the change. If we're speeding - * up we need to set the larger DRI value after the change. + * we need to preset the smaller DRI before the change. If we're + * speeding up we need to set the larger DRI value after the change. */ preset_mdrefr = postset_mdrefr = MDREFR; - if ((MDREFR & MDREFR_DRI_MASK) > MDREFR_DRI(pxa_freq_settings[idx].membus)) { - preset_mdrefr = (preset_mdrefr & ~MDREFR_DRI_MASK) | - MDREFR_DRI(pxa_freq_settings[idx].membus); + if ((MDREFR & MDREFR_DRI_MASK) > mdrefr_dri(new_freq_mem)) { + preset_mdrefr = (preset_mdrefr & ~MDREFR_DRI_MASK); + preset_mdrefr |= mdrefr_dri(new_freq_mem); } - postset_mdrefr = (postset_mdrefr & ~MDREFR_DRI_MASK) | - MDREFR_DRI(pxa_freq_settings[idx].membus); + postset_mdrefr = + (postset_mdrefr & ~MDREFR_DRI_MASK) | mdrefr_dri(new_freq_mem); /* If we're dividing the memory clock by two for the SDRAM clock, this * must be set prior to the change. Clearing the divide must be done @@ -201,26 +292,27 @@ static int pxa_set_target(struct cpufreq_policy *policy, local_irq_save(flags); - /* Set new the CCCR */ + /* Set new the CCCR and prepare CCLKCFG */ CCCR = pxa_freq_settings[idx].cccr; + cclkcfg = pxa_freq_settings[idx].cclkcfg; asm volatile(" \n\ ldr r4, [%1] /* load MDREFR */ \n\ b 2f \n\ - .align 5 \n\ + .align 5 \n\ 1: \n\ - str %4, [%1] /* preset the MDREFR */ \n\ + str %3, [%1] /* preset the MDREFR */ \n\ mcr p14, 0, %2, c6, c0, 0 /* set CCLKCFG[FCS] */ \n\ - str %5, [%1] /* postset the MDREFR */ \n\ + str %4, [%1] /* postset the MDREFR */ \n\ \n\ b 3f \n\ 2: b 1b \n\ 3: nop \n\ " - : "=&r" (unused) - : "r" (&MDREFR), "r" (CCLKCFG_TURBO|CCLKCFG_FCS), "r" (ramstart), - "r" (preset_mdrefr), "r" (postset_mdrefr) - : "r4", "r5"); + : "=&r" (unused) + : "r" (&MDREFR), "r" (cclkcfg), + "r" (preset_mdrefr), "r" (postset_mdrefr) + : "r4", "r5"); local_irq_restore(flags); /* @@ -233,38 +325,57 @@ static int pxa_set_target(struct cpufreq_policy *policy, return 0; } -static unsigned int pxa_cpufreq_get(unsigned int cpu) -{ - return get_clk_frequency_khz(0); -} - -static int pxa_cpufreq_init(struct cpufreq_policy *policy) +static __init int pxa_cpufreq_init(struct cpufreq_policy *policy) { int i; + unsigned int freq; + + /* try to guess pxa27x cpu */ + if (cpu_is_pxa27x()) + pxa27x_guess_max_freq(); /* set default policy and cpuinfo */ policy->governor = CPUFREQ_DEFAULT_GOVERNOR; - policy->policy = CPUFREQ_POLICY_PERFORMANCE; - policy->cpuinfo.max_freq = PXA25x_MAX_FREQ; - policy->cpuinfo.min_freq = PXA25x_MIN_FREQ; + if (cpu_is_pxa25x()) + policy->policy = CPUFREQ_POLICY_PERFORMANCE; policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */ - policy->cur = get_clk_frequency_khz(0); /* current freq */ + policy->cur = get_clk_frequency_khz(0); /* current freq */ policy->min = policy->max = policy->cur; - /* Generate the run cpufreq_frequency_table struct */ - for (i = 0; i < NUM_RUN_FREQS; i++) { + /* Generate pxa25x the run cpufreq_frequency_table struct */ + for (i = 0; i < NUM_PXA25x_RUN_FREQS; i++) { pxa255_run_freq_table[i].frequency = pxa255_run_freqs[i].khz; pxa255_run_freq_table[i].index = i; } - pxa255_run_freq_table[i].frequency = CPUFREQ_TABLE_END; - /* Generate the turbo cpufreq_frequency_table struct */ - for (i = 0; i < NUM_TURBO_FREQS; i++) { - pxa255_turbo_freq_table[i].frequency = pxa255_turbo_freqs[i].khz; + + /* Generate pxa25x the turbo cpufreq_frequency_table struct */ + for (i = 0; i < NUM_PXA25x_TURBO_FREQS; i++) { + pxa255_turbo_freq_table[i].frequency = + pxa255_turbo_freqs[i].khz; pxa255_turbo_freq_table[i].index = i; } pxa255_turbo_freq_table[i].frequency = CPUFREQ_TABLE_END; + /* Generate the pxa27x cpufreq_frequency_table struct */ + for (i = 0; i < NUM_PXA27x_FREQS; i++) { + freq = pxa27x_freqs[i].khz; + if (freq > pxa27x_maxfreq) + break; + pxa27x_freq_table[i].frequency = freq; + pxa27x_freq_table[i].index = i; + } + pxa27x_freq_table[i].frequency = CPUFREQ_TABLE_END; + + /* + * Set the policy's minimum and maximum frequencies from the tables + * just constructed. This sets cpuinfo.mxx_freq, min and max. + */ + if (cpu_is_pxa25x()) + cpufreq_frequency_table_cpuinfo(policy, pxa255_run_freq_table); + else if (cpu_is_pxa27x()) + cpufreq_frequency_table_cpuinfo(policy, pxa27x_freq_table); + printk(KERN_INFO "PXA CPU frequency change support initialized\n"); return 0; @@ -275,26 +386,25 @@ static struct cpufreq_driver pxa_cpufreq_driver = { .target = pxa_set_target, .init = pxa_cpufreq_init, .get = pxa_cpufreq_get, - .name = "PXA25x", + .name = "PXA2xx", }; static int __init pxa_cpu_init(void) { int ret = -ENODEV; - if (cpu_is_pxa25x()) + if (cpu_is_pxa25x() || cpu_is_pxa27x()) ret = cpufreq_register_driver(&pxa_cpufreq_driver); return ret; } static void __exit pxa_cpu_exit(void) { - if (cpu_is_pxa25x()) - cpufreq_unregister_driver(&pxa_cpufreq_driver); + cpufreq_unregister_driver(&pxa_cpufreq_driver); } -MODULE_AUTHOR ("Intrinsyc Software Inc."); -MODULE_DESCRIPTION ("CPU frequency changing driver for the PXA architecture"); +MODULE_AUTHOR("Intrinsyc Software Inc."); +MODULE_DESCRIPTION("CPU frequency changing driver for the PXA architecture"); MODULE_LICENSE("GPL"); module_init(pxa_cpu_init); module_exit(pxa_cpu_exit); diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index 0993f4d1a0bc71bba362a86a2c92aba54f56ee4f..7b9bdd0c66653b5a423b772d7f7e8152975e25ef 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c @@ -396,7 +396,7 @@ static struct pxafb_mach_info sharp_lm8v31 = { .cmap_inverse = 0, .cmap_static = 0, .lcd_conn = LCD_COLOR_DSTN_16BPP | LCD_PCLK_EDGE_FALL | - LCD_AC_BIAS_FREQ(255); + LCD_AC_BIAS_FREQ(255), }; #define MMC_POLL_RATE msecs_to_jiffies(1000) diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c index ec1bbf333a3ad5a74c8c1cb06c2b0c6613fa277b..7d4debbdcca3feb1c9fa253f0441256d670c6a84 100644 --- a/arch/arm/mach-pxa/pm.c +++ b/arch/arm/mach-pxa/pm.c @@ -42,20 +42,17 @@ int pxa_pm_enter(suspend_state_t state) if (state != PM_SUSPEND_STANDBY) { pxa_cpu_pm_fns->save(sleep_save); /* before sleeping, calculate and save a checksum */ - for (i = 0; i < pxa_cpu_pm_fns->save_size - 1; i++) + for (i = 0; i < pxa_cpu_pm_fns->save_count - 1; i++) sleep_save_checksum += sleep_save[i]; } - /* Clear reset status */ - RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR; - /* *** go zzz *** */ pxa_cpu_pm_fns->enter(state); cpu_init(); if (state != PM_SUSPEND_STANDBY) { /* after sleeping, validate the checksum */ - for (i = 0; i < pxa_cpu_pm_fns->save_size - 1; i++) + for (i = 0; i < pxa_cpu_pm_fns->save_count - 1; i++) checksum += sleep_save[i]; /* if invalid, display message and wait for a hardware reset */ @@ -101,7 +98,8 @@ static int __init pxa_pm_init(void) return -EINVAL; } - sleep_save = kmalloc(pxa_cpu_pm_fns->save_size, GFP_KERNEL); + sleep_save = kmalloc(pxa_cpu_pm_fns->save_count * sizeof(unsigned long), + GFP_KERNEL); if (!sleep_save) { printk(KERN_ERR "failed to alloc memory for pm save\n"); return -ENOMEM; diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c index ca5ac196b47b71e3b011281ed5e77dc574df65b7..0b30f25cff3c15020d6363f1469b1c0e75977935 100644 --- a/arch/arm/mach-pxa/poodle.c +++ b/arch/arm/mach-pxa/poodle.c @@ -326,13 +326,11 @@ static struct platform_device *devices[] __initdata = { static void poodle_poweroff(void) { - RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR; arm_machine_restart('h'); } static void poodle_restart(char mode) { - RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR; arm_machine_restart('h'); } diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index d9b5450aee5b68e227e1fbf96ad24ad396a3ac88..e5b417d14bb04b772689b431631994c7985899d5 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c @@ -150,9 +150,7 @@ static struct clk pxa25x_clks[] = { * More ones like CP and general purpose register values are preserved * with the stack pointer in sleep.S. */ -enum { SLEEP_SAVE_START = 0, - - SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, +enum { SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U, SLEEP_SAVE_GAFR1_L, SLEEP_SAVE_GAFR1_U, @@ -162,7 +160,7 @@ enum { SLEEP_SAVE_START = 0, SLEEP_SAVE_CKEN, - SLEEP_SAVE_SIZE + SLEEP_SAVE_COUNT }; @@ -200,6 +198,9 @@ static void pxa25x_cpu_pm_restore(unsigned long *sleep_save) static void pxa25x_cpu_pm_enter(suspend_state_t state) { + /* Clear reset status */ + RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR; + switch (state) { case PM_SUSPEND_MEM: /* set resume return address */ @@ -210,7 +211,7 @@ static void pxa25x_cpu_pm_enter(suspend_state_t state) } static struct pxa_cpu_pm_fns pxa25x_cpu_pm_fns = { - .save_size = SLEEP_SAVE_SIZE, + .save_count = SLEEP_SAVE_COUNT, .valid = suspend_valid_only_mem, .save = pxa25x_cpu_pm_save, .restore = pxa25x_cpu_pm_restore, diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index 7a2449dd0fd4f19ebf7ac64c59290b7f4d8bd5b6..7e945836e12924e9e4a5b89a4edd3331f339710a 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -181,9 +181,7 @@ static struct clk pxa27x_clks[] = { * More ones like CP and general purpose register values are preserved * with the stack pointer in sleep.S. */ -enum { SLEEP_SAVE_START = 0, - - SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, SLEEP_SAVE_PGSR3, +enum { SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, SLEEP_SAVE_PGSR3, SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U, SLEEP_SAVE_GAFR1_L, SLEEP_SAVE_GAFR1_U, @@ -198,7 +196,7 @@ enum { SLEEP_SAVE_START = 0, SLEEP_SAVE_PWER, SLEEP_SAVE_PCFR, SLEEP_SAVE_PRER, SLEEP_SAVE_PFER, SLEEP_SAVE_PKWR, - SLEEP_SAVE_SIZE + SLEEP_SAVE_COUNT }; void pxa27x_cpu_pm_save(unsigned long *sleep_save) @@ -251,6 +249,9 @@ void pxa27x_cpu_pm_enter(suspend_state_t state) /* Clear edge-detect status register. */ PEDR = 0xDF12FE1B; + /* Clear reset status */ + RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR; + switch (state) { case PM_SUSPEND_STANDBY: pxa_cpu_standby(); @@ -269,7 +270,7 @@ static int pxa27x_cpu_pm_valid(suspend_state_t state) } static struct pxa_cpu_pm_fns pxa27x_cpu_pm_fns = { - .save_size = SLEEP_SAVE_SIZE, + .save_count = SLEEP_SAVE_COUNT, .save = pxa27x_cpu_pm_save, .restore = pxa27x_cpu_pm_restore, .valid = pxa27x_cpu_pm_valid, diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index b6a6f5fcc77ad56158bbd01b061c973ca4700285..644550bfa330fb8607dc89e3f192f864f5adc95a 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -256,12 +256,11 @@ static unsigned long wakeup_src; #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] -enum { SLEEP_SAVE_START = 0, - SLEEP_SAVE_CKENA, +enum { SLEEP_SAVE_CKENA, SLEEP_SAVE_CKENB, SLEEP_SAVE_ACCR, - SLEEP_SAVE_SIZE, + SLEEP_SAVE_COUNT, }; static void pxa3xx_cpu_pm_save(unsigned long *sleep_save) @@ -376,7 +375,7 @@ static int pxa3xx_cpu_pm_valid(suspend_state_t state) } static struct pxa_cpu_pm_fns pxa3xx_cpu_pm_fns = { - .save_size = SLEEP_SAVE_SIZE, + .save_count = SLEEP_SAVE_COUNT, .save = pxa3xx_cpu_pm_save, .restore = pxa3xx_cpu_pm_restore, .valid = pxa3xx_cpu_pm_valid, diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index 62a02c3927c576e26d0dd016c3518882a5e0778f..dace3820f1eed83dbaff06074eab806cc073e59b 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -529,8 +530,6 @@ static struct platform_device *devices[] __initdata = { static void spitz_poweroff(void) { - RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR; - pxa_gpio_mode(SPITZ_GPIO_ON_RESET | GPIO_OUT); GPSR(SPITZ_GPIO_ON_RESET) = GPIO_bit(SPITZ_GPIO_ON_RESET); diff --git a/arch/arm/mach-pxa/spitz_pm.c b/arch/arm/mach-pxa/spitz_pm.c index 7a7f5f947cc557d2a5b4e81796ab92663a09e252..23f050feb2083d152640c43e9d47f6312235cf65 100644 --- a/arch/arm/mach-pxa/spitz_pm.c +++ b/arch/arm/mach-pxa/spitz_pm.c @@ -119,9 +119,6 @@ static void spitz_presuspend(void) /* nRESET_OUT Disable */ PSLR |= PSLR_SL_ROD; - /* Clear reset status */ - RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR; - /* Stop 3.6MHz and drive HIGH to PCMCIA and CS */ PCFR = PCFR_GPR_EN | PCFR_OPDE; } diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c index 6458f6d371d966e16399ce61c596df2835f75653..c2cbd66db8147e894b806c9c110996d0996700a6 100644 --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c @@ -467,8 +467,6 @@ static struct platform_device *devices[] __initdata = { static void tosa_poweroff(void) { - RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR; - pxa_gpio_mode(TOSA_GPIO_ON_RESET | GPIO_OUT); GPSR(TOSA_GPIO_ON_RESET) = GPIO_bit(TOSA_GPIO_ON_RESET); diff --git a/arch/arm/mach-sa1100/pm.c b/arch/arm/mach-sa1100/pm.c index 246c573e7252dc0d833f1325222809bd1782e36d..1693d447a224b6eaf566ae649b9d65082f4656a0 100644 --- a/arch/arm/mach-sa1100/pm.c +++ b/arch/arm/mach-sa1100/pm.c @@ -43,20 +43,18 @@ extern void sa1100_cpu_resume(void); * More ones like CP and general purpose register values are preserved * on the stack and then the stack pointer is stored last in sleep.S. */ -enum { SLEEP_SAVE_SP = 0, - - SLEEP_SAVE_GPDR, SLEEP_SAVE_GAFR, +enum { SLEEP_SAVE_GPDR, SLEEP_SAVE_GAFR, SLEEP_SAVE_PPDR, SLEEP_SAVE_PPSR, SLEEP_SAVE_PPAR, SLEEP_SAVE_PSDR, SLEEP_SAVE_Ser1SDCR0, - SLEEP_SAVE_SIZE + SLEEP_SAVE_COUNT }; static int sa11x0_pm_enter(suspend_state_t state) { - unsigned long gpio, sleep_save[SLEEP_SAVE_SIZE]; + unsigned long gpio, sleep_save[SLEEP_SAVE_COUNT]; gpio = GPLR; diff --git a/arch/arm/mm/proc-arm925.S b/arch/arm/mm/proc-arm925.S index 065087afb7720375736329576ad0e22968dab533..d045812f33999cc0ef40d03ee95034499fd0cda1 100644 --- a/arch/arm/mm/proc-arm925.S +++ b/arch/arm/mm/proc-arm925.S @@ -332,7 +332,7 @@ ENTRY(arm925_dma_flush_range) #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry #else - mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry #endif add r0, r0, #CACHE_DLINESIZE cmp r0, r1 diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S index 997db8472b5c3c6aca4b0e99f6baba97036e21b7..4cd33169a7c917235cd8d549d36a2666c0bc32a5 100644 --- a/arch/arm/mm/proc-arm926.S +++ b/arch/arm/mm/proc-arm926.S @@ -295,7 +295,7 @@ ENTRY(arm926_dma_flush_range) #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry #else - mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry #endif add r0, r0, #CACHE_DLINESIZE cmp r0, r1 diff --git a/arch/arm/mm/proc-arm940.S b/arch/arm/mm/proc-arm940.S index 44ead902bd54f5347aa877f25bb98af2a4547f43..1a3d63df8e908055b83a8a589bbe52231b5a944f 100644 --- a/arch/arm/mm/proc-arm940.S +++ b/arch/arm/mm/proc-arm940.S @@ -222,7 +222,7 @@ ENTRY(arm940_dma_flush_range) #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH mcr p15, 0, r3, c7, c14, 2 @ clean/flush D entry #else - mcr p15, 0, r3, c7, c10, 2 @ clean D entry + mcr p15, 0, r3, c7, c6, 2 @ invalidate D entry #endif subs r3, r3, #1 << 26 bcs 2b @ entries 63 to 0 diff --git a/arch/arm/mm/proc-arm946.S b/arch/arm/mm/proc-arm946.S index 2218b0c01330a8f96a5ea4ef6b360cb596ec4ffe..82d579ac9b98f9ed4cb2bad539c7c3e085aa936b 100644 --- a/arch/arm/mm/proc-arm946.S +++ b/arch/arm/mm/proc-arm946.S @@ -265,7 +265,7 @@ ENTRY(arm946_dma_flush_range) #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry #else - mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry #endif add r0, r0, #CACHE_DLINESIZE cmp r0, r1 diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c index 72d34a23a2ec6276073af8906e916075b6808945..2946c193a7d63195806e431bc63d5b5db281a919 100644 --- a/arch/arm/plat-omap/clock.c +++ b/arch/arm/plat-omap/clock.c @@ -134,9 +134,17 @@ void clk_disable(struct clk *clk) return; spin_lock_irqsave(&clockfw_lock, flags); - BUG_ON(clk->usecount == 0); + if (clk->usecount == 0) { + printk(KERN_ERR "Trying disable clock %s with 0 usecount\n", + clk->name); + WARN_ON(1); + goto out; + } + if (arch_clock->clk_disable) arch_clock->clk_disable(clk); + +out: spin_unlock_irqrestore(&clockfw_lock, flags); } EXPORT_SYMBOL(clk_disable); diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index 793740686be278e21b7fd7c683e39280ce84d67f..c00eda588cd81b2ad87d51646a27b7ffcd577549 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c @@ -604,6 +604,7 @@ int omap_request_dma(int dev_id, const char *dev_name, chan->data = data; #ifndef CONFIG_ARCH_OMAP1 chan->chain_id = -1; + chan->next_linked_ch = -1; #endif chan->enabled_irqs = OMAP_DMA_DROP_IRQ | OMAP_DMA_BLOCK_IRQ; @@ -1087,7 +1088,6 @@ int omap_request_dma_chain(int dev_id, const char *dev_name, printk(KERN_ERR "omap_dma: Request failed %d\n", err); return err; } - dma_chan[channels[i]].next_linked_ch = -1; dma_chan[channels[i]].prev_linked_ch = -1; dma_chan[channels[i]].state = DMA_CH_NOTSTARTED; diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index 1945ddfec18dcdee81d8d0069797bf6ec7e729d4..6f33f58bca4573184aaa7b5147b02d707ab6e496 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -355,7 +355,6 @@ static int omap_mbox_init(struct omap_mbox *mbox) "failed to register mailbox interrupt:%d\n", ret); goto fail_request_irq; } - enable_mbox_irq(mbox, IRQ_RX); mq = mbox_queue_alloc(mbox, mbox_txq_fn, mbox_tx_work); if (!mq) { diff --git a/arch/arm/plat-s3c24xx/clock.c b/arch/arm/plat-s3c24xx/clock.c index d84167fb33b1fa69df54602a925ffc2f573ed008..3ac8d8d781b3837f4ec47653e2b1ce4b98d25dfe 100644 --- a/arch/arm/plat-s3c24xx/clock.c +++ b/arch/arm/plat-s3c24xx/clock.c @@ -411,7 +411,7 @@ static int s3c24xx_clkout_setparent(struct clk *clk, struct clk *parent) clk->parent = parent; - if (clk == &s3c24xx_dclk0) + if (clk == &s3c24xx_clkout0) mask = S3C2410_MISCCR_CLK0_MASK; else { source <<= 4; @@ -437,7 +437,7 @@ struct clk s3c24xx_dclk0 = { struct clk s3c24xx_dclk1 = { .name = "dclk1", .id = -1, - .ctrlbit = S3C2410_DCLKCON_DCLK0EN, + .ctrlbit = S3C2410_DCLKCON_DCLK1EN, .enable = s3c24xx_dclk_enable, .set_parent = s3c24xx_dclk_setparent, .set_rate = s3c24xx_set_dclk_rate, diff --git a/arch/avr32/kernel/init_task.c b/arch/avr32/kernel/init_task.c index effcacf9d1a2b5bf0a46d33939c6a9702ca42207..44058469c6ec905c2cad58fca1e315f0b395474c 100644 --- a/arch/avr32/kernel/init_task.c +++ b/arch/avr32/kernel/init_task.c @@ -14,7 +14,6 @@ #include static struct fs_struct init_fs = INIT_FS; -static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS(init_signals); static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); struct mm_struct init_mm = INIT_MM(init_mm); diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index 795d0ac67c2192a93c6fd0404bb3e9fed92c45d7..b87634e75f20f6b4ac9cecb8068e430c27ba8885 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -479,16 +479,6 @@ comment "Memory Setup" comment "Misc" -config ENET_FLASH_PIN - int "PF port/pin used for flash and ethernet sharing" - depends on (BFIN533_STAMP) - default 0 - help - PF port/pin used for flash and ethernet sharing to allow other PF - pins to be used on other platforms without having to touch common - code. - For example: PF0 --> 0,PF1 --> 1,PF2 --> 2, etc. - choice prompt "Blackfin Exception Scratch Register" default BFIN_SCRATCH_REG_RETN @@ -695,6 +685,8 @@ choice prompt "Uncached SDRAM region" default DMA_UNCACHED_1M depends on BFIN_DMA_5XX +config DMA_UNCACHED_4M + bool "Enable 4M DMA region" config DMA_UNCACHED_2M bool "Enable 2M DMA region" config DMA_UNCACHED_1M @@ -832,6 +824,7 @@ config BANK_0 config BANK_1 hex "Bank 1" default 0x7BB0 + default 0x5558 if BF54x config BANK_2 hex "Bank 2" @@ -963,21 +956,22 @@ endchoice endmenu -if (BF537 || BF533 || BF54x) - menu "CPU Frequency scaling" source "drivers/cpufreq/Kconfig" -config CPU_FREQ - bool +config CPU_VOLTAGE + bool "CPU Voltage scaling" + depends on EXPERIMENTAL + depends on CPU_FREQ default n help - If you want to enable this option, you should select the - DPMC driver from Character Devices. -endmenu + Say Y here if you want CPU voltage scaling according to the CPU frequency. + This option violates the PLL BYPASS recommendation in the Blackfin Processor + manuals. There is a theoretical risk that during VDDINT transitions + the PLL may unlock. -endif +endmenu source "net/Kconfig" diff --git a/arch/blackfin/configs/BF527-EZKIT_defconfig b/arch/blackfin/configs/BF527-EZKIT_defconfig index 64876dfc2e550b57eb9a8b015295f49bc3a560d8..5e6fb9d8e50fb4d9bf4378821f8fb29ab763647c 100644 --- a/arch/blackfin/configs/BF527-EZKIT_defconfig +++ b/arch/blackfin/configs/BF527-EZKIT_defconfig @@ -1,6 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.22.16 +# Linux kernel version: 2.6.24.7 +# Fri May 16 10:02:29 2008 # # CONFIG_MMU is not set # CONFIG_FPU is not set @@ -13,35 +14,34 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_GENERIC_TIME=y CONFIG_GENERIC_GPIO=y CONFIG_FORCE_MAX_ZONEORDER=14 CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # -# Code maturity level options +# General setup # CONFIG_EXPERIMENTAL=y CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_FAIR_USER_SCHED=y +# CONFIG_FAIR_CGROUP_SCHED is not set CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set CONFIG_BLK_DEV_INITRD=y @@ -64,32 +64,24 @@ CONFIG_EPOLL=y CONFIG_SIGNALFD=y CONFIG_EVENTFD=y CONFIG_VM_EVENT_COUNTERS=y -CONFIG_BIG_ORDER_ALLOC_NOFAIL_MAGIC=3 -# CONFIG_NP2 is not set CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set +CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y CONFIG_TINY_SHMEM=y CONFIG_BASE_SMALL=0 - -# -# Loadable module support -# CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_KMOD=y - -# -# Block layer -# CONFIG_BLOCK=y # CONFIG_LBD is not set # CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set # # IO Schedulers @@ -141,7 +133,6 @@ CONFIG_BF_REV_0_0=y # CONFIG_BF_REV_ANY is not set # CONFIG_BF_REV_NONE is not set CONFIG_BF52x=y -CONFIG_BFIN_SINGLE_CORE=y CONFIG_MEM_MT48LC32M16A2TG_75=y CONFIG_BFIN527_EZKIT=y @@ -227,12 +218,14 @@ CONFIG_IRQ_USB_DMA=11 # Board customizations # # CONFIG_CMDLINE_BOOL is not set +CONFIG_BOOT_LOAD=0x1000 # # Clock/PLL Setup # CONFIG_CLKIN_HZ=25000000 # CONFIG_BFIN_KERNEL_CLOCK is not set +CONFIG_MAX_MEM_SIZE=512 CONFIG_MAX_VCO_HZ=600000000 CONFIG_MIN_VCO_HZ=50000000 CONFIG_MAX_SCLK_HZ=133333333 @@ -246,13 +239,17 @@ CONFIG_HZ_250=y # CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +# CONFIG_CYCLES_CLOCKSOURCE is not set +# CONFIG_TICK_ONESHOT is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y # -# Memory Setup +# Misc # -CONFIG_MAX_MEM_SIZE=512 -CONFIG_MEM_ADD_WIDTH=10 -CONFIG_BOOT_LOAD=0x1000 CONFIG_BFIN_SCRATCH_REG_RETN=y # CONFIG_BFIN_SCRATCH_REG_RETE is not set # CONFIG_BFIN_SCRATCH_REG_CYCLES is not set @@ -288,12 +285,14 @@ CONFIG_FLATMEM_MANUAL=y CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 -CONFIG_LARGE_ALLOCS=y +CONFIG_VIRT_TO_BUS=y # CONFIG_BFIN_GPTIMERS is not set CONFIG_BFIN_DMA_5XX=y +# CONFIG_DMA_UNCACHED_4M is not set # CONFIG_DMA_UNCACHED_2M is not set CONFIG_DMA_UNCACHED_1M=y # CONFIG_DMA_UNCACHED_NONE is not set @@ -338,10 +337,6 @@ CONFIG_BANK_3=0xFFC0 # # CONFIG_PCI is not set # CONFIG_ARCH_SUPPORTS_MSI is not set - -# -# PCCARD (PCMCIA/CardBus) support -# # CONFIG_PCCARD is not set # @@ -357,8 +352,14 @@ CONFIG_BINFMT_ZFLAT=y # Power management options # # CONFIG_PM is not set +CONFIG_SUSPEND_UP_POSSIBLE=y # CONFIG_PM_WAKEUP_BY_GPIO is not set +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ is not set + # # Networking # @@ -395,6 +396,7 @@ CONFIG_SYN_COOKIES=y CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y CONFIG_INET_XFRM_MODE_BEET=y +# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set @@ -421,10 +423,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_LAPB is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# # CONFIG_NET_SCHED is not set # @@ -444,6 +442,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set # CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set # # Device Drivers @@ -452,14 +451,11 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # Generic Driver Options # +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set # CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# # CONFIG_CONNECTOR is not set CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set @@ -479,6 +475,7 @@ CONFIG_MTD_BLOCK=y # CONFIG_INFTL is not set # CONFIG_RFD_FTL is not set # CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set # # RAM/ROM/Flash chip drivers @@ -542,39 +539,27 @@ CONFIG_MTD_NAND_IDS=m # CONFIG_MTD_NAND_DISKONCHIP is not set # CONFIG_MTD_NAND_NANDSIM is not set # CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ALAUDA is not set # CONFIG_MTD_ONENAND is not set # # UBI - Unsorted block images # # CONFIG_MTD_UBI is not set - -# -# Parallel port support -# # CONFIG_PARPORT is not set - -# -# Plug and Play support -# -# CONFIG_PNPACPI is not set - -# -# Block devices -# +CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set - -# -# Misc devices -# +CONFIG_MISC_DEVICES=y +# CONFIG_EEPROM_93CX6 is not set # CONFIG_IDE is not set # @@ -582,22 +567,18 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set # CONFIG_SCSI_NETLINK is not set # CONFIG_ATA is not set - -# -# Multi-device support (RAID and LVM) -# # CONFIG_MD is not set - -# -# Network device support -# CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set # CONFIG_DUMMY is not set # CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set +# CONFIG_VETH is not set CONFIG_PHYLIB=y # @@ -611,21 +592,24 @@ CONFIG_PHYLIB=y # CONFIG_VITESSE_PHY is not set # CONFIG_SMSC_PHY is not set # CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set # CONFIG_FIXED_PHY is not set - -# -# Ethernet (10 or 100Mbit) -# +# CONFIG_MDIO_BITBANG is not set CONFIG_NET_ETHERNET=y CONFIG_MII=y -# CONFIG_SMC91X is not set CONFIG_BFIN_MAC=y CONFIG_BFIN_MAC_USE_L1=y CONFIG_BFIN_TX_DESC_NUM=10 CONFIG_BFIN_RX_DESC_NUM=20 CONFIG_BFIN_MAC_RMII=y +# CONFIG_SMC91X is not set # CONFIG_SMSC911X is not set # CONFIG_DM9000 is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_B44 is not set CONFIG_NETDEV_1000=y # CONFIG_AX88180 is not set CONFIG_NETDEV_10000=y @@ -635,6 +619,15 @@ CONFIG_NETDEV_10000=y # # CONFIG_WLAN_PRE80211 is not set # CONFIG_WLAN_80211 is not set + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set # CONFIG_WAN is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -642,15 +635,7 @@ CONFIG_NETDEV_10000=y # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# # CONFIG_ISDN is not set - -# -# Telephony Support -# # CONFIG_PHONE is not set # @@ -665,7 +650,6 @@ CONFIG_INPUT=y # # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set # CONFIG_INPUT_EVDEV is not set # CONFIG_INPUT_EVBUG is not set @@ -697,7 +681,6 @@ CONFIG_INPUT_MISC=y # # CONFIG_AD9960 is not set # CONFIG_SPI_ADC_BF533 is not set -# CONFIG_BF5xx_PFLAGS is not set # CONFIG_BF5xx_PPIFCD is not set # CONFIG_BFIN_SIMPLE_TIMER is not set # CONFIG_BF5xx_PPI is not set @@ -706,7 +689,7 @@ CONFIG_BFIN_OTP=y # CONFIG_BFIN_SPORT is not set # CONFIG_BFIN_TIMER_LATENCY is not set # CONFIG_TWI_LCD is not set -# CONFIG_AD5304 is not set +# CONFIG_SIMPLE_GPIO is not set # CONFIG_VT is not set # CONFIG_SERIAL_NONSTANDARD is not set @@ -735,27 +718,11 @@ CONFIG_UNIX98_PTYS=y # CAN, the car bus and industrial fieldbus # # CONFIG_CAN4LINUX is not set - -# -# IPMI -# # CONFIG_IPMI_HANDLER is not set -CONFIG_WATCHDOG=y -# CONFIG_WATCHDOG_NOWAYOUT is not set - -# -# Watchdog Device Drivers -# -# CONFIG_SOFT_WATCHDOG is not set -CONFIG_BFIN_WDT=y CONFIG_HW_RANDOM=y # CONFIG_GEN_RTC is not set # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# # CONFIG_TCG_TPM is not set CONFIG_I2C=y CONFIG_I2C_BOARDINFO=y @@ -777,21 +744,24 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=50 # CONFIG_I2C_OCORES is not set # CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_TAOS_EVM is not set # CONFIG_I2C_STUB is not set +# CONFIG_I2C_TINY_USB is not set # # Miscellaneous I2C Chip support # # CONFIG_SENSORS_DS1337 is not set # CONFIG_SENSORS_DS1374 is not set +# CONFIG_DS1682 is not set # CONFIG_SENSORS_AD5252 is not set # CONFIG_SENSORS_EEPROM is not set # CONFIG_SENSORS_PCF8574 is not set # CONFIG_SENSORS_PCF8575 is not set -# CONFIG_SENSORS_PCA9543 is not set # CONFIG_SENSORS_PCA9539 is not set # CONFIG_SENSORS_PCF8591 is not set # CONFIG_SENSORS_MAX6875 is not set +# CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set @@ -814,14 +784,11 @@ CONFIG_SPI_BFIN=y # # CONFIG_SPI_AT25 is not set # CONFIG_SPI_SPIDEV is not set - -# -# Dallas's 1-wire bus -# +# CONFIG_SPI_TLE62X0 is not set # CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set CONFIG_HWMON=y # CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_AD7418 is not set # CONFIG_SENSORS_ADM1021 is not set # CONFIG_SENSORS_ADM1025 is not set @@ -829,12 +796,12 @@ CONFIG_HWMON=y # CONFIG_SENSORS_ADM1029 is not set # CONFIG_SENSORS_ADM1031 is not set # CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ADT7470 is not set # CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS1621 is not set # CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_FSCHER is not set -# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_F71882FG is not set +# CONFIG_SENSORS_F75375S is not set # CONFIG_SENSORS_GL518SM is not set # CONFIG_SENSORS_GL520SM is not set # CONFIG_SENSORS_IT87 is not set @@ -849,13 +816,16 @@ CONFIG_HWMON=y # CONFIG_SENSORS_LM87 is not set # CONFIG_SENSORS_LM90 is not set # CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_LM93 is not set # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_MAX6650 is not set # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_DME1737 is not set # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_SMSC47M192 is not set # CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_THMC50 is not set # CONFIG_SENSORS_VT1211 is not set # CONFIG_SENSORS_W83781D is not set # CONFIG_SENSORS_W83791D is not set @@ -865,6 +835,25 @@ CONFIG_HWMON=y # CONFIG_SENSORS_W83627HF is not set # CONFIG_SENSORS_W83627EHF is not set # CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_BFIN_WDT=y + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set # # Multifunction device drivers @@ -881,72 +870,133 @@ CONFIG_HWMON=y # # Graphics support # +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set # CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Display device support # # CONFIG_DISPLAY_SUPPORT is not set -# CONFIG_VGASTATE is not set -# CONFIG_FB is not set # # Sound # # CONFIG_SOUND is not set - -# -# HID Devices -# +CONFIG_HID_SUPPORT=y CONFIG_HID=y # CONFIG_HID_DEBUG is not set +# CONFIG_HIDRAW is not set # -# USB support +# USB Input Devices # +CONFIG_USB_HID=y +# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_HID_FF is not set +# CONFIG_USB_HIDDEV is not set +CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y # CONFIG_USB_ARCH_HAS_OHCI is not set # CONFIG_USB_ARCH_HAS_EHCI is not set -# CONFIG_USB is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_WHITELIST is not set +CONFIG_USB_OTG_BLACKLIST_HUB=y + +# +# USB Host Controller Drivers +# +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +CONFIG_USB_MUSB_HDRC=y +CONFIG_USB_MUSB_SOC=y # -# Enable Host or Gadget support to see Inventra options +# Blackfin high speed USB support # +CONFIG_USB_MUSB_HOST=y +# CONFIG_USB_MUSB_PERIPHERAL is not set +# CONFIG_USB_MUSB_OTG is not set +CONFIG_USB_MUSB_HDRC_HCD=y +CONFIG_MUSB_PIO_ONLY=y +CONFIG_USB_MUSB_LOGLEVEL=0 + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set # # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' # # -# USB Gadget Support +# may also be needed; see USB_STORAGE Help for more information # -# CONFIG_USB_GADGET is not set -# CONFIG_MMC is not set +# CONFIG_USB_LIBUSUAL is not set # -# LED devices +# USB Imaging devices # -# CONFIG_NEW_LEDS is not set +# CONFIG_USB_MDC800 is not set +CONFIG_USB_MON=y # -# LED drivers +# USB port drivers # # -# LED Triggers +# USB Serial Converter support # +# CONFIG_USB_SERIAL is not set # -# InfiniBand support +# USB Miscellaneous drivers # +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set # -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# USB DSL modem support # # -# Real Time Clock +# USB Gadget Support # +# CONFIG_USB_GADGET is not set +# CONFIG_MMC is not set +# CONFIG_NEW_LEDS is not set CONFIG_RTC_LIB=y CONFIG_RTC_CLASS=y CONFIG_RTC_HCTOSYS=y @@ -966,6 +1016,7 @@ CONFIG_RTC_INTF_DEV=y # I2C RTC drivers # # CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set # CONFIG_RTC_DRV_DS1672 is not set # CONFIG_RTC_DRV_MAX6900 is not set # CONFIG_RTC_DRV_RS5C372 is not set @@ -973,6 +1024,7 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_X1205 is not set # CONFIG_RTC_DRV_PCF8563 is not set # CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set # # SPI RTC drivers @@ -984,8 +1036,10 @@ CONFIG_RTC_INTF_DEV=y # Platform RTC drivers # # CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set # CONFIG_RTC_DRV_DS1742 is not set # CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T59 is not set # CONFIG_RTC_DRV_V3020 is not set # @@ -994,22 +1048,9 @@ CONFIG_RTC_INTF_DEV=y CONFIG_RTC_DRV_BFIN=y # -# DMA Engine support -# -# CONFIG_DMA_ENGINE is not set - -# -# DMA Clients +# Userspace I/O # - -# -# DMA Devices -# - -# -# PBX support -# -# CONFIG_PBX is not set +# CONFIG_UIO is not set # # File systems @@ -1054,7 +1095,6 @@ CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y # CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set # @@ -1080,10 +1120,12 @@ CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y CONFIG_JFFS2_FS=m CONFIG_JFFS2_FS_DEBUG=0 CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set # CONFIG_JFFS2_SUMMARY is not set # CONFIG_JFFS2_FS_XATTR is not set # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set # CONFIG_CRAMFS is not set @@ -1092,10 +1134,7 @@ CONFIG_JFFS2_RTIME=y # CONFIG_QNX4FS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set - -# -# Network File Systems -# +CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=m CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set @@ -1115,17 +1154,12 @@ CONFIG_SMB_FS=m # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set # # Partition Types # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# CONFIG_NLS=m CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_CODEPAGE_437 is not set @@ -1166,21 +1200,16 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_KOI8_R is not set # CONFIG_NLS_KOI8_U is not set # CONFIG_NLS_UTF8 is not set - -# -# Distributed Lock Manager -# # CONFIG_DLM is not set - -# -# Profiling support -# +CONFIG_INSTRUMENTATION=y # CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set # # Kernel hacking # # CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set @@ -1188,6 +1217,7 @@ CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set # CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_SAMPLES is not set CONFIG_DEBUG_MMRS=y CONFIG_DEBUG_HUNT_FOR_ZERO=y CONFIG_DEBUG_BFIN_HWTRACE_ON=y @@ -1207,11 +1237,8 @@ CONFIG_ACCESS_CHECK=y # CONFIG_KEYS is not set CONFIG_SECURITY=y # CONFIG_SECURITY_NETWORK is not set -CONFIG_SECURITY_CAPABILITIES=m - -# -# Cryptographic options -# +# CONFIG_SECURITY_CAPABILITIES is not set +# CONFIG_SECURITY_ROOTPLUG is not set # CONFIG_CRYPTO is not set # @@ -1222,6 +1249,7 @@ CONFIG_CRC_CCITT=m # CONFIG_CRC16 is not set # CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y +# CONFIG_CRC7 is not set # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=m diff --git a/arch/blackfin/configs/BF548-EZKIT_defconfig b/arch/blackfin/configs/BF548-EZKIT_defconfig index 5bfdfb287d138537b7125116ae4988436926bf21..1ff2ff4b49aa14aa6fc536eb00f1d8836385b10b 100644 --- a/arch/blackfin/configs/BF548-EZKIT_defconfig +++ b/arch/blackfin/configs/BF548-EZKIT_defconfig @@ -1,6 +1,6 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.22.16 +# Linux kernel version: 2.6.24.7 # # CONFIG_MMU is not set # CONFIG_FPU is not set @@ -13,35 +13,34 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_GENERIC_TIME=y CONFIG_GENERIC_GPIO=y CONFIG_FORCE_MAX_ZONEORDER=14 CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # -# Code maturity level options +# General setup # CONFIG_EXPERIMENTAL=y CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_FAIR_USER_SCHED=y +# CONFIG_FAIR_CGROUP_SCHED is not set CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set CONFIG_BLK_DEV_INITRD=y @@ -64,32 +63,24 @@ CONFIG_EPOLL=y CONFIG_SIGNALFD=y CONFIG_EVENTFD=y CONFIG_VM_EVENT_COUNTERS=y -CONFIG_BIG_ORDER_ALLOC_NOFAIL_MAGIC=3 -# CONFIG_NP2 is not set CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set +CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y CONFIG_TINY_SHMEM=y CONFIG_BASE_SMALL=0 - -# -# Loadable module support -# CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_KMOD=y - -# -# Block layer -# CONFIG_BLOCK=y # CONFIG_LBD is not set # CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set # # IO Schedulers @@ -141,7 +132,6 @@ CONFIG_BF_REV_0_0=y # CONFIG_BF_REV_ANY is not set # CONFIG_BF_REV_NONE is not set CONFIG_BF54x=y -CONFIG_BFIN_SINGLE_CORE=y CONFIG_IRQ_PLL_WAKEUP=7 CONFIG_IRQ_RTC=8 CONFIG_IRQ_SPORT0_RX=9 @@ -169,6 +159,7 @@ CONFIG_IRQ_TIMER8=11 CONFIG_IRQ_TIMER9=11 CONFIG_IRQ_TIMER10=11 CONFIG_BFIN548_EZKIT=y +# CONFIG_BFIN548_BLUETECHNIX_CM is not set # # BF548 Specific Configuration @@ -262,12 +253,14 @@ CONFIG_PINT3_ASSIGN=0x02020303 # Board customizations # # CONFIG_CMDLINE_BOOL is not set +CONFIG_BOOT_LOAD=0x1000 # # Clock/PLL Setup # CONFIG_CLKIN_HZ=25000000 # CONFIG_BFIN_KERNEL_CLOCK is not set +CONFIG_MAX_MEM_SIZE=512 CONFIG_MAX_VCO_HZ=600000000 CONFIG_MIN_VCO_HZ=50000000 CONFIG_MAX_SCLK_HZ=133333333 @@ -281,14 +274,17 @@ CONFIG_HZ_250=y # CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +# CONFIG_CYCLES_CLOCKSOURCE is not set +# CONFIG_TICK_ONESHOT is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y # -# Memory Setup +# Misc # -CONFIG_MAX_MEM_SIZE=512 -# CONFIG_MEM_MT46V32M16_6T is not set -CONFIG_MEM_MT46V32M16_5B=y -CONFIG_BOOT_LOAD=0x1000 CONFIG_BFIN_SCRATCH_REG_RETN=y # CONFIG_BFIN_SCRATCH_REG_RETE is not set # CONFIG_BFIN_SCRATCH_REG_CYCLES is not set @@ -324,12 +320,14 @@ CONFIG_FLATMEM_MANUAL=y CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 -CONFIG_LARGE_ALLOCS=y +CONFIG_VIRT_TO_BUS=y # CONFIG_BFIN_GPTIMERS is not set CONFIG_BFIN_DMA_5XX=y +# CONFIG_DMA_UNCACHED_4M is not set CONFIG_DMA_UNCACHED_2M=y # CONFIG_DMA_UNCACHED_1M is not set # CONFIG_DMA_UNCACHED_NONE is not set @@ -377,10 +375,6 @@ CONFIG_EBIU_FCTLVAL=0x6 # # CONFIG_PCI is not set # CONFIG_ARCH_SUPPORTS_MSI is not set - -# -# PCCARD (PCMCIA/CardBus) support -# # CONFIG_PCCARD is not set # @@ -396,6 +390,7 @@ CONFIG_BINFMT_ZFLAT=y # Power management options # # CONFIG_PM is not set +CONFIG_SUSPEND_UP_POSSIBLE=y # CONFIG_PM_WAKEUP_BY_GPIO is not set # @@ -439,6 +434,7 @@ CONFIG_SYN_COOKIES=y CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y CONFIG_INET_XFRM_MODE_BEET=y +# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set @@ -465,10 +461,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_LAPB is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# # CONFIG_NET_SCHED is not set # @@ -488,6 +480,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set # CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set # # Device Drivers @@ -496,14 +489,11 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # Generic Driver Options # +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set # CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# # CONFIG_CONNECTOR is not set CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set @@ -523,6 +513,7 @@ CONFIG_MTD_BLOCK=y # CONFIG_INFTL is not set # CONFIG_RFD_FTL is not set # CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set # # RAM/ROM/Flash chip drivers @@ -587,39 +578,27 @@ CONFIG_MTD_NAND_BF5XX_HWECC=y # CONFIG_MTD_NAND_DISKONCHIP is not set # CONFIG_MTD_NAND_NANDSIM is not set # CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ALAUDA is not set # CONFIG_MTD_ONENAND is not set # # UBI - Unsorted block images # # CONFIG_MTD_UBI is not set - -# -# Parallel port support -# # CONFIG_PARPORT is not set - -# -# Plug and Play support -# -# CONFIG_PNPACPI is not set - -# -# Block devices -# +CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set - -# -# Misc devices -# +CONFIG_MISC_DEVICES=y +# CONFIG_EEPROM_93CX6 is not set # CONFIG_IDE is not set # @@ -627,6 +606,7 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y +CONFIG_SCSI_DMA=y # CONFIG_SCSI_TGT is not set # CONFIG_SCSI_NETLINK is not set CONFIG_SCSI_PROC_FS=y @@ -657,43 +637,35 @@ CONFIG_SCSI_WAIT_SCAN=m # CONFIG_SCSI_SPI_ATTRS is not set # CONFIG_SCSI_FC_ATTRS is not set # CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_SAS_ATTRS is not set # CONFIG_SCSI_SAS_LIBSAS is not set - -# -# SCSI low-level drivers -# +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y # CONFIG_ISCSI_TCP is not set # CONFIG_SCSI_DEBUG is not set CONFIG_ATA=y # CONFIG_ATA_NONSTANDARD is not set # CONFIG_PATA_PLATFORM is not set CONFIG_PATA_BF54X=y -CONFIG_PATA_BF54X_DMA=y - -# -# Multi-device support (RAID and LVM) -# # CONFIG_MD is not set - -# -# Network device support -# CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set # CONFIG_DUMMY is not set # CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set +# CONFIG_VETH is not set # CONFIG_PHYLIB is not set - -# -# Ethernet (10 or 100Mbit) -# CONFIG_NET_ETHERNET=y CONFIG_MII=y # CONFIG_SMC91X is not set CONFIG_SMSC911X=y # CONFIG_DM9000 is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_B44 is not set CONFIG_NETDEV_1000=y # CONFIG_AX88180 is not set CONFIG_NETDEV_10000=y @@ -703,6 +675,15 @@ CONFIG_NETDEV_10000=y # # CONFIG_WLAN_PRE80211 is not set # CONFIG_WLAN_80211 is not set + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set # CONFIG_WAN is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -710,15 +691,7 @@ CONFIG_NETDEV_10000=y # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# # CONFIG_ISDN is not set - -# -# Telephony Support -# # CONFIG_PHONE is not set # @@ -733,9 +706,6 @@ CONFIG_INPUT=y # # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set -CONFIG_INPUT_TSDEV=m -CONFIG_INPUT_TSDEV_SCREEN_X=240 -CONFIG_INPUT_TSDEV_SCREEN_Y=320 CONFIG_INPUT_EVDEV=m CONFIG_INPUT_EVBUG=m @@ -758,6 +728,7 @@ CONFIG_KEYBOARD_BFIN=y CONFIG_INPUT_TOUCHSCREEN=y # CONFIG_TOUCHSCREEN_ADS7846 is not set CONFIG_TOUCHSCREEN_AD7877=m +# CONFIG_TOUCHSCREEN_FUJITSU is not set # CONFIG_TOUCHSCREEN_GUNZE is not set # CONFIG_TOUCHSCREEN_ELO is not set # CONFIG_TOUCHSCREEN_MTOUCH is not set @@ -787,7 +758,6 @@ CONFIG_INPUT_MISC=y # # CONFIG_AD9960 is not set # CONFIG_SPI_ADC_BF533 is not set -# CONFIG_BF5xx_PFLAGS is not set # CONFIG_BF5xx_PPIFCD is not set # CONFIG_BFIN_SIMPLE_TIMER is not set # CONFIG_BF5xx_PPI is not set @@ -796,7 +766,7 @@ CONFIG_BFIN_OTP=y # CONFIG_BFIN_SPORT is not set # CONFIG_BFIN_TIMER_LATENCY is not set # CONFIG_TWI_LCD is not set -# CONFIG_AD5304 is not set +# CONFIG_SIMPLE_GPIO is not set CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y @@ -830,27 +800,11 @@ CONFIG_UNIX98_PTYS=y # CAN, the car bus and industrial fieldbus # # CONFIG_CAN4LINUX is not set - -# -# IPMI -# # CONFIG_IPMI_HANDLER is not set -CONFIG_WATCHDOG=y -# CONFIG_WATCHDOG_NOWAYOUT is not set - -# -# Watchdog Device Drivers -# -# CONFIG_SOFT_WATCHDOG is not set -CONFIG_BFIN_WDT=y CONFIG_HW_RANDOM=y # CONFIG_GEN_RTC is not set # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# # CONFIG_TCG_TPM is not set CONFIG_I2C=y CONFIG_I2C_BOARDINFO=y @@ -872,21 +826,24 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=50 # CONFIG_I2C_OCORES is not set # CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_TAOS_EVM is not set # CONFIG_I2C_STUB is not set +# CONFIG_I2C_TINY_USB is not set # # Miscellaneous I2C Chip support # # CONFIG_SENSORS_DS1337 is not set # CONFIG_SENSORS_DS1374 is not set +# CONFIG_DS1682 is not set # CONFIG_SENSORS_AD5252 is not set # CONFIG_SENSORS_EEPROM is not set # CONFIG_SENSORS_PCF8574 is not set # CONFIG_SENSORS_PCF8575 is not set -# CONFIG_SENSORS_PCA9543 is not set # CONFIG_SENSORS_PCA9539 is not set # CONFIG_SENSORS_PCF8591 is not set # CONFIG_SENSORS_MAX6875 is not set +# CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set @@ -909,14 +866,11 @@ CONFIG_SPI_BFIN=y # # CONFIG_SPI_AT25 is not set # CONFIG_SPI_SPIDEV is not set - -# -# Dallas's 1-wire bus -# +# CONFIG_SPI_TLE62X0 is not set # CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set CONFIG_HWMON=y # CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_AD7418 is not set # CONFIG_SENSORS_ADM1021 is not set # CONFIG_SENSORS_ADM1025 is not set @@ -924,12 +878,12 @@ CONFIG_HWMON=y # CONFIG_SENSORS_ADM1029 is not set # CONFIG_SENSORS_ADM1031 is not set # CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ADT7470 is not set # CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS1621 is not set # CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_FSCHER is not set -# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_F71882FG is not set +# CONFIG_SENSORS_F75375S is not set # CONFIG_SENSORS_GL518SM is not set # CONFIG_SENSORS_GL520SM is not set # CONFIG_SENSORS_IT87 is not set @@ -944,13 +898,16 @@ CONFIG_HWMON=y # CONFIG_SENSORS_LM87 is not set # CONFIG_SENSORS_LM90 is not set # CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_LM93 is not set # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_MAX6650 is not set # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_DME1737 is not set # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_SMSC47M192 is not set # CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_THMC50 is not set # CONFIG_SENSORS_VT1211 is not set # CONFIG_SENSORS_W83781D is not set # CONFIG_SENSORS_W83791D is not set @@ -960,6 +917,25 @@ CONFIG_HWMON=y # CONFIG_SENSORS_W83627HF is not set # CONFIG_SENSORS_W83627EHF is not set # CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_BFIN_WDT=y + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set # # Multifunction device drivers @@ -972,23 +948,20 @@ CONFIG_HWMON=y # CONFIG_VIDEO_DEV is not set # CONFIG_DVB_CORE is not set CONFIG_DAB=y +# CONFIG_USB_DABUSB is not set # # Graphics support # -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Display device support -# -# CONFIG_DISPLAY_SUPPORT is not set # CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set CONFIG_FB=y CONFIG_FIRMWARE_EDID=y # CONFIG_FB_DDC is not set CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set # CONFIG_FB_SYS_FILLRECT is not set # CONFIG_FB_SYS_COPYAREA is not set # CONFIG_FB_SYS_IMAGEBLIT is not set @@ -1003,18 +976,24 @@ CONFIG_FB_DEFERRED_IO=y # # Frame buffer hardware drivers # -# CONFIG_FB_BFIN_7171 is not set -# CONFIG_FB_BFIN_7393 is not set CONFIG_FB_BF54X_LQ043=y # CONFIG_FB_BFIN_T350MCQB is not set +# CONFIG_FB_BFIN_7393 is not set # CONFIG_FB_S1D13XXX is not set # CONFIG_FB_VIRTUAL is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set # # Console display driver support # CONFIG_DUMMY_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set CONFIG_FONTS=y # CONFIG_FONT_8x8 is not set @@ -1064,11 +1043,22 @@ CONFIG_SND_VERBOSE_PROCFS=y # CONFIG_SND_SERIAL_U16550 is not set # CONFIG_SND_MPU401 is not set +# +# SPI devices +# + # # ALSA Blackfin devices # # CONFIG_SND_BLACKFIN_AD1836 is not set # CONFIG_SND_BFIN_AD73311 is not set +# CONFIG_SND_BFIN_AD73322 is not set + +# +# USB devices +# +# CONFIG_SND_USB_AUDIO is not set +# CONFIG_SND_USB_CAIAQ is not set # # System on Chip audio support @@ -1084,6 +1074,10 @@ CONFIG_SND_BF5XX_SOC_BF548_EZKIT=y CONFIG_SND_BF5XX_SPORT_NUM=0 CONFIG_SND_BF5XX_HAVE_COLD_RESET=y CONFIG_SND_BF5XX_RESET_GPIO_NUM=19 + +# +# SoC Audio support for SuperH +# CONFIG_SND_SOC_AD1980=y # @@ -1091,72 +1085,152 @@ CONFIG_SND_SOC_AD1980=y # # CONFIG_SOUND_PRIME is not set CONFIG_AC97_BUS=y - -# -# HID Devices -# -CONFIG_HID=m +CONFIG_HID_SUPPORT=y +CONFIG_HID=y # CONFIG_HID_DEBUG is not set +# CONFIG_HIDRAW is not set # -# USB support +# USB Input Devices # +CONFIG_USB_HID=y +# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_HID_FF is not set +# CONFIG_USB_HIDDEV is not set +CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y # CONFIG_USB_ARCH_HAS_OHCI is not set # CONFIG_USB_ARCH_HAS_EHCI is not set -# CONFIG_USB is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_WHITELIST is not set +CONFIG_USB_OTG_BLACKLIST_HUB=y # -# Enable Host or Gadget support to see Inventra options +# USB Host Controller Drivers # +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +CONFIG_USB_MUSB_HDRC=y +CONFIG_USB_MUSB_SOC=y + +# +# Blackfin high speed USB support +# +CONFIG_USB_MUSB_HOST=y +# CONFIG_USB_MUSB_PERIPHERAL is not set +# CONFIG_USB_MUSB_OTG is not set +CONFIG_USB_MUSB_HDRC_HCD=y +# CONFIG_MUSB_PIO_ONLY is not set +# CONFIG_USB_INVENTRA_DMA is not set +# CONFIG_USB_TI_CPPI_DMA is not set +CONFIG_USB_MUSB_LOGLEVEL=0 + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set # # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' # # -# USB Gadget Support +# may also be needed; see USB_STORAGE Help for more information # -# CONFIG_USB_GADGET is not set -CONFIG_MMC=m -# CONFIG_MMC_DEBUG is not set -# CONFIG_MMC_UNSAFE_RESUME is not set +CONFIG_USB_STORAGE=m +# 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_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_LIBUSUAL is not set # -# MMC/SD Card Drivers +# USB Imaging devices # -CONFIG_MMC_BLOCK=m +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +CONFIG_USB_MON=y # -# MMC/SD Host Controller Drivers +# USB port drivers # -CONFIG_SDH_BFIN=m -# CONFIG_SPI_MMC is not set # -# LED devices +# USB Serial Converter support # -# CONFIG_NEW_LEDS is not set +# CONFIG_USB_SERIAL is not set # -# LED drivers +# USB Miscellaneous drivers # +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set # -# LED Triggers +# USB DSL modem support # # -# InfiniBand support +# USB Gadget Support # +# CONFIG_USB_GADGET is not set +CONFIG_MMC=m +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set # -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# MMC/SD Card Drivers # +CONFIG_MMC_BLOCK=m +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set # -# Real Time Clock +# MMC/SD Host Controller Drivers # +CONFIG_SDH_BFIN=m +# CONFIG_SDH_BFIN_MISSING_CMD_PULLUP_WORKAROUND is not set +# CONFIG_MMC_SPI is not set +# CONFIG_SPI_MMC is not set +# CONFIG_NEW_LEDS is not set CONFIG_RTC_LIB=y CONFIG_RTC_CLASS=y CONFIG_RTC_HCTOSYS=y @@ -1176,6 +1250,7 @@ CONFIG_RTC_INTF_DEV=y # I2C RTC drivers # # CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set # CONFIG_RTC_DRV_DS1672 is not set # CONFIG_RTC_DRV_MAX6900 is not set # CONFIG_RTC_DRV_RS5C372 is not set @@ -1183,6 +1258,7 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_X1205 is not set # CONFIG_RTC_DRV_PCF8563 is not set # CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set # # SPI RTC drivers @@ -1194,8 +1270,10 @@ CONFIG_RTC_INTF_DEV=y # Platform RTC drivers # # CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set # CONFIG_RTC_DRV_DS1742 is not set # CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T59 is not set # CONFIG_RTC_DRV_V3020 is not set # @@ -1204,22 +1282,9 @@ CONFIG_RTC_INTF_DEV=y CONFIG_RTC_DRV_BFIN=y # -# DMA Engine support -# -# CONFIG_DMA_ENGINE is not set - -# -# DMA Clients +# Userspace I/O # - -# -# DMA Devices -# - -# -# PBX support -# -# CONFIG_PBX is not set +# CONFIG_UIO is not set # # File systems @@ -1280,7 +1345,6 @@ CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y # CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set # @@ -1306,10 +1370,12 @@ CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y CONFIG_JFFS2_FS=m CONFIG_JFFS2_FS_DEBUG=0 CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set # CONFIG_JFFS2_SUMMARY is not set # CONFIG_JFFS2_FS_XATTR is not set # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set # CONFIG_CRAMFS is not set @@ -1318,10 +1384,7 @@ CONFIG_JFFS2_RTIME=y # CONFIG_QNX4FS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set - -# -# Network File Systems -# +CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=m CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set @@ -1352,7 +1415,6 @@ CONFIG_CIFS=y # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set # # Partition Types @@ -1375,10 +1437,6 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_KARMA_PARTITION is not set # CONFIG_EFI_PARTITION is not set # CONFIG_SYSV68_PARTITION is not set - -# -# Native Language Support -# CONFIG_NLS=y CONFIG_NLS_DEFAULT="iso8859-1" CONFIG_NLS_CODEPAGE_437=m @@ -1419,21 +1477,16 @@ CONFIG_NLS_ISO8859_15=m CONFIG_NLS_KOI8_R=m CONFIG_NLS_KOI8_U=m CONFIG_NLS_UTF8=m - -# -# Distributed Lock Manager -# # CONFIG_DLM is not set - -# -# Profiling support -# +CONFIG_INSTRUMENTATION=y # CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set # # Kernel hacking # # CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set @@ -1441,6 +1494,7 @@ CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set # CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_SAMPLES is not set CONFIG_DEBUG_MMRS=y CONFIG_DEBUG_HUNT_FOR_ZERO=y CONFIG_DEBUG_BFIN_HWTRACE_ON=y @@ -1460,11 +1514,8 @@ CONFIG_ACCESS_CHECK=y # CONFIG_KEYS is not set CONFIG_SECURITY=y # CONFIG_SECURITY_NETWORK is not set -CONFIG_SECURITY_CAPABILITIES=m - -# -# Cryptographic options -# +# CONFIG_SECURITY_CAPABILITIES is not set +# CONFIG_SECURITY_ROOTPLUG is not set # CONFIG_CRYPTO is not set # @@ -1475,6 +1526,7 @@ CONFIG_CRC_CCITT=m # CONFIG_CRC16 is not set # CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y +# CONFIG_CRC7 is not set # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=m diff --git a/arch/blackfin/configs/IP0X_defconfig b/arch/blackfin/configs/IP0X_defconfig index 5f6ff04a86c31dda1ca77a13f6fd235dd7b91072..4384a670a8b8e2f97ed0cd294d41a127e8cde537 100644 --- a/arch/blackfin/configs/IP0X_defconfig +++ b/arch/blackfin/configs/IP0X_defconfig @@ -212,7 +212,7 @@ CONFIG_HZ=250 # # Memory Setup # -CONFIG_MEM_SIZE=64 +CONFIG_MAX_MEM_SIZE=64 CONFIG_MEM_ADD_WIDTH=10 # diff --git a/arch/blackfin/kernel/asm-offsets.c b/arch/blackfin/kernel/asm-offsets.c index 721f15f3cebf1915d67f2b83ab46574697517155..881afe9082c76744bd9bdb01cc0bcd564a50f973 100644 --- a/arch/blackfin/kernel/asm-offsets.c +++ b/arch/blackfin/kernel/asm-offsets.c @@ -56,9 +56,6 @@ int main(void) /* offsets into the thread struct */ DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp)); DEFINE(THREAD_USP, offsetof(struct thread_struct, usp)); - DEFINE(THREAD_SR, offsetof(struct thread_struct, seqstat)); - DEFINE(PT_SR, offsetof(struct thread_struct, seqstat)); - DEFINE(THREAD_ESP0, offsetof(struct thread_struct, esp0)); DEFINE(THREAD_PC, offsetof(struct thread_struct, pc)); DEFINE(KERNEL_STACK_SIZE, THREAD_SIZE); diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c index fd5448d6107cdf7564b53b6470731dccbd2e7ba9..d54f19085f37a13d5b7798f387bd65aa83373ce0 100644 --- a/arch/blackfin/kernel/bfin_dma_5xx.c +++ b/arch/blackfin/kernel/bfin_dma_5xx.c @@ -90,6 +90,17 @@ int request_dma(unsigned int channel, char *device_id) { pr_debug("request_dma() : BEGIN \n"); + +#if defined(CONFIG_BF561) && ANOMALY_05000182 + if (channel >= CH_IMEM_STREAM0_DEST && channel <= CH_IMEM_STREAM1_DEST) { + if (get_cclk() > 500000000) { + printk(KERN_WARNING + "Request IMDMA failed due to ANOMALY 05000182\n"); + return -EFAULT; + } + } +#endif + mutex_lock(&(dma_ch[channel].dmalock)); if ((dma_ch[channel].chan_status == DMA_CHANNEL_REQUESTED) diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c index 7e8eaf4a31bbc64ffbe17602c5b8ec1bbd8e8c45..b6d89d1644cc8515c1909865e01fdf83e9ede39f 100644 --- a/arch/blackfin/kernel/bfin_gpio.c +++ b/arch/blackfin/kernel/bfin_gpio.c @@ -1130,6 +1130,25 @@ void bfin_gpio_irq_prepare(unsigned gpio) #else +int gpio_get_value(unsigned gpio) +{ + unsigned long flags; + int ret; + + if (unlikely(get_gpio_edge(gpio))) { + local_irq_save(flags); + set_gpio_edge(gpio, 0); + ret = get_gpio_data(gpio); + set_gpio_edge(gpio, 1); + local_irq_restore(flags); + + return ret; + } else + return get_gpio_data(gpio); +} +EXPORT_SYMBOL(gpio_get_value); + + int gpio_direction_input(unsigned gpio) { unsigned long flags; diff --git a/arch/blackfin/kernel/bfin_ksyms.c b/arch/blackfin/kernel/bfin_ksyms.c index 053edff6c0d84aa4f2b03c24606bf393d261bd01..4367330909b27ec4832a4f4d3b54bd6fed825e50 100644 --- a/arch/blackfin/kernel/bfin_ksyms.c +++ b/arch/blackfin/kernel/bfin_ksyms.c @@ -90,7 +90,9 @@ EXPORT_SYMBOL(__umodsi3); EXPORT_SYMBOL(outsb); EXPORT_SYMBOL(insb); EXPORT_SYMBOL(outsw); +EXPORT_SYMBOL(outsw_8); EXPORT_SYMBOL(insw); +EXPORT_SYMBOL(insw_8); EXPORT_SYMBOL(outsl); EXPORT_SYMBOL(insl); EXPORT_SYMBOL(insl_16); diff --git a/arch/blackfin/kernel/fixed_code.S b/arch/blackfin/kernel/fixed_code.S index 5ed47228a39075a284e99801d7c79165f6b7367f..4b03ba025488edd4ec55d0f2cc9c92d3d9c2313b 100644 --- a/arch/blackfin/kernel/fixed_code.S +++ b/arch/blackfin/kernel/fixed_code.S @@ -1,6 +1,6 @@ /* * This file contains sequences of code that will be copied to a - * fixed location, defined in . The interrupt + * fixed location, defined in . The interrupt * handlers ensure that these sequences appear to be atomic when * executed from userspace. * These are aligned to 16 bytes, so that we have some space to replace diff --git a/arch/blackfin/kernel/init_task.c b/arch/blackfin/kernel/init_task.c index c640154030e270d358c5f748f11222038cbbf286..6bdba7b21109e0872c8589d123439335a1073a50 100644 --- a/arch/blackfin/kernel/init_task.c +++ b/arch/blackfin/kernel/init_task.c @@ -34,7 +34,6 @@ #include static struct fs_struct init_fs = INIT_FS; -static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS(init_signals); static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); diff --git a/arch/blackfin/kernel/module.c b/arch/blackfin/kernel/module.c index 8b9fe29d03f4f4a02c91f3a2585b703bfa7b3bc9..14a42848f37f70d453807bf3cbe7b1a3346e98e1 100644 --- a/arch/blackfin/kernel/module.c +++ b/arch/blackfin/kernel/module.c @@ -160,6 +160,13 @@ int module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs, char *secstrings, struct module *mod) { + /* + * XXX: sechdrs are vmalloced in kernel/module.c + * and would be vfreed just after module is loaded, + * so we hack to keep the only information we needed + * in mod->arch to correctly free L1 I/D sram later. + * NOTE: this breaks the semantic of mod->arch structure. + */ Elf_Shdr *s, *sechdrs_end = sechdrs + hdr->e_shnum; void *dest = NULL; @@ -167,8 +174,8 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs, if ((strcmp(".l1.text", secstrings + s->sh_name) == 0) || ((strcmp(".text", secstrings + s->sh_name) == 0) && (hdr->e_flags & FLG_CODE_IN_L1) && (s->sh_size > 0))) { - mod->arch.text_l1 = s; dest = l1_inst_sram_alloc(s->sh_size); + mod->arch.text_l1 = dest; if (dest == NULL) { printk(KERN_ERR "module %s: L1 instruction memory allocation failed\n", @@ -182,8 +189,8 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs, if ((strcmp(".l1.data", secstrings + s->sh_name) == 0) || ((strcmp(".data", secstrings + s->sh_name) == 0) && (hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) { - mod->arch.data_a_l1 = s; dest = l1_data_sram_alloc(s->sh_size); + mod->arch.data_a_l1 = dest; if (dest == NULL) { printk(KERN_ERR "module %s: L1 data memory allocation failed\n", @@ -197,8 +204,8 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs, if (strcmp(".l1.bss", secstrings + s->sh_name) == 0 || ((strcmp(".bss", secstrings + s->sh_name) == 0) && (hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) { - mod->arch.bss_a_l1 = s; dest = l1_data_sram_alloc(s->sh_size); + mod->arch.bss_a_l1 = dest; if (dest == NULL) { printk(KERN_ERR "module %s: L1 data memory allocation failed\n", @@ -210,8 +217,8 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs, s->sh_addr = (unsigned long)dest; } if (strcmp(".l1.data.B", secstrings + s->sh_name) == 0) { - mod->arch.data_b_l1 = s; dest = l1_data_B_sram_alloc(s->sh_size); + mod->arch.data_b_l1 = dest; if (dest == NULL) { printk(KERN_ERR "module %s: L1 data memory allocation failed\n", @@ -223,8 +230,8 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs, s->sh_addr = (unsigned long)dest; } if (strcmp(".l1.bss.B", secstrings + s->sh_name) == 0) { - mod->arch.bss_b_l1 = s; dest = l1_data_B_sram_alloc(s->sh_size); + mod->arch.bss_b_l1 = dest; if (dest == NULL) { printk(KERN_ERR "module %s: L1 data memory allocation failed\n", @@ -416,14 +423,14 @@ module_finalize(const Elf_Ehdr * hdr, void module_arch_cleanup(struct module *mod) { - if ((mod->arch.text_l1) && (mod->arch.text_l1->sh_addr)) - l1_inst_sram_free((void *)mod->arch.text_l1->sh_addr); - if ((mod->arch.data_a_l1) && (mod->arch.data_a_l1->sh_addr)) - l1_data_sram_free((void *)mod->arch.data_a_l1->sh_addr); - if ((mod->arch.bss_a_l1) && (mod->arch.bss_a_l1->sh_addr)) - l1_data_sram_free((void *)mod->arch.bss_a_l1->sh_addr); - if ((mod->arch.data_b_l1) && (mod->arch.data_b_l1->sh_addr)) - l1_data_B_sram_free((void *)mod->arch.data_b_l1->sh_addr); - if ((mod->arch.bss_b_l1) && (mod->arch.bss_b_l1->sh_addr)) - l1_data_B_sram_free((void *)mod->arch.bss_b_l1->sh_addr); + if (mod->arch.text_l1) + l1_inst_sram_free((void *)mod->arch.text_l1); + if (mod->arch.data_a_l1) + l1_data_sram_free((void *)mod->arch.data_a_l1); + if (mod->arch.bss_a_l1) + l1_data_sram_free((void *)mod->arch.bss_a_l1); + if (mod->arch.data_b_l1) + l1_data_B_sram_free((void *)mod->arch.data_b_l1); + if (mod->arch.bss_b_l1) + l1_data_B_sram_free((void *)mod->arch.bss_b_l1); } diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c index be9fdd00d7cb2c55ef0dcd1d83a9c0bb9beb6c85..53c2cd255441ff5a23a55ce9cc8e5702ef1ec966 100644 --- a/arch/blackfin/kernel/process.c +++ b/arch/blackfin/kernel/process.c @@ -245,7 +245,7 @@ unsigned long get_wchan(struct task_struct *p) void finish_atomic_sections (struct pt_regs *regs) { - int __user *up0 = (int __user *)®s->p0; + int __user *up0 = (int __user *)regs->p0; if (regs->pc < ATOMIC_SEQS_START || regs->pc >= ATOMIC_SEQS_END) return; diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c index b4f062c172c69042e192b73352c21805ef4a7abe..f51ab088098ec1e16162c2c4a62c4c20a42b4b17 100644 --- a/arch/blackfin/kernel/ptrace.c +++ b/arch/blackfin/kernel/ptrace.c @@ -185,8 +185,8 @@ void ptrace_disable(struct task_struct *child) { unsigned long tmp; /* make sure the single step bit is not set. */ - tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16); - put_reg(child, PT_SR, tmp); + tmp = get_reg(child, PT_SYSCFG) & ~TRACE_BITS; + put_reg(child, PT_SYSCFG, tmp); } long arch_ptrace(struct task_struct *child, long request, long addr, long data) diff --git a/arch/blackfin/kernel/signal.c b/arch/blackfin/kernel/signal.c index cb9d883d493c4b3ad30dbefed9766de9980faf0e..dbc3bbf846be2f4cf7197644fa287c5e9f8ed070 100644 --- a/arch/blackfin/kernel/signal.c +++ b/arch/blackfin/kernel/signal.c @@ -42,6 +42,9 @@ #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) +/* Location of the trace bit in SYSCFG. */ +#define TRACE_BITS 0x0001 + struct fdpic_func_descriptor { unsigned long text; unsigned long GOT; @@ -225,6 +228,16 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info, regs->r1 = (unsigned long)(&frame->info); regs->r2 = (unsigned long)(&frame->uc); + /* + * Clear the trace flag when entering the signal handler, but + * notify any tracer that was single-stepping it. The tracer + * may want to single-step inside the handler too. + */ + if (regs->syscfg & TRACE_BITS) { + regs->syscfg &= ~TRACE_BITS; + ptrace_notify(SIGTRAP); + } + return 0; give_sigsegv: diff --git a/arch/blackfin/kernel/time-ts.c b/arch/blackfin/kernel/time-ts.c index 4482c47c09e5c728891bd453c9a1bfeb8a8823c5..e887efc86c29e8215d544dcba262128b65343008 100644 --- a/arch/blackfin/kernel/time-ts.c +++ b/arch/blackfin/kernel/time-ts.c @@ -60,7 +60,7 @@ static inline unsigned long long cycles_2_ns(cycle_t cyc) static cycle_t read_cycles(void) { - return get_cycles(); + return __bfin_cycles_off + (get_cycles() << __bfin_cycles_mod); } unsigned long long sched_clock(void) @@ -117,7 +117,7 @@ static void bfin_timer_set_mode(enum clock_event_mode mode, break; } case CLOCK_EVT_MODE_ONESHOT: - bfin_write_TSCALE(0); + bfin_write_TSCALE(TIME_SCALE - 1); bfin_write_TCOUNT(0); bfin_write_TCNTL(TMPWR | TMREN); CSYNC(); @@ -183,10 +183,14 @@ irqreturn_t timer_interrupt(int irq, void *dev_id) static int __init bfin_clockevent_init(void) { + unsigned long timer_clk; + + timer_clk = get_cclk() / TIME_SCALE; + setup_irq(IRQ_CORETMR, &bfin_timer_irq); bfin_timer_init(); - clockevent_bfin.mult = div_sc(get_cclk(), NSEC_PER_SEC, clockevent_bfin.shift); + clockevent_bfin.mult = div_sc(timer_clk, NSEC_PER_SEC, clockevent_bfin.shift); clockevent_bfin.max_delta_ns = clockevent_delta2ns(-1, &clockevent_bfin); clockevent_bfin.min_delta_ns = clockevent_delta2ns(100, &clockevent_bfin); clockevents_register_device(&clockevent_bfin); diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index 5b847070dae509f293827e327e32204d4be8e133..7bfbd958980ca39af8386dd897a5766a4407bb58 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c @@ -364,13 +364,13 @@ asmlinkage void trap_c(struct pt_regs *fp) /* 0x27 - Data CPLB Multiple Hits - Linux Trap Zero, handled here */ case VEC_CPLB_MHIT: info.si_code = ILL_CPLB_MULHIT; -#ifdef CONFIG_DEBUG_HUNT_FOR_ZERO sig = SIGSEGV; - printk(KERN_NOTICE "NULL pointer access (probably)\n"); -#else - sig = SIGILL; - printk(KERN_NOTICE EXC_0x27(KERN_NOTICE)); +#ifdef CONFIG_DEBUG_HUNT_FOR_ZERO + if (saved_dcplb_fault_addr < (void *)FIXED_CODE_START) + printk(KERN_NOTICE "NULL pointer access\n"); + else #endif + printk(KERN_NOTICE EXC_0x27(KERN_NOTICE)); CHK_DEBUGGER_TRAP(); break; /* 0x28 - Emulation Watchpoint, handled here */ @@ -419,13 +419,13 @@ asmlinkage void trap_c(struct pt_regs *fp) /* 0x2D - Instruction CPLB Multiple Hits, handled here */ case VEC_CPLB_I_MHIT: info.si_code = ILL_CPLB_MULHIT; -#ifdef CONFIG_DEBUG_HUNT_FOR_ZERO sig = SIGSEGV; - printk(KERN_NOTICE "Jump to address 0 - 0x0fff\n"); -#else - sig = SIGILL; - printk(KERN_NOTICE EXC_0x2D(KERN_NOTICE)); +#ifdef CONFIG_DEBUG_HUNT_FOR_ZERO + if (saved_icplb_fault_addr < (void *)FIXED_CODE_START) + printk(KERN_NOTICE "Jump to NULL address\n"); + else #endif + printk(KERN_NOTICE EXC_0x2D(KERN_NOTICE)); CHK_DEBUGGER_TRAP(); break; /* 0x2E - Illegal use of Supervisor Resource, handled here */ diff --git a/arch/blackfin/lib/checksum.c b/arch/blackfin/lib/checksum.c index 42768e0c80ca59979b8f6f2a5ea572d7eac3caf5..5c87505165d37f5018d06f3c36b5b19b8ac080a1 100644 --- a/arch/blackfin/lib/checksum.c +++ b/arch/blackfin/lib/checksum.c @@ -72,9 +72,9 @@ static unsigned short do_csum(const unsigned char *buff, int len) * This is a version of ip_compute_csum() optimized for IP headers, * which always checksum on 4 octet boundaries. */ -unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl) +__sum16 ip_fast_csum(unsigned char *iph, unsigned int ihl) { - return ~do_csum(iph, ihl * 4); + return (__force __sum16)~do_csum(iph, ihl * 4); } /* @@ -89,7 +89,7 @@ unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl) * * it's best to have buff aligned on a 32-bit boundary */ -unsigned int csum_partial(const unsigned char *buff, int len, unsigned int sum) +__wsum csum_partial(const void *buff, int len, __wsum sum) { /* * Just in case we get nasty checksum data... @@ -109,22 +109,22 @@ unsigned int csum_partial(const unsigned char *buff, int len, unsigned int sum) * this routine is used for miscellaneous IP-like checksums, mainly * in icmp.c */ -unsigned short ip_compute_csum(const unsigned char *buff, int len) +__sum16 ip_compute_csum(const void *buff, int len) { - return ~do_csum(buff, len); + return (__force __sum16)~do_csum(buff, len); } /* * copy from fs while checksumming, otherwise like csum_partial */ -unsigned int -csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst, - int len, int sum, int *csum_err) +__wsum +csum_partial_copy_from_user(const void __user *src, void *dst, + int len, __wsum sum, int *csum_err) { if (csum_err) *csum_err = 0; - memcpy(dst, src, len); + memcpy(dst, (__force void *)src, len); return csum_partial(dst, len, sum); } @@ -132,8 +132,7 @@ csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst, * copy from ds while checksumming, otherwise like csum_partial */ -unsigned int csum_partial_copy(const unsigned char *src, unsigned char *dst, - int len, int sum) +__wsum csum_partial_copy(const void *src, void *dst, int len, __wsum sum) { memcpy(dst, src, len); return csum_partial(dst, len, sum); diff --git a/arch/blackfin/lib/ins.S b/arch/blackfin/lib/ins.S index df7b8833a0c56abf7a5a4ad6df43253f006331c8..eba2343b1b59246564ba96ef89cad418bbba8bf8 100644 --- a/arch/blackfin/lib/ins.S +++ b/arch/blackfin/lib/ins.S @@ -7,7 +7,7 @@ * Description: Implementation of ins{bwl} for BlackFin processors using zero overhead loops. * * Modified: - * Copyright 2004-2006 Analog Devices Inc. + * Copyright 2004-2008 Analog Devices Inc. * Copyright (C) 2005 Bas Vermeulen, BuyWays BV * * Bugs: Enter bugs at http://blackfin.uclinux.org/ @@ -63,6 +63,23 @@ ENTRY(_insw) RTS; ENDPROC(_insw) +ENTRY(_insw_8) + P0 = R0; /* P0 = port */ + cli R3; + P1 = R1; /* P1 = address */ + P2 = R2; /* P2 = count */ + SSYNC; + LSETUP( .Lword8_loop_s, .Lword8_loop_e) LC0 = P2; +.Lword8_loop_s: R0 = W[P0]; + B[P1++] = R0; + R0 = R0 >> 8; + B[P1++] = R0; + NOP; +.Lword8_loop_e: NOP; + sti R3; + RTS; +ENDPROC(_insw_8) + ENTRY(_insb) P0 = R0; /* P0 = port */ cli R3; @@ -78,8 +95,6 @@ ENTRY(_insb) RTS; ENDPROC(_insb) - - ENTRY(_insl_16) P0 = R0; /* P0 = port */ cli R3; diff --git a/arch/blackfin/lib/outs.S b/arch/blackfin/lib/outs.S index 4c3da8ae094ece20119b6181a9b5991b968ad144..3daf96035bf66ca99b92f5459e1c851724e5c30d 100644 --- a/arch/blackfin/lib/outs.S +++ b/arch/blackfin/lib/outs.S @@ -7,7 +7,7 @@ * Description: Implementation of outs{bwl} for BlackFin processors using zero overhead loops. * * Modified: Copyright (C) 2005 Bas Vermeulen, BuyWays BV - * Copyright 2004-2006 Analog Devices Inc. + * Copyright 2004-2008 Analog Devices Inc. * * Bugs: Enter bugs at http://blackfin.uclinux.org/ * @@ -63,3 +63,17 @@ ENTRY(_outsb) .Lbyte_loop_e: B[P0] = R0; RTS; ENDPROC(_outsb) + +ENTRY(_outsw_8) + P0 = R0; /* P0 = port */ + P1 = R1; /* P1 = address */ + P2 = R2; /* P2 = count */ + + LSETUP( .Lword8_loop_s, .Lword8_loop_e) LC0 = P2; +.Lword8_loop_s: R1 = B[P1++]; + R0 = B[P1++]; + R0 = R0 << 8; + R0 = R0 + R1; +.Lword8_loop_e: W[P0] = R0; + RTS; +ENDPROC(_outsw) diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c index 583d53811f0364fb4ae28c3654c5736489e853dd..bb6d58c931de648bc6af3347bece976803e6c92f 100644 --- a/arch/blackfin/mach-bf527/boards/ezkit.c +++ b/arch/blackfin/mach-bf527/boards/ezkit.c @@ -32,12 +32,14 @@ #include #include #include +#include #include #include #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) #include #endif #include +#include #include #include #include @@ -50,6 +52,7 @@ #include #include #include +#include #include /* @@ -171,6 +174,46 @@ static struct platform_device bf52x_t350mcqb_device = { }; #endif +#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) +static struct mtd_partition ezkit_partitions[] = { + { + .name = "Bootloader", + .size = 0x40000, + .offset = 0, + }, { + .name = "Kernel", + .size = 0x1C0000, + .offset = MTDPART_OFS_APPEND, + }, { + .name = "RootFS", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, + } +}; + +static struct physmap_flash_data ezkit_flash_data = { + .width = 2, + .parts = ezkit_partitions, + .nr_parts = ARRAY_SIZE(ezkit_partitions), +}; + +static struct resource ezkit_flash_resource = { + .start = 0x20000000, + .end = 0x203fffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device ezkit_flash_device = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &ezkit_flash_data, + }, + .num_resources = 1, + .resource = &ezkit_flash_resource, +}; +#endif + #if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE) static struct mtd_partition partition_info[] = { { @@ -420,11 +463,7 @@ static struct mtd_partition bfin_spi_flash_partitions[] = { .offset = 0, .mask_flags = MTD_CAP_ROM }, { - .name = "kernel", - .size = 0xe0000, - .offset = MTDPART_OFS_APPEND, - }, { - .name = "file system", + .name = "linux kernel", .size = MTDPART_SIZ_FULL, .offset = MTDPART_OFS_APPEND, } @@ -434,7 +473,7 @@ static struct flash_platform_data bfin_spi_flash_data = { .name = "m25p80", .parts = bfin_spi_flash_partitions, .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions), - .type = "m25p64", + .type = "m25p16", }; /* SPI flash chip (m25p64) */ @@ -755,6 +794,22 @@ static struct platform_device i2c_bfin_twi_device = { }; #endif +#ifdef CONFIG_I2C_BOARDINFO +static struct i2c_board_info __initdata bfin_i2c_board_info[] = { +#if defined(CONFIG_TWI_LCD) || defined(CONFIG_TWI_LCD_MODULE) + { + I2C_BOARD_INFO("pcf8574_lcd", 0x22), + }, +#endif +#if defined(CONFIG_TWI_KEYPAD) || defined(CONFIG_TWI_KEYPAD_MODULE) + { + I2C_BOARD_INFO("pcf8574_keypad", 0x27), + .irq = IRQ_PF8, + }, +#endif +}; +#endif + #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) static struct platform_device bfin_sport0_uart_device = { .name = "bfin-sport-uart", @@ -839,7 +894,32 @@ static struct platform_device bfin_gpios_device = { .resource = &bfin_gpios_resources, }; +static const unsigned int cclk_vlev_datasheet[] = +{ + VRPAIR(VLEV_100, 400000000), + VRPAIR(VLEV_105, 426000000), + VRPAIR(VLEV_110, 500000000), + VRPAIR(VLEV_115, 533000000), + VRPAIR(VLEV_120, 600000000), +}; + +static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = { + .tuple_tab = cclk_vlev_datasheet, + .tabsize = ARRAY_SIZE(cclk_vlev_datasheet), + .vr_settling_time = 25 /* us */, +}; + +static struct platform_device bfin_dpmc = { + .name = "bfin dpmc", + .dev = { + .platform_data = &bfin_dmpc_vreg_data, + }, +}; + static struct platform_device *stamp_devices[] __initdata = { + + &bfin_dpmc, + #if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE) &bf5xx_nand_device, #endif @@ -921,12 +1001,22 @@ static struct platform_device *stamp_devices[] __initdata = { &bfin_device_gpiokeys, #endif +#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) + &ezkit_flash_device, +#endif + &bfin_gpios_device, }; static int __init stamp_init(void) { printk(KERN_INFO "%s(): registering device resources\n", __func__); + +#ifdef CONFIG_I2C_BOARDINFO + i2c_register_board_info(0, bfin_i2c_board_info, + ARRAY_SIZE(bfin_i2c_board_info)); +#endif + platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices)); #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) spi_register_board_info(bfin_spi_board_info, diff --git a/arch/blackfin/mach-bf533/boards/cm_bf533.c b/arch/blackfin/mach-bf533/boards/cm_bf533.c index a03149c72681adb2fdf9e2f2c29c3ed005c59fc2..ed2b0b8f5dc93f4673accc7013329fa67baaf748 100644 --- a/arch/blackfin/mach-bf533/boards/cm_bf533.c +++ b/arch/blackfin/mach-bf533/boards/cm_bf533.c @@ -33,12 +33,15 @@ #include #include #include +#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) #include +#endif #include #include #include #include #include +#include /* * Name the Board for the /proc/cpuinfo @@ -341,7 +344,37 @@ static struct platform_device bfin_pata_device = { }; #endif +static const unsigned int cclk_vlev_datasheet[] = +{ + VRPAIR(VLEV_085, 250000000), + VRPAIR(VLEV_090, 376000000), + VRPAIR(VLEV_095, 426000000), + VRPAIR(VLEV_100, 426000000), + VRPAIR(VLEV_105, 476000000), + VRPAIR(VLEV_110, 476000000), + VRPAIR(VLEV_115, 476000000), + VRPAIR(VLEV_120, 600000000), + VRPAIR(VLEV_125, 600000000), + VRPAIR(VLEV_130, 600000000), +}; + +static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = { + .tuple_tab = cclk_vlev_datasheet, + .tabsize = ARRAY_SIZE(cclk_vlev_datasheet), + .vr_settling_time = 25 /* us */, +}; + +static struct platform_device bfin_dpmc = { + .name = "bfin dpmc", + .dev = { + .platform_data = &bfin_dmpc_vreg_data, + }, +}; + static struct platform_device *cm_bf533_devices[] __initdata = { + + &bfin_dpmc, + #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) &bfin_uart_device, #endif diff --git a/arch/blackfin/mach-bf533/boards/ezkit.c b/arch/blackfin/mach-bf533/boards/ezkit.c index 08a7943949aef477b5fb2820c6d70d059ded82b3..9d28415163ea67064a1085a0b5c9c63e005a4560 100644 --- a/arch/blackfin/mach-bf533/boards/ezkit.c +++ b/arch/blackfin/mach-bf533/boards/ezkit.c @@ -42,6 +42,7 @@ #include #include #include +#include /* * Name the Board for the /proc/cpuinfo @@ -350,7 +351,37 @@ static struct platform_device i2c_gpio_device = { }; #endif +static const unsigned int cclk_vlev_datasheet[] = +{ + VRPAIR(VLEV_085, 250000000), + VRPAIR(VLEV_090, 376000000), + VRPAIR(VLEV_095, 426000000), + VRPAIR(VLEV_100, 426000000), + VRPAIR(VLEV_105, 476000000), + VRPAIR(VLEV_110, 476000000), + VRPAIR(VLEV_115, 476000000), + VRPAIR(VLEV_120, 600000000), + VRPAIR(VLEV_125, 600000000), + VRPAIR(VLEV_130, 600000000), +}; + +static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = { + .tuple_tab = cclk_vlev_datasheet, + .tabsize = ARRAY_SIZE(cclk_vlev_datasheet), + .vr_settling_time = 25 /* us */, +}; + +static struct platform_device bfin_dpmc = { + .name = "bfin dpmc", + .dev = { + .platform_data = &bfin_dmpc_vreg_data, + }, +}; + static struct platform_device *ezkit_devices[] __initdata = { + + &bfin_dpmc, + #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) &smc91x_device, #endif diff --git a/arch/blackfin/mach-bf533/boards/stamp.c b/arch/blackfin/mach-bf533/boards/stamp.c index 024f418ae5430b36951c67072ac312e5c139c58c..ec05b236dc3f766ab738cf7a8d0dcd997ce85454 100644 --- a/arch/blackfin/mach-bf533/boards/stamp.c +++ b/arch/blackfin/mach-bf533/boards/stamp.c @@ -45,6 +45,7 @@ #include #include #include +#include /* * Name the Board for the /proc/cpuinfo @@ -110,7 +111,7 @@ static struct platform_device net2272_bfin_device = { }; #endif -#if defined(CONFIG_MTD_BF5xx) || defined(CONFIG_MTD_BF5xx_MODULE) +#if defined(CONFIG_MTD_BFIN_ASYNC) || defined(CONFIG_MTD_BFIN_ASYNC_MODULE) static struct mtd_partition stamp_partitions[] = { { .name = "Bootloader", @@ -140,13 +141,17 @@ static struct resource stamp_flash_resource[] = { .end = 0x203fffff, .flags = IORESOURCE_MEM, }, { - .start = CONFIG_ENET_FLASH_PIN, + .start = 0x7BB07BB0, /* AMBCTL0 setting when accessing flash */ + .end = 0x7BB07BB0, /* AMBCTL1 setting when accessing flash */ + .flags = IORESOURCE_MEM, + }, { + .start = GPIO_PF0, .flags = IORESOURCE_IRQ, } }; static struct platform_device stamp_flash_device = { - .name = "BF5xx-Flash", + .name = "bfin-async-flash", .id = 0, .dev = { .platform_data = &stamp_flash_data, @@ -516,7 +521,37 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = { }; #endif +static const unsigned int cclk_vlev_datasheet[] = +{ + VRPAIR(VLEV_085, 250000000), + VRPAIR(VLEV_090, 376000000), + VRPAIR(VLEV_095, 426000000), + VRPAIR(VLEV_100, 426000000), + VRPAIR(VLEV_105, 476000000), + VRPAIR(VLEV_110, 476000000), + VRPAIR(VLEV_115, 476000000), + VRPAIR(VLEV_120, 600000000), + VRPAIR(VLEV_125, 600000000), + VRPAIR(VLEV_130, 600000000), +}; + +static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = { + .tuple_tab = cclk_vlev_datasheet, + .tabsize = ARRAY_SIZE(cclk_vlev_datasheet), + .vr_settling_time = 25 /* us */, +}; + +static struct platform_device bfin_dpmc = { + .name = "bfin dpmc", + .dev = { + .platform_data = &bfin_dmpc_vreg_data, + }, +}; + static struct platform_device *stamp_devices[] __initdata = { + + &bfin_dpmc, + #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) &rtc_device, #endif @@ -564,7 +599,7 @@ static struct platform_device *stamp_devices[] __initdata = { &bfin_gpios_device, -#if defined(CONFIG_MTD_BF5xx) || defined(CONFIG_MTD_BF5xx_MODULE) +#if defined(CONFIG_MTD_BFIN_ASYNC) || defined(CONFIG_MTD_BFIN_ASYNC_MODULE) &stamp_flash_device, #endif }; @@ -586,8 +621,8 @@ static int __init stamp_init(void) #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) /* setup BF533_STAMP CPLD to route AMS3 to Ethernet MAC */ - bfin_write_FIO_DIR(bfin_read_FIO_DIR() | (1 << CONFIG_ENET_FLASH_PIN)); - bfin_write_FIO_FLAG_S(1 << CONFIG_ENET_FLASH_PIN); + bfin_write_FIO_DIR(bfin_read_FIO_DIR() | PF0); + bfin_write_FIO_FLAG_S(PF0); SSYNC(); #endif @@ -605,8 +640,8 @@ arch_initcall(stamp_init); void native_machine_restart(char *cmd) { -#define BIT_TO_SET (1 << CONFIG_ENET_FLASH_PIN) - bfin_write_FIO_INEN(~BIT_TO_SET); - bfin_write_FIO_DIR(BIT_TO_SET); - bfin_write_FIO_FLAG_C(BIT_TO_SET); + /* workaround pull up on cpld / flash pin not being strong enough */ + bfin_write_FIO_INEN(~PF0); + bfin_write_FIO_DIR(PF0); + bfin_write_FIO_FLAG_C(PF0); } diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537.c b/arch/blackfin/mach-bf537/boards/cm_bf537.c index d8a23cd9b9ed9f860ae22ccfba85ff1d2c4b175f..73f2142875e241d5257c92b860179b33b3207050 100644 --- a/arch/blackfin/mach-bf537/boards/cm_bf537.c +++ b/arch/blackfin/mach-bf537/boards/cm_bf537.c @@ -35,12 +35,15 @@ #include #include #include +#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) #include +#endif #include #include #include #include #include +#include /* * Name the Board for the /proc/cpuinfo @@ -428,7 +431,37 @@ static struct platform_device bfin_pata_device = { }; #endif +static const unsigned int cclk_vlev_datasheet[] = +{ + VRPAIR(VLEV_085, 250000000), + VRPAIR(VLEV_090, 376000000), + VRPAIR(VLEV_095, 426000000), + VRPAIR(VLEV_100, 426000000), + VRPAIR(VLEV_105, 476000000), + VRPAIR(VLEV_110, 476000000), + VRPAIR(VLEV_115, 476000000), + VRPAIR(VLEV_120, 500000000), + VRPAIR(VLEV_125, 533000000), + VRPAIR(VLEV_130, 600000000), +}; + +static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = { + .tuple_tab = cclk_vlev_datasheet, + .tabsize = ARRAY_SIZE(cclk_vlev_datasheet), + .vr_settling_time = 25 /* us */, +}; + +static struct platform_device bfin_dpmc = { + .name = "bfin dpmc", + .dev = { + .platform_data = &bfin_dmpc_vreg_data, + }, +}; + static struct platform_device *cm_bf537_devices[] __initdata = { + + &bfin_dpmc, + #if defined(CONFIG_FB_HITACHI_TX09) || defined(CONFIG_FB_HITACHI_TX09_MODULE) &hitachi_fb_device, #endif diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index d3727b7c2d7d94da933ec76834c2a2378764b407..9a756d1f3d73f19f52c0688b834952d2baa716f0 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -47,6 +47,7 @@ #include #include #include +#include #include /* @@ -817,7 +818,37 @@ static struct platform_device bfin_pata_device = { }; #endif +static const unsigned int cclk_vlev_datasheet[] = +{ + VRPAIR(VLEV_085, 250000000), + VRPAIR(VLEV_090, 376000000), + VRPAIR(VLEV_095, 426000000), + VRPAIR(VLEV_100, 426000000), + VRPAIR(VLEV_105, 476000000), + VRPAIR(VLEV_110, 476000000), + VRPAIR(VLEV_115, 476000000), + VRPAIR(VLEV_120, 500000000), + VRPAIR(VLEV_125, 533000000), + VRPAIR(VLEV_130, 600000000), +}; + +static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = { + .tuple_tab = cclk_vlev_datasheet, + .tabsize = ARRAY_SIZE(cclk_vlev_datasheet), + .vr_settling_time = 25 /* us */, +}; + +static struct platform_device bfin_dpmc = { + .name = "bfin dpmc", + .dev = { + .platform_data = &bfin_dmpc_vreg_data, + }, +}; + static struct platform_device *stamp_devices[] __initdata = { + + &bfin_dpmc, + #if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE) &bfin_pcmcia_cf_device, #endif diff --git a/arch/blackfin/mach-bf548/boards/cm_bf548.c b/arch/blackfin/mach-bf548/boards/cm_bf548.c index e3e8479fffb5bf28731f2ba195ad0e640872a8c0..3b74f96d3590d04a728bf8970dd2199e2799e8d3 100644 --- a/arch/blackfin/mach-bf548/boards/cm_bf548.c +++ b/arch/blackfin/mach-bf548/boards/cm_bf548.c @@ -36,7 +36,9 @@ #include #include #include +#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE) #include +#endif #include #include #include @@ -44,6 +46,7 @@ #include #include #include +#include #include #include @@ -590,7 +593,38 @@ static struct platform_device bfin_device_gpiokeys = { }; #endif +static const unsigned int cclk_vlev_datasheet[] = +{ +/* + * Internal VLEV BF54XSBBC1533 + ****temporarily using these values until data sheet is updated + */ + VRPAIR(VLEV_085, 150000000), + VRPAIR(VLEV_090, 250000000), + VRPAIR(VLEV_110, 276000000), + VRPAIR(VLEV_115, 301000000), + VRPAIR(VLEV_120, 525000000), + VRPAIR(VLEV_125, 550000000), + VRPAIR(VLEV_130, 600000000), +}; + +static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = { + .tuple_tab = cclk_vlev_datasheet, + .tabsize = ARRAY_SIZE(cclk_vlev_datasheet), + .vr_settling_time = 25 /* us */, +}; + +static struct platform_device bfin_dpmc = { + .name = "bfin dpmc", + .dev = { + .platform_data = &bfin_dmpc_vreg_data, + }, +}; + static struct platform_device *cm_bf548_devices[] __initdata = { + + &bfin_dpmc, + #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) &rtc_device, #endif diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c index b00f68ac6bc991e972a765fe670bfff67bcc5ea8..d1682bb37509937646237df1bf6fa019995a5400 100644 --- a/arch/blackfin/mach-bf548/boards/ezkit.c +++ b/arch/blackfin/mach-bf548/boards/ezkit.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -689,7 +690,38 @@ static struct platform_device bfin_gpios_device = { .resource = &bfin_gpios_resources, }; +static const unsigned int cclk_vlev_datasheet[] = +{ +/* + * Internal VLEV BF54XSBBC1533 + ****temporarily using these values until data sheet is updated + */ + VRPAIR(VLEV_085, 150000000), + VRPAIR(VLEV_090, 250000000), + VRPAIR(VLEV_110, 276000000), + VRPAIR(VLEV_115, 301000000), + VRPAIR(VLEV_120, 525000000), + VRPAIR(VLEV_125, 550000000), + VRPAIR(VLEV_130, 600000000), +}; + +static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = { + .tuple_tab = cclk_vlev_datasheet, + .tabsize = ARRAY_SIZE(cclk_vlev_datasheet), + .vr_settling_time = 25 /* us */, +}; + +static struct platform_device bfin_dpmc = { + .name = "bfin dpmc", + .dev = { + .platform_data = &bfin_dmpc_vreg_data, + }, +}; + static struct platform_device *ezkit_devices[] __initdata = { + + &bfin_dpmc, + #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) &rtc_device, #endif diff --git a/arch/blackfin/mach-bf561/boards/cm_bf561.c b/arch/blackfin/mach-bf561/boards/cm_bf561.c index 9fd580952fd891cc0a64808f22fdf43fb154473b..466ef5929a254d76d62333fc198554d41245cfd7 100644 --- a/arch/blackfin/mach-bf561/boards/cm_bf561.c +++ b/arch/blackfin/mach-bf561/boards/cm_bf561.c @@ -33,12 +33,15 @@ #include #include #include +#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) #include +#endif #include #include #include #include #include +#include /* * Name the Board for the /proc/cpuinfo @@ -339,8 +342,37 @@ static struct platform_device bfin_pata_device = { }; #endif +static const unsigned int cclk_vlev_datasheet[] = +{ + VRPAIR(VLEV_085, 250000000), + VRPAIR(VLEV_090, 300000000), + VRPAIR(VLEV_095, 313000000), + VRPAIR(VLEV_100, 350000000), + VRPAIR(VLEV_105, 400000000), + VRPAIR(VLEV_110, 444000000), + VRPAIR(VLEV_115, 450000000), + VRPAIR(VLEV_120, 475000000), + VRPAIR(VLEV_125, 500000000), + VRPAIR(VLEV_130, 600000000), +}; + +static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = { + .tuple_tab = cclk_vlev_datasheet, + .tabsize = ARRAY_SIZE(cclk_vlev_datasheet), + .vr_settling_time = 25 /* us */, +}; + +static struct platform_device bfin_dpmc = { + .name = "bfin dpmc", + .dev = { + .platform_data = &bfin_dmpc_vreg_data, + }, +}; + static struct platform_device *cm_bf561_devices[] __initdata = { + &bfin_dpmc, + #if defined(CONFIG_FB_HITACHI_TX09) || defined(CONFIG_FB_HITACHI_TX09_MODULE) &hitachi_fb_device, #endif diff --git a/arch/blackfin/mach-bf561/boards/ezkit.c b/arch/blackfin/mach-bf561/boards/ezkit.c index 0d74b7d99209e7460c5af87f9926d9ea1c32c32e..61d8f7648b247da40f771d252ecfd759c20e29bf 100644 --- a/arch/blackfin/mach-bf561/boards/ezkit.c +++ b/arch/blackfin/mach-bf561/boards/ezkit.c @@ -39,6 +39,7 @@ #include #include #include +#include /* * Name the Board for the /proc/cpuinfo @@ -443,7 +444,37 @@ static struct platform_device i2c_gpio_device = { }; #endif +static const unsigned int cclk_vlev_datasheet[] = +{ + VRPAIR(VLEV_085, 250000000), + VRPAIR(VLEV_090, 300000000), + VRPAIR(VLEV_095, 313000000), + VRPAIR(VLEV_100, 350000000), + VRPAIR(VLEV_105, 400000000), + VRPAIR(VLEV_110, 444000000), + VRPAIR(VLEV_115, 450000000), + VRPAIR(VLEV_120, 475000000), + VRPAIR(VLEV_125, 500000000), + VRPAIR(VLEV_130, 600000000), +}; + +static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = { + .tuple_tab = cclk_vlev_datasheet, + .tabsize = ARRAY_SIZE(cclk_vlev_datasheet), + .vr_settling_time = 25 /* us */, +}; + +static struct platform_device bfin_dpmc = { + .name = "bfin dpmc", + .dev = { + .platform_data = &bfin_dmpc_vreg_data, + }, +}; + static struct platform_device *ezkit_devices[] __initdata = { + + &bfin_dpmc, + #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) &smc91x_device, #endif diff --git a/arch/blackfin/mach-common/Makefile b/arch/blackfin/mach-common/Makefile index 393081e9b6804316b4d61c6d4f25ef9fbe13bb3d..422bfee34adcec22b834a41a36b55f9e3337dffa 100644 --- a/arch/blackfin/mach-common/Makefile +++ b/arch/blackfin/mach-common/Makefile @@ -6,5 +6,6 @@ obj-y := \ cache.o cacheinit.o entry.o \ interrupt.o lock.o irqpanic.o arch_checks.o ints-priority.o -obj-$(CONFIG_PM) += pm.o dpmc.o -obj-$(CONFIG_CPU_FREQ) += cpufreq.o +obj-$(CONFIG_PM) += pm.o dpmc_modes.o +obj-$(CONFIG_CPU_FREQ) += cpufreq.o +obj-$(CONFIG_CPU_VOLTAGE) += dpmc.o diff --git a/arch/blackfin/mach-common/cpufreq.c b/arch/blackfin/mach-common/cpufreq.c index ed81e00d20e172cd8c14e9966d77211fc00f2c49..75cdad291e889be2b3b1a761c6304d9308d46118 100644 --- a/arch/blackfin/mach-common/cpufreq.c +++ b/arch/blackfin/mach-common/cpufreq.c @@ -62,6 +62,14 @@ static struct bfin_dpm_state { unsigned int tscale; /* change the divider on the core timer interrupt */ } dpm_state_table[3]; +/* + normalized to maximum frequncy offset for CYCLES, + used in time-ts cycles clock source, but could be used + somewhere also. + */ +unsigned long long __bfin_cycles_off; +unsigned int __bfin_cycles_mod; + /**************************************************************************/ static unsigned int bfin_getfreq(unsigned int cpu) @@ -80,6 +88,7 @@ static int bfin_target(struct cpufreq_policy *policy, unsigned int index, plldiv, tscale; unsigned long flags, cclk_hz; struct cpufreq_freqs freqs; + cycles_t cycles; if (cpufreq_frequency_table_target(policy, bfin_freq_table, target_freq, relation, &index)) @@ -101,8 +110,14 @@ static int bfin_target(struct cpufreq_policy *policy, bfin_write_PLL_DIV(plldiv); /* we have to adjust the core timer, because it is using cclk */ bfin_write_TSCALE(tscale); + cycles = get_cycles(); SSYNC(); + cycles += 10; /* ~10 cycles we loose after get_cycles() */ + __bfin_cycles_off += (cycles << __bfin_cycles_mod) - (cycles << index); + __bfin_cycles_mod = index; local_irq_restore(flags); + /* TODO: just test case for cycles clock source, remove later */ + pr_debug("cpufreq: done\n"); cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); return 0; @@ -119,22 +134,13 @@ static int __init __bfin_cpu_init(struct cpufreq_policy *policy) unsigned long cclk, sclk, csel, min_cclk; int index; -#ifdef CONFIG_CYCLES_CLOCKSOURCE -/* - * Clocksource CYCLES is still CONTINUOUS but not longer MONOTONIC in case we enable - * CPU frequency scaling, since CYCLES runs off Core Clock. - */ - printk(KERN_WARNING "CPU frequency scaling not supported: Clocksource not suitable\n" - return -ENODEV; -#endif - if (policy->cpu != 0) return -EINVAL; cclk = get_cclk(); sclk = get_sclk(); -#if ANOMALY_05000273 +#if ANOMALY_05000273 || (!defined(CONFIG_BF54x) && defined(CONFIG_BFIN_DCACHE)) min_cclk = sclk * 2; #else min_cclk = sclk; diff --git a/arch/blackfin/mach-common/dpmc.c b/arch/blackfin/mach-common/dpmc.c new file mode 100644 index 0000000000000000000000000000000000000000..02c7efd1bcf4807939135734a5f41e159b1af224 --- /dev/null +++ b/arch/blackfin/mach-common/dpmc.c @@ -0,0 +1,137 @@ +/* + * Copyright 2008 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define DRIVER_NAME "bfin dpmc" + +#define dprintk(msg...) \ + cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, DRIVER_NAME, msg) + +struct bfin_dpmc_platform_data *pdata; + +/** + * bfin_set_vlev - Update VLEV field in VR_CTL Reg. + * Avoid BYPASS sequence + */ +static void bfin_set_vlev(unsigned int vlev) +{ + unsigned pll_lcnt; + + pll_lcnt = bfin_read_PLL_LOCKCNT(); + + bfin_write_PLL_LOCKCNT(1); + bfin_write_VR_CTL((bfin_read_VR_CTL() & ~VLEV) | vlev); + bfin_write_PLL_LOCKCNT(pll_lcnt); +} + +/** + * bfin_get_vlev - Get CPU specific VLEV from platform device data + */ +static unsigned int bfin_get_vlev(unsigned int freq) +{ + int i; + + if (!pdata) + goto err_out; + + freq >>= 16; + + for (i = 0; i < pdata->tabsize; i++) + if (freq <= (pdata->tuple_tab[i] & 0xFFFF)) + return pdata->tuple_tab[i] >> 16; + +err_out: + printk(KERN_WARNING "DPMC: No suitable CCLK VDDINT voltage pair found\n"); + return VLEV_120; +} + +#ifdef CONFIG_CPU_FREQ +static int +vreg_cpufreq_notifier(struct notifier_block *nb, unsigned long val, void *data) +{ + struct cpufreq_freqs *freq = data; + + if (val == CPUFREQ_PRECHANGE && freq->old < freq->new) { + bfin_set_vlev(bfin_get_vlev(freq->new)); + udelay(pdata->vr_settling_time); /* Wait until Volatge settled */ + + } else if (val == CPUFREQ_POSTCHANGE && freq->old > freq->new) + bfin_set_vlev(bfin_get_vlev(freq->new)); + + return 0; +} + +static struct notifier_block vreg_cpufreq_notifier_block = { + .notifier_call = vreg_cpufreq_notifier +}; +#endif /* CONFIG_CPU_FREQ */ + +/** + * bfin_dpmc_probe - + * + */ +static int __devinit bfin_dpmc_probe(struct platform_device *pdev) +{ + if (pdev->dev.platform_data) + pdata = pdev->dev.platform_data; + else + return -EINVAL; + + return cpufreq_register_notifier(&vreg_cpufreq_notifier_block, + CPUFREQ_TRANSITION_NOTIFIER); +} + +/** + * bfin_dpmc_remove - + */ +static int __devexit bfin_dpmc_remove(struct platform_device *pdev) +{ + pdata = NULL; + return cpufreq_unregister_notifier(&vreg_cpufreq_notifier_block, + CPUFREQ_TRANSITION_NOTIFIER); +} + +struct platform_driver bfin_dpmc_device_driver = { + .probe = bfin_dpmc_probe, + .remove = __devexit_p(bfin_dpmc_remove), + .driver = { + .name = DRIVER_NAME, + } +}; + +/** + * bfin_dpmc_init - Init driver + */ +static int __init bfin_dpmc_init(void) +{ + return platform_driver_register(&bfin_dpmc_device_driver); +} +module_init(bfin_dpmc_init); + +/** + * bfin_dpmc_exit - break down driver + */ +static void __exit bfin_dpmc_exit(void) +{ + platform_driver_unregister(&bfin_dpmc_device_driver); +} +module_exit(bfin_dpmc_exit); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("cpu power management driver for Blackfin"); +MODULE_LICENSE("GPL"); diff --git a/arch/blackfin/mach-common/dpmc.S b/arch/blackfin/mach-common/dpmc_modes.S similarity index 82% rename from arch/blackfin/mach-common/dpmc.S rename to arch/blackfin/mach-common/dpmc_modes.S index 9d45aa3265b19a399e403045c1cda8ad3cac5130..b7981d31c39212b42ea0d1ce56017e9a1867cb43 100644 --- a/arch/blackfin/mach-common/dpmc.S +++ b/arch/blackfin/mach-common/dpmc_modes.S @@ -1,30 +1,7 @@ /* - * File: arch/blackfin/mach-common/dpmc.S - * Based on: - * Author: LG Soft India + * Copyright 2004-2008 Analog Devices Inc. * - * Created: ? - * Description: Watchdog Timer APIs - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Licensed under the GPL-2 or later. */ #include diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S index f2fb87e9a46e29edfb5f04f2190ff337717e35da..038f70e0be65cb4adcb1ada19b07f6d75eba7d8b 100644 --- a/arch/blackfin/mach-common/entry.S +++ b/arch/blackfin/mach-common/entry.S @@ -151,26 +151,62 @@ ENTRY(_ex_soft_bp) ENDPROC(_ex_soft_bp) ENTRY(_ex_single_step) + /* If we just returned from an interrupt, the single step event is + for the RTI instruction. */ r7 = retx; r6 = reti; cc = r7 == r6; - if cc jump _bfin_return_from_exception - r7 = syscfg; - bitclr (r7, 0); - syscfg = R7; + if cc jump _bfin_return_from_exception; + /* If we were in user mode, do the single step normally. */ p5.l = lo(IPEND); p5.h = hi(IPEND); r6 = [p5]; - cc = bittst(r6, 5); - if !cc jump _ex_trap_c; - p4.l = lo(EVT5); - p4.h = hi(EVT5); - r6.h = _exception_to_level5; - r6.l = _exception_to_level5; - r7 = [p4]; - cc = r6 == r7; - if !cc jump _ex_trap_c; + r7 = 0xffe0 (z); + r7 = r7 & r6; + cc = r7 == 0; + if !cc jump 1f; + + /* Single stepping only a single instruction, so clear the trace + * bit here. */ + r7 = syscfg; + bitclr (r7, 0); + syscfg = R7; + jump _ex_trap_c; + +1: + /* + * We were in an interrupt handler. By convention, all of them save + * SYSCFG with their first instruction, so by checking whether our + * RETX points at the entry point, we can determine whether to allow + * a single step, or whether to clear SYSCFG. + * + * First, find out the interrupt level and the event vector for it. + */ + p5.l = lo(EVT0); + p5.h = hi(EVT0); + p5 += -4; +2: + r7 = rot r7 by -1; + p5 += 4; + if !cc jump 2b; + + /* What we actually do is test for the _second_ instruction in the + * IRQ handler. That way, if there are insns following the restore + * of SYSCFG after leaving the handler, we will not turn off SYSCFG + * for them. */ + + r7 = [p5]; + r7 += 2; + r6 = RETX; + cc = R7 == R6; + if !cc jump _bfin_return_from_exception; + + r7 = syscfg; + bitclr (r7, 0); + syscfg = R7; + + /* Fall through to _bfin_return_from_exception. */ ENDPROC(_ex_single_step) ENTRY(_bfin_return_from_exception) @@ -234,20 +270,26 @@ ENTRY(_ex_trap_c) p5.l = _saved_icplb_fault_addr; [p5] = r7; - p4.l = __retx; - p4.h = __retx; + p4.l = _excpt_saved_stuff; + p4.h = _excpt_saved_stuff; + r6 = retx; [p4] = r6; - p4.l = lo(SAFE_USER_INSTRUCTION); - p4.h = hi(SAFE_USER_INSTRUCTION); - retx = p4; + + r6 = SYSCFG; + [p4 + 4] = r6; + BITCLR(r6, 0); + SYSCFG = r6; /* Disable all interrupts, but make sure level 5 is enabled so * we can switch to that level. Save the old mask. */ cli r6; - p4.l = _excpt_saved_imask; - p4.h = _excpt_saved_imask; - [p4] = r6; + [p4 + 8] = r6; + + p4.l = lo(SAFE_USER_INSTRUCTION); + p4.h = hi(SAFE_USER_INSTRUCTION); + retx = p4; + r6 = 0x3f; sti r6; @@ -295,6 +337,11 @@ ENTRY(_double_fault) */ SAVE_ALL_SYS + /* The dumping functions expect the return address in the RETI + * slot. */ + r6 = retx; + [sp + PT_PC] = r6; + r0 = sp; /* stack frame pt_regs pointer argument ==> r0 */ SP += -12; call _double_fault_c; @@ -307,16 +354,17 @@ ENDPROC(_double_fault) ENTRY(_exception_to_level5) SAVE_ALL_SYS - p4.l = __retx; - p4.h = __retx; + p4.l = _excpt_saved_stuff; + p4.h = _excpt_saved_stuff; r6 = [p4]; [sp + PT_PC] = r6; + r6 = [p4 + 4]; + [sp + PT_SYSCFG] = r6; + /* Restore interrupt mask. We haven't pushed RETI, so this * doesn't enable interrupts until we return from this handler. */ - p4.l = _excpt_saved_imask; - p4.h = _excpt_saved_imask; - r6 = [p4]; + r6 = [p4 + 8]; sti r6; /* Restore the hardware error vector. */ @@ -1344,7 +1392,14 @@ ENTRY(_sys_call_table) .rept NR_syscalls-(.-_sys_call_table)/4 .long _sys_ni_syscall .endr -_excpt_saved_imask: + + /* + * Used to save the real RETX, IMASK and SYSCFG when temporarily + * storing safe values across the transition from exception to IRQ5. + */ +_excpt_saved_stuff: + .long 0; + .long 0; .long 0; _exception_stack: @@ -1358,7 +1413,3 @@ _exception_stack_top: _last_cplb_fault_retx: .long 0; #endif - /* Used to save the real RETX when temporarily storing a safe - * return address. */ -__retx: - .long 0; diff --git a/arch/cris/kernel/process.c b/arch/cris/kernel/process.c index ef2db8fd102aaa58169e6fc6c7e78f65eee0bb32..5933656db5a2ca58b9a2f583ce5945a57d1b832b 100644 --- a/arch/cris/kernel/process.c +++ b/arch/cris/kernel/process.c @@ -38,7 +38,6 @@ */ static struct fs_struct init_fs = INIT_FS; -static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS(init_signals); static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); struct mm_struct init_mm = INIT_MM(init_mm); diff --git a/arch/cris/kernel/sys_cris.c b/arch/cris/kernel/sys_cris.c index 8b9984197edcc57878356a56848c237ea06aa109..a79fbd87021b02cf03663f7a06d680a58a24ceac 100644 --- a/arch/cris/kernel/sys_cris.c +++ b/arch/cris/kernel/sys_cris.c @@ -27,25 +27,6 @@ #include #include -/* - * sys_pipe() is the normal C calling standard for creating - * a pipe. It's not the way Unix traditionally does this, though. - */ -asmlinkage int sys_pipe(unsigned long __user * fildes) -{ - int fd[2]; - int error; - - lock_kernel(); - error = do_pipe(fd); - unlock_kernel(); - if (!error) { - if (copy_to_user(fildes, fd, 2*sizeof(int))) - error = -EFAULT; - } - return error; -} - /* common code for old and new mmaps */ static inline long do_mmap2(unsigned long addr, unsigned long len, unsigned long prot, diff --git a/arch/frv/kernel/init_task.c b/arch/frv/kernel/init_task.c index 22993932b3fc7a689ae1bef65e773d7ced93c1f4..e2198815b630e5dafd7084ffbac233026fe3ea2f 100644 --- a/arch/frv/kernel/init_task.c +++ b/arch/frv/kernel/init_task.c @@ -11,7 +11,6 @@ static struct fs_struct init_fs = INIT_FS; -static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS(init_signals); static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); struct mm_struct init_mm = INIT_MM(init_mm); diff --git a/arch/h8300/kernel/init_task.c b/arch/h8300/kernel/init_task.c index 19272c2ac56a2b76a0bea621c7ae39708153b923..93a4899e46c23d24923920a85d8977448ad4644e 100644 --- a/arch/h8300/kernel/init_task.c +++ b/arch/h8300/kernel/init_task.c @@ -13,7 +13,6 @@ #include static struct fs_struct init_fs = INIT_FS; -static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS(init_signals); static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); struct mm_struct init_mm = INIT_MM(init_mm); diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 0df5f6f75edf7a016d7033a85519e778d4cfcc7c..16be41446b5bd60bed0730db3b2f152ab851d085 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -135,6 +135,7 @@ config IA64_GENERIC HP-zx1/sx1000 For HP systems HP-zx1/sx1000+swiotlb For HP systems with (broken) DMA-constrained devices. SGI-SN2 For SGI Altix systems + SGI-UV For SGI UV systems Ski-simulator For the HP simulator If you don't know what to do, choose "generic". @@ -170,6 +171,18 @@ config IA64_SGI_SN2 to select this option. If in doubt, select ia64 generic support instead. +config IA64_SGI_UV` + bool "SGI-UV`" + select NUMA + select ACPI_NUMA + select SWIOTLB + help + Selecting this option will optimize the kernel for use on UV based + systems, but the resulting kernel binary will not run on other + types of ia64 systems. If you have an SGI UV system, it's safe + to select this option. If in doubt, select ia64 generic support + instead. + config IA64_HP_SIM bool "Ski-simulator" select SWIOTLB diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile index ec4cca477f491c31cf74b79f184e1fce812cf4dc..88f1a55c6c94461c9967dbb54dec198abd9935ca 100644 --- a/arch/ia64/Makefile +++ b/arch/ia64/Makefile @@ -63,7 +63,7 @@ drivers-$(CONFIG_PCI) += arch/ia64/pci/ drivers-$(CONFIG_IA64_HP_SIM) += arch/ia64/hp/sim/ drivers-$(CONFIG_IA64_HP_ZX1) += arch/ia64/hp/common/ arch/ia64/hp/zx1/ drivers-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += arch/ia64/hp/common/ arch/ia64/hp/zx1/ -drivers-$(CONFIG_IA64_GENERIC) += arch/ia64/hp/common/ arch/ia64/hp/zx1/ arch/ia64/hp/sim/ arch/ia64/sn/ +drivers-$(CONFIG_IA64_GENERIC) += arch/ia64/hp/common/ arch/ia64/hp/zx1/ arch/ia64/hp/sim/ arch/ia64/sn/ arch/ia64/uv/ drivers-$(CONFIG_OPROFILE) += arch/ia64/oprofile/ boot := arch/ia64/hp/sim/boot diff --git a/arch/ia64/ia32/ia32_support.c b/arch/ia64/ia32/ia32_support.c index 896b1ebbfb268381bc87eb2e766e9c75e7d75f84..a6965ddafc46c90b188cdf0e7f1f9ede463abdbb 100644 --- a/arch/ia64/ia32/ia32_support.c +++ b/arch/ia64/ia32/ia32_support.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include @@ -29,7 +28,6 @@ extern int die_if_kernel (char *str, struct pt_regs *regs, long err); -struct exec_domain ia32_exec_domain; struct page *ia32_shared_page[NR_CPUS]; unsigned long *ia32_boot_gdt; unsigned long *cpu_gdt_table[NR_CPUS]; @@ -240,14 +238,6 @@ ia32_cpu_init (void) static int __init ia32_init (void) { - ia32_exec_domain.name = "Linux/x86"; - ia32_exec_domain.handler = NULL; - ia32_exec_domain.pers_low = PER_LINUX32; - ia32_exec_domain.pers_high = PER_LINUX32; - ia32_exec_domain.signal_map = default_exec_domain.signal_map; - ia32_exec_domain.signal_invmap = default_exec_domain.signal_invmap; - register_exec_domain(&ia32_exec_domain); - #if PAGE_SHIFT > IA32_PAGE_SHIFT { extern struct kmem_cache *ia64_partial_page_cachep; diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 19709a0796351e408a30fcd74ebc3a6ac92ec279..853d1f11be005f9e0b3443d8b33cdcbd72e53edd 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c @@ -117,7 +117,10 @@ acpi_get_sysname(void) if (!strcmp(hdr->oem_id, "HP")) { return "hpzx1"; } else if (!strcmp(hdr->oem_id, "SGI")) { - return "sn2"; + if (!strcmp(hdr->oem_table_id + 4, "UV")) + return "uv"; + else + return "sn2"; } return "dig"; @@ -130,6 +133,8 @@ acpi_get_sysname(void) return "hpzx1_swiotlb"; # elif defined (CONFIG_IA64_SGI_SN2) return "sn2"; +# elif defined (CONFIG_IA64_SGI_UV) + return "uv"; # elif defined (CONFIG_IA64_DIG) return "dig"; # else @@ -622,6 +627,9 @@ void acpi_unregister_gsi(u32 gsi) if (acpi_irq_model == ACPI_IRQ_MODEL_PLATFORM) return; + if (has_8259 && gsi < 16) + return; + iosapic_unregister_intr(gsi); } diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index e49ad8c5dc6954303f47dd3d050525ff3353c800..ca2bb95726de7c24fad1f00013d37ca483d7217a 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -1156,6 +1156,9 @@ skip_rbs_switch: * r31 = current->thread_info->flags * On exit: * p6 = TRUE if work-pending-check needs to be redone + * + * Interrupts are disabled on entry, reenabled depend on work, and + * disabled on exit. */ .work_pending_syscall: add r2=-8,r2 @@ -1164,16 +1167,16 @@ skip_rbs_switch: st8 [r2]=r8 st8 [r3]=r10 .work_pending: - tbit.z p6,p0=r31,TIF_NEED_RESCHED // current_thread_info()->need_resched==0? + tbit.z p6,p0=r31,TIF_NEED_RESCHED // is resched not needed? (p6) br.cond.sptk.few .notify #ifdef CONFIG_PREEMPT (pKStk) dep r21=-1,r0,PREEMPT_ACTIVE_BIT,1 ;; (pKStk) st4 [r20]=r21 - ssm psr.i // enable interrupts #endif + ssm psr.i // enable interrupts br.call.spnt.many rp=schedule -.ret9: cmp.eq p6,p0=r0,r0 // p6 <- 1 +.ret9: cmp.eq p6,p0=r0,r0 // p6 <- 1 (re-check) rsm psr.i // disable interrupts ;; #ifdef CONFIG_PREEMPT @@ -1182,13 +1185,13 @@ skip_rbs_switch: (pKStk) st4 [r20]=r0 // preempt_count() <- 0 #endif (pLvSys)br.cond.sptk.few .work_pending_syscall_end - br.cond.sptk.many .work_processed_kernel // re-check + br.cond.sptk.many .work_processed_kernel .notify: (pUStk) br.call.spnt.many rp=notify_resume_user -.ret10: cmp.ne p6,p0=r0,r0 // p6 <- 0 +.ret10: cmp.ne p6,p0=r0,r0 // p6 <- 0 (don't re-check) (pLvSys)br.cond.sptk.few .work_pending_syscall_end - br.cond.sptk.many .work_processed_kernel // don't re-check + br.cond.sptk.many .work_processed_kernel .work_pending_syscall_end: adds r2=PT(R8)+16,r12 @@ -1196,7 +1199,7 @@ skip_rbs_switch: ;; ld8 r8=[r2] ld8 r10=[r3] - br.cond.sptk.many .work_processed_syscall // re-check + br.cond.sptk.many .work_processed_syscall END(ia64_leave_kernel) @@ -1234,9 +1237,12 @@ GLOBAL_ENTRY(ia64_invoke_schedule_tail) END(ia64_invoke_schedule_tail) /* - * Setup stack and call do_notify_resume_user(). Note that pSys and pNonSys need to - * be set up by the caller. We declare 8 input registers so the system call - * args get preserved, in case we need to restart a system call. + * Setup stack and call do_notify_resume_user(), keeping interrupts + * disabled. + * + * Note that pSys and pNonSys need to be set up by the caller. + * We declare 8 input registers so the system call args get preserved, + * in case we need to restart a system call. */ ENTRY(notify_resume_user) .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8) diff --git a/arch/ia64/kernel/init_task.c b/arch/ia64/kernel/init_task.c index bc8efcad28b877c046c589a4a7514129b5aed010..9d7e1c66faf403ecfc154dc7597248892b1f38f8 100644 --- a/arch/ia64/kernel/init_task.c +++ b/arch/ia64/kernel/init_task.c @@ -18,7 +18,6 @@ #include static struct fs_struct init_fs = INIT_FS; -static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS(init_signals); static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); struct mm_struct init_mm = INIT_MM(init_mm); diff --git a/arch/ia64/kernel/palinfo.c b/arch/ia64/kernel/palinfo.c index 4547a2092af9d4717273883247b6e854749c819d..9dc00f7fe10e8f6c08cccaa37df20c6eba739e4f 100644 --- a/arch/ia64/kernel/palinfo.c +++ b/arch/ia64/kernel/palinfo.c @@ -900,12 +900,6 @@ static void palinfo_smp_call(void *info) { palinfo_smp_data_t *data = (palinfo_smp_data_t *)info; - if (data == NULL) { - printk(KERN_ERR "palinfo: data pointer is NULL\n"); - data->ret = 0; /* no output */ - return; - } - /* does this actual call */ data->ret = (*data->func)(data->page); } diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index c1ad27de2dd2080e0bdea8a845147fcc6f855dba..71d05133f556000530d930537c9dc14c543037c9 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c @@ -5013,12 +5013,13 @@ pfm_context_force_terminate(pfm_context_t *ctx, struct pt_regs *regs) } static int pfm_ovfl_notify_user(pfm_context_t *ctx, unsigned long ovfl_pmds); + /* * pfm_handle_work() can be called with interrupts enabled * (TIF_NEED_RESCHED) or disabled. The down_interruptible * call may sleep, therefore we must re-enable interrupts * to avoid deadlocks. It is safe to do so because this function - * is called ONLY when returning to user level (PUStk=1), in which case + * is called ONLY when returning to user level (pUStk=1), in which case * there is no risk of kernel stack overflow due to deep * interrupt nesting. */ @@ -5034,7 +5035,8 @@ pfm_handle_work(void) ctx = PFM_GET_CTX(current); if (ctx == NULL) { - printk(KERN_ERR "perfmon: [%d] has no PFM context\n", task_pid_nr(current)); + printk(KERN_ERR "perfmon: [%d] has no PFM context\n", + task_pid_nr(current)); return; } @@ -5058,11 +5060,12 @@ pfm_handle_work(void) /* * must be done before we check for simple-reset mode */ - if (ctx->ctx_fl_going_zombie || ctx->ctx_state == PFM_CTX_ZOMBIE) goto do_zombie; - + if (ctx->ctx_fl_going_zombie || ctx->ctx_state == PFM_CTX_ZOMBIE) + goto do_zombie; //if (CTX_OVFL_NOBLOCK(ctx)) goto skip_blocking; - if (reason == PFM_TRAP_REASON_RESET) goto skip_blocking; + if (reason == PFM_TRAP_REASON_RESET) + goto skip_blocking; /* * restore interrupt mask to what it was on entry. @@ -5110,7 +5113,8 @@ do_zombie: /* * in case of interruption of down() we don't restart anything */ - if (ret < 0) goto nothing_to_do; + if (ret < 0) + goto nothing_to_do; skip_blocking: pfm_resume_after_ovfl(ctx, ovfl_regs, regs); diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index 58dcfac5ea882ec5529ffdec98d3219cbb58b27d..a3a34b4eb038e6d03d6b487ec3916748605a1025 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c @@ -167,11 +167,18 @@ void tsk_clear_notify_resume(struct task_struct *tsk) clear_ti_thread_flag(task_thread_info(tsk), TIF_NOTIFY_RESUME); } +/* + * do_notify_resume_user(): + * Called from notify_resume_user at entry.S, with interrupts disabled. + */ void -do_notify_resume_user (sigset_t *unused, struct sigscratch *scr, long in_syscall) +do_notify_resume_user(sigset_t *unused, struct sigscratch *scr, long in_syscall) { if (fsys_mode(current, &scr->pt)) { - /* defer signal-handling etc. until we return to privilege-level 0. */ + /* + * defer signal-handling etc. until we return to + * privilege-level 0. + */ if (!ia64_psr(&scr->pt)->lp) ia64_psr(&scr->pt)->lp = 1; return; @@ -179,16 +186,26 @@ do_notify_resume_user (sigset_t *unused, struct sigscratch *scr, long in_syscall #ifdef CONFIG_PERFMON if (current->thread.pfm_needs_checking) + /* + * Note: pfm_handle_work() allow us to call it with interrupts + * disabled, and may enable interrupts within the function. + */ pfm_handle_work(); #endif /* deal with pending signal delivery */ - if (test_thread_flag(TIF_SIGPENDING)) + if (test_thread_flag(TIF_SIGPENDING)) { + local_irq_enable(); /* force interrupt enable */ ia64_do_signal(scr, in_syscall); + } /* copy user rbs to kernel rbs */ - if (unlikely(test_thread_flag(TIF_RESTORE_RSE))) + if (unlikely(test_thread_flag(TIF_RESTORE_RSE))) { + local_irq_enable(); /* force interrupt enable */ ia64_sync_krbs(); + } + + local_irq_disable(); /* force interrupt disable */ } static int pal_halt = 1; diff --git a/arch/ia64/kernel/sal.c b/arch/ia64/kernel/sal.c index a3022dc48ef8432a437256948d5a25080b1cf24d..7e0259709c0415081c6f42396e7e2d446c9c5479 100644 --- a/arch/ia64/kernel/sal.c +++ b/arch/ia64/kernel/sal.c @@ -229,6 +229,14 @@ static void __init sal_desc_ap_wakeup(void *p) { } */ static int sal_cache_flush_drops_interrupts; +static int __init +force_pal_cache_flush(char *str) +{ + sal_cache_flush_drops_interrupts = 1; + return 0; +} +early_param("force_pal_cache_flush", force_pal_cache_flush); + void __init check_sal_cache_flush (void) { @@ -237,6 +245,9 @@ check_sal_cache_flush (void) u64 vector, cache_type = 3; struct ia64_sal_retval isrv; + if (sal_cache_flush_drops_interrupts) + return; + cpu = get_cpu(); local_irq_save(flags); diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index 5015ca1275ca0520f4e0530e94fd57eae9b7cbef..e9596cd0cdab21595f7c5f85d7da7d2952beb5d6 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -239,6 +239,25 @@ __initcall(register_memory); #ifdef CONFIG_KEXEC + +/* + * This function checks if the reserved crashkernel is allowed on the specific + * IA64 machine flavour. Machines without an IO TLB use swiotlb and require + * some memory below 4 GB (i.e. in 32 bit area), see the implementation of + * lib/swiotlb.c. The hpzx1 architecture has an IO TLB but cannot use that + * in kdump case. See the comment in sba_init() in sba_iommu.c. + * + * So, the only machvec that really supports loading the kdump kernel + * over 4 GB is "sn2". + */ +static int __init check_crashkernel_memory(unsigned long pbase, size_t size) +{ + if (ia64_platform_is("sn2") || ia64_platform_is("uv")) + return 1; + else + return pbase < (1UL << 32); +} + static void __init setup_crashkernel(unsigned long total, int *n) { unsigned long long base = 0, size = 0; @@ -252,6 +271,16 @@ static void __init setup_crashkernel(unsigned long total, int *n) base = kdump_find_rsvd_region(size, rsvd_region, *n); } + + if (!check_crashkernel_memory(base, size)) { + pr_warning("crashkernel: There would be kdump memory " + "at %ld GB but this is unusable because it " + "must\nbe below 4 GB. Change the memory " + "configuration of the machine.\n", + (unsigned long)(base >> 30)); + return; + } + if (base != ~0UL) { printk(KERN_INFO "Reserving %ldMB of memory at %ldMB " "for crashkernel (System RAM: %ldMB)\n", diff --git a/arch/ia64/kvm/Makefile b/arch/ia64/kvm/Makefile index 52353397a1a4b94d36f167680ffffa7822ca326c..112791dd2542b19145155d4285669012fabe94ff 100644 --- a/arch/ia64/kvm/Makefile +++ b/arch/ia64/kvm/Makefile @@ -7,7 +7,6 @@ offsets-file := asm-offsets.h always := $(offsets-file) targets := $(offsets-file) targets += arch/ia64/kvm/asm-offsets.s -clean-files := $(addprefix $(objtree)/,$(targets) $(obj)/memcpy.S $(obj)/memset.S) # Default sed regexp - multiline due to syntax constraints define sed-y @@ -54,5 +53,5 @@ EXTRA_CFLAGS_vcpu.o += -mfixed-range=f2-f5,f12-f127 kvm-intel-objs = vmm.o vmm_ivt.o trampoline.o vcpu.o optvfault.o mmio.o \ vtlb.o process.o #Add link memcpy and memset to avoid possible structure assignment error -kvm-intel-objs += ../lib/memset.o ../lib/memcpy.o +kvm-intel-objs += memcpy.o memset.o obj-$(CONFIG_KVM_INTEL) += kvm-intel.o diff --git a/arch/ia64/kvm/memcpy.S b/arch/ia64/kvm/memcpy.S new file mode 100644 index 0000000000000000000000000000000000000000..c04cdbe9f80f923c2abd0c3f7e91ef4728d01009 --- /dev/null +++ b/arch/ia64/kvm/memcpy.S @@ -0,0 +1 @@ +#include "../lib/memcpy.S" diff --git a/arch/ia64/kvm/memset.S b/arch/ia64/kvm/memset.S new file mode 100644 index 0000000000000000000000000000000000000000..83c3066d844ab131997ad23b5c9bbaecd21cb819 --- /dev/null +++ b/arch/ia64/kvm/memset.S @@ -0,0 +1 @@ +#include "../lib/memset.S" diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index fc6c6636ffdac444b280e1cf4bc29fa140483ba5..200100ea7610883ae8fc90768a64ba185aa68d3c 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c @@ -719,3 +719,28 @@ out: EXPORT_SYMBOL_GPL(remove_memory); #endif /* CONFIG_MEMORY_HOTREMOVE */ #endif + +/* + * Even when CONFIG_IA32_SUPPORT is not enabled it is + * useful to have the Linux/x86 domain registered to + * avoid an attempted module load when emulators call + * personality(PER_LINUX32). This saves several milliseconds + * on each such call. + */ +static struct exec_domain ia32_exec_domain; + +static int __init +per_linux32_init(void) +{ + ia32_exec_domain.name = "Linux/x86"; + ia32_exec_domain.handler = NULL; + ia32_exec_domain.pers_low = PER_LINUX32; + ia32_exec_domain.pers_high = PER_LINUX32; + ia32_exec_domain.signal_map = default_exec_domain.signal_map; + ia32_exec_domain.signal_invmap = default_exec_domain.signal_invmap; + register_exec_domain(&ia32_exec_domain); + + return 0; +} + +__initcall(per_linux32_init); diff --git a/arch/ia64/uv/Makefile b/arch/ia64/uv/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..aa9f91947c492341aa039a68c98f26ae3f90ac66 --- /dev/null +++ b/arch/ia64/uv/Makefile @@ -0,0 +1,12 @@ +# arch/ia64/uv/Makefile +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. +# +# Copyright (C) 2008 Silicon Graphics, Inc. All Rights Reserved. +# +# Makefile for the sn uv subplatform +# + +obj-y += kernel/ diff --git a/arch/ia64/uv/kernel/Makefile b/arch/ia64/uv/kernel/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..8d92b4684d8e06714b06fbaacfcaec452c58a086 --- /dev/null +++ b/arch/ia64/uv/kernel/Makefile @@ -0,0 +1,13 @@ +# arch/ia64/uv/kernel/Makefile +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. +# +# Copyright (C) 2008 Silicon Graphics, Inc. All Rights Reserved. +# + +EXTRA_CFLAGS += -Iarch/ia64/sn/include + +obj-y += setup.o +obj-$(CONFIG_IA64_GENERIC) += machvec.o diff --git a/arch/ia64/uv/kernel/machvec.c b/arch/ia64/uv/kernel/machvec.c new file mode 100644 index 0000000000000000000000000000000000000000..50737a9dca7428a3157d973066408f8356b915f6 --- /dev/null +++ b/arch/ia64/uv/kernel/machvec.c @@ -0,0 +1,11 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved. + */ + +#define MACHVEC_PLATFORM_NAME uv +#define MACHVEC_PLATFORM_HEADER +#include diff --git a/arch/ia64/uv/kernel/setup.c b/arch/ia64/uv/kernel/setup.c new file mode 100644 index 0000000000000000000000000000000000000000..9aa743203c3c526ebbbe0a68c6b0ebccb6747ecb --- /dev/null +++ b/arch/ia64/uv/kernel/setup.c @@ -0,0 +1,98 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * SGI UV Core Functions + * + * Copyright (C) 2008 Silicon Graphics, Inc. All rights reserved. + */ + +#include +#include +#include +#include +#include + +DEFINE_PER_CPU(struct uv_hub_info_s, __uv_hub_info); +EXPORT_PER_CPU_SYMBOL_GPL(__uv_hub_info); + + +struct redir_addr { + unsigned long redirect; + unsigned long alias; +}; + +#define DEST_SHIFT UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR_DEST_BASE_SHFT + +static __initdata struct redir_addr redir_addrs[] = { + {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR, UVH_SI_ALIAS0_OVERLAY_CONFIG}, + {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR, UVH_SI_ALIAS1_OVERLAY_CONFIG}, + {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR, UVH_SI_ALIAS2_OVERLAY_CONFIG}, +}; + +static __init void get_lowmem_redirect(unsigned long *base, unsigned long *size) +{ + union uvh_si_alias0_overlay_config_u alias; + union uvh_rh_gam_alias210_redirect_config_2_mmr_u redirect; + int i; + + for (i = 0; i < ARRAY_SIZE(redir_addrs); i++) { + alias.v = uv_read_local_mmr(redir_addrs[i].alias); + if (alias.s.base == 0) { + *size = (1UL << alias.s.m_alias); + redirect.v = uv_read_local_mmr(redir_addrs[i].redirect); + *base = (unsigned long)redirect.s.dest_base << DEST_SHIFT; + return; + } + } + BUG(); +} + +void __init uv_setup(char **cmdline_p) +{ + union uvh_si_addr_map_config_u m_n_config; + union uvh_node_id_u node_id; + unsigned long gnode_upper; + int nid, cpu, m_val, n_val; + unsigned long mmr_base, lowmem_redir_base, lowmem_redir_size; + + if (IS_MEDUSA()) { + lowmem_redir_base = 0; + lowmem_redir_size = 0; + node_id.v = 0; + m_n_config.s.m_skt = 37; + m_n_config.s.n_skt = 0; + mmr_base = 0; + } else { + get_lowmem_redirect(&lowmem_redir_base, &lowmem_redir_size); + node_id.v = uv_read_local_mmr(UVH_NODE_ID); + m_n_config.v = uv_read_local_mmr(UVH_SI_ADDR_MAP_CONFIG); + mmr_base = + uv_read_local_mmr(UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR) & + ~UV_MMR_ENABLE; + } + + m_val = m_n_config.s.m_skt; + n_val = m_n_config.s.n_skt; + printk(KERN_DEBUG "UV: global MMR base 0x%lx\n", mmr_base); + + gnode_upper = (((unsigned long)node_id.s.node_id) & + ~((1 << n_val) - 1)) << m_val; + + for_each_present_cpu(cpu) { + nid = cpu_to_node(cpu); + uv_cpu_hub_info(cpu)->lowmem_remap_base = lowmem_redir_base; + uv_cpu_hub_info(cpu)->lowmem_remap_top = + lowmem_redir_base + lowmem_redir_size; + uv_cpu_hub_info(cpu)->m_val = m_val; + uv_cpu_hub_info(cpu)->n_val = m_val; + uv_cpu_hub_info(cpu)->pnode_mask = (1 << n_val) -1; + uv_cpu_hub_info(cpu)->gpa_mask = (1 << (m_val + n_val)) - 1; + uv_cpu_hub_info(cpu)->gnode_upper = gnode_upper; + uv_cpu_hub_info(cpu)->global_mmr_base = mmr_base; + uv_cpu_hub_info(cpu)->coherency_domain_number = 0;/* ZZZ */ + printk(KERN_DEBUG "UV cpu %d, nid %d\n", cpu, nid); + } +} + diff --git a/arch/m32r/kernel/init_task.c b/arch/m32r/kernel/init_task.c index 9e508fd9d970170d5f710401b90306f2355a913f..0d658dbb676693f13ef978ae07772951ba75a32c 100644 --- a/arch/m32r/kernel/init_task.c +++ b/arch/m32r/kernel/init_task.c @@ -12,7 +12,6 @@ #include static struct fs_struct init_fs = INIT_FS; -static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS(init_signals); static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); struct mm_struct init_mm = INIT_MM(init_mm); diff --git a/arch/m32r/kernel/sys_m32r.c b/arch/m32r/kernel/sys_m32r.c index 6d7a80fdad488676b8e69c43b0db180e68baf823..305ac852bbed417dda77de7a9b100c6a401bc75d 100644 --- a/arch/m32r/kernel/sys_m32r.c +++ b/arch/m32r/kernel/sys_m32r.c @@ -76,26 +76,6 @@ asmlinkage int sys_tas(int __user *addr) return oldval; } -/* - * sys_pipe() is the normal C calling standard for creating - * a pipe. It's not the way Unix traditionally does this, though. - */ -asmlinkage int -sys_pipe(unsigned long r0, unsigned long r1, unsigned long r2, - unsigned long r3, unsigned long r4, unsigned long r5, - unsigned long r6, struct pt_regs regs) -{ - int fd[2]; - int error; - - error = do_pipe(fd); - if (!error) { - if (copy_to_user((void __user *)r0, fd, 2*sizeof(int))) - error = -EFAULT; - } - return error; -} - asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long pgoff) diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index 65db2261b9ea5baa94d87a2042d690200cdcb874..55ea52fe6aca0a945328d8380f5b9672d583c7f8 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -44,7 +44,7 @@ config GENERIC_IOMAP config ARCH_MAY_HAVE_PC_FDC bool - depends on Q40 || (BROKEN && SUN3X) + depends on BROKEN && (Q40 || SUN3X) default y config NO_IOPORT @@ -539,13 +539,6 @@ config AMIGA_BUILTIN_SERIAL To compile this driver as a module, choose M here. -config WHIPPET_SERIAL - tristate "Hisoft Whippet PCMCIA serial support" - depends on AMIGA_PCMCIA - help - HiSoft has a web page at , but there - is no listing for the Whippet in their Amiga section. - config MULTIFACE_III_TTY tristate "Multiface Card III serial support" depends on AMIGA diff --git a/arch/m68k/configs/amiga_defconfig b/arch/m68k/configs/amiga_defconfig index e419583713679c1834fd83a3ad89221071a546b0..dca50da9ffd0a726cd20926b26d6fc18f3d73ebf 100644 --- a/arch/m68k/configs/amiga_defconfig +++ b/arch/m68k/configs/amiga_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.25-rc8 -# Wed Apr 2 20:46:06 2008 +# Linux kernel version: 2.6.26-rc2 +# Sun May 18 14:44:41 2008 # CONFIG_M68K=y CONFIG_MMU=y @@ -52,6 +52,7 @@ CONFIG_SYSCTL=y # CONFIG_EMBEDDED is not set CONFIG_UID16=y CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set CONFIG_HOTPLUG=y @@ -76,12 +77,14 @@ CONFIG_SLAB=y # CONFIG_HAVE_OPROFILE is not set # CONFIG_HAVE_KPROBES is not set # CONFIG_HAVE_KRETPROBES is not set +# CONFIG_HAVE_DMA_ATTRS is not set CONFIG_PROC_PAGE_MONITOR=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set @@ -141,6 +144,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_NEED_MULTIPLE_NODES=y # CONFIG_SPARSEMEM_STATIC is not set # CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 @@ -222,8 +226,10 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m CONFIG_INET6_XFRM_MODE_BEET=m CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m CONFIG_IPV6_SIT=m +CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=m # CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_MROUTE is not set # CONFIG_NETWORK_SECMARK is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set @@ -239,6 +245,7 @@ CONFIG_NF_CONNTRACK=m CONFIG_NF_CT_ACCT=y CONFIG_NF_CONNTRACK_MARK=y # CONFIG_NF_CONNTRACK_EVENTS is not set +# CONFIG_NF_CT_PROTO_DCCP is not set CONFIG_NF_CT_PROTO_GRE=m CONFIG_NF_CT_PROTO_SCTP=m CONFIG_NF_CT_PROTO_UDPLITE=m @@ -317,6 +324,8 @@ CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_NF_NAT_SNMP_BASIC=m CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_PROTO_UDPLITE=m +CONFIG_NF_NAT_PROTO_SCTP=m CONFIG_NF_NAT_FTP=m CONFIG_NF_NAT_IRC=m CONFIG_NF_NAT_TFTP=m @@ -410,8 +419,6 @@ CONFIG_IEEE80211=m CONFIG_IEEE80211_CRYPT_WEP=m CONFIG_IEEE80211_CRYPT_CCMP=m CONFIG_IEEE80211_CRYPT_TKIP=m -CONFIG_IEEE80211_SOFTMAC=m -# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -477,27 +484,12 @@ CONFIG_IDE_PROC_FS=y # # IDE chipset support/bugfixes # -# CONFIG_IDE_GENERIC is not set # CONFIG_BLK_DEV_PLATFORM is not set CONFIG_BLK_DEV_GAYLE=y CONFIG_BLK_DEV_IDEDOUBLER=y CONFIG_BLK_DEV_BUDDHA=y - -# -# Other IDE chipsets support -# - -# -# Note: most of these also require special kernel boot parameters -# -# CONFIG_BLK_DEV_4DRIVES is not set -# CONFIG_BLK_DEV_ALI14XX is not set -# CONFIG_BLK_DEV_DTC2278 is not set -# CONFIG_BLK_DEV_HT6560B is not set -# CONFIG_BLK_DEV_QD65XX is not set -# CONFIG_BLK_DEV_UMC8672 is not set # CONFIG_BLK_DEV_IDEDMA is not set -# CONFIG_IDE_ARCH_OBSOLETE_INIT is not set +# CONFIG_BLK_DEV_HD_ONLY is not set # CONFIG_BLK_DEV_HD is not set # @@ -626,6 +618,7 @@ CONFIG_APNE=m # # CONFIG_WLAN_PRE80211 is not set # CONFIG_WLAN_80211 is not set +# CONFIG_IWLWIFI_LEDS is not set # CONFIG_WAN is not set # CONFIG_PLIP is not set CONFIG_PPP=m @@ -707,6 +700,7 @@ CONFIG_INPUT_JOYSTICK=y # CONFIG_JOYSTICK_SPACEBALL is not set # CONFIG_JOYSTICK_STINGER is not set # CONFIG_JOYSTICK_TWIDJOY is not set +# CONFIG_JOYSTICK_ZHENHUA is not set # CONFIG_JOYSTICK_DB9 is not set # CONFIG_JOYSTICK_GAMECON is not set # CONFIG_JOYSTICK_TURBOGRAFX is not set @@ -731,6 +725,7 @@ CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_DEVKMEM is not set # CONFIG_SERIAL_NONSTANDARD is not set CONFIG_A2232=m @@ -757,12 +752,7 @@ CONFIG_GEN_RTC_X=y # CONFIG_RAW_DRIVER is not set # CONFIG_TCG_TPM is not set # CONFIG_I2C is not set - -# -# SPI support -# # CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set @@ -779,12 +769,22 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set # # Multimedia devices # + +# +# Multimedia core support +# # CONFIG_VIDEO_DEV is not set # CONFIG_DVB_CORE is not set +# CONFIG_VIDEO_MEDIA is not set + +# +# Multimedia drivers +# # CONFIG_DAB is not set # @@ -802,8 +802,8 @@ CONFIG_FB_CFB_IMAGEBLIT=y # CONFIG_FB_SYS_FILLRECT is not set # CONFIG_FB_SYS_COPYAREA is not set # CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set # CONFIG_FB_SYS_FOPS is not set -CONFIG_FB_DEFERRED_IO=y # CONFIG_FB_SVGALIB is not set # CONFIG_FB_MACMODES is not set # CONFIG_FB_BACKLIGHT is not set @@ -859,19 +859,15 @@ CONFIG_HIDRAW=y # CONFIG_MMC is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set # CONFIG_RTC_CLASS is not set # CONFIG_AUXDISPLAY is not set - -# -# Userspace I/O -# # CONFIG_UIO is not set # # Character devices # CONFIG_AMIGA_BUILTIN_SERIAL=y -# CONFIG_WHIPPET_SERIAL is not set CONFIG_MULTIFACE_III_TTY=m # CONFIG_SERIAL_CONSOLE is not set @@ -894,16 +890,15 @@ CONFIG_JFS_FS=m # CONFIG_JFS_SECURITY is not set # CONFIG_JFS_DEBUG is not set # CONFIG_JFS_STATISTICS is not set -CONFIG_FS_POSIX_ACL=y +# CONFIG_FS_POSIX_ACL is not set CONFIG_XFS_FS=m # CONFIG_XFS_QUOTA is not set -# CONFIG_XFS_SECURITY is not set # CONFIG_XFS_POSIX_ACL is not set # CONFIG_XFS_RT is not set -CONFIG_GFS2_FS=m -CONFIG_GFS2_FS_LOCKING_NOLOCK=m -CONFIG_GFS2_FS_LOCKING_DLM=m +# CONFIG_XFS_DEBUG is not set CONFIG_OCFS2_FS=m +CONFIG_OCFS2_FS_O2CB=m +CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set # CONFIG_OCFS2_DEBUG_FS is not set CONFIG_DNOTIFY=y @@ -975,12 +970,10 @@ CONFIG_NFS_FS=m CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set CONFIG_NFS_V4=y -# CONFIG_NFS_DIRECTIO is not set CONFIG_NFSD=m CONFIG_NFSD_V3=y # CONFIG_NFSD_V3_ACL is not set # CONFIG_NFSD_V4 is not set -CONFIG_NFSD_TCP=y CONFIG_LOCKD=m CONFIG_LOCKD_V4=y CONFIG_EXPORTFS=m @@ -1054,6 +1047,7 @@ CONFIG_DLM=m # CONFIG_PRINTK_TIME is not set CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set # CONFIG_DEBUG_FS is not set @@ -1073,53 +1067,82 @@ CONFIG_ASYNC_CORE=m CONFIG_ASYNC_MEMCPY=m CONFIG_ASYNC_XOR=m CONFIG_CRYPTO=y + +# +# Crypto core or helper +# CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_AEAD=m CONFIG_CRYPTO_BLKCIPHER=m -CONFIG_CRYPTO_SEQIV=m CONFIG_CRYPTO_HASH=y CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_TEST=m + +# +# Authenticated Encryption with Associated Data +# +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_SEQIV=m + +# +# Block modes +# +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_CTR=m +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_XTS=m + +# +# Hash modes +# CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_XCBC=m -CONFIG_CRYPTO_NULL=m + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=m CONFIG_CRYPTO_MD4=m CONFIG_CRYPTO_MD5=m +CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_SHA1=m CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m -CONFIG_CRYPTO_WP512=m CONFIG_CRYPTO_TGR192=m -CONFIG_CRYPTO_GF128MUL=m -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=m -CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_LRW=m -CONFIG_CRYPTO_XTS=m -CONFIG_CRYPTO_CTR=m -CONFIG_CRYPTO_GCM=m -CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_CRYPTD=m -CONFIG_CRYPTO_DES=m -CONFIG_CRYPTO_FCRYPT=m -CONFIG_CRYPTO_BLOWFISH=m -CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_TWOFISH_COMMON=m -CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_WP512=m + +# +# Ciphers +# CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m CONFIG_CRYPTO_CAST5=m CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_TEA=m -CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_FCRYPT=m CONFIG_CRYPTO_KHAZAD=m -CONFIG_CRYPTO_ANUBIS=m -CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SALSA20=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m + +# +# Compression +# CONFIG_CRYPTO_DEFLATE=m -CONFIG_CRYPTO_MICHAEL_MIC=m -CONFIG_CRYPTO_CRC32C=m -CONFIG_CRYPTO_CAMELLIA=m -CONFIG_CRYPTO_TEST=m -CONFIG_CRYPTO_AUTHENC=m CONFIG_CRYPTO_LZO=m # CONFIG_CRYPTO_HW is not set @@ -1127,9 +1150,11 @@ CONFIG_CRYPTO_LZO=m # Library routines # CONFIG_BITREVERSE=y +# CONFIG_GENERIC_FIND_FIRST_BIT is not set +# CONFIG_GENERIC_FIND_NEXT_BIT is not set CONFIG_CRC_CCITT=m CONFIG_CRC16=m -# CONFIG_CRC_ITU_T is not set +CONFIG_CRC_ITU_T=m CONFIG_CRC32=y # CONFIG_CRC7 is not set CONFIG_LIBCRC32C=m diff --git a/arch/m68k/configs/apollo_defconfig b/arch/m68k/configs/apollo_defconfig index e61196cd7fa540f8775c4cb2dfcf37d2bd52fcbe..c3cd5b749d2cb94290fb1159fd1fd68467422744 100644 --- a/arch/m68k/configs/apollo_defconfig +++ b/arch/m68k/configs/apollo_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.25-rc8 -# Wed Apr 2 20:46:07 2008 +# Linux kernel version: 2.6.26-rc2 +# Sun May 18 14:44:42 2008 # CONFIG_M68K=y CONFIG_MMU=y @@ -52,6 +52,7 @@ CONFIG_SYSCTL=y # CONFIG_EMBEDDED is not set CONFIG_UID16=y CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set CONFIG_HOTPLUG=y @@ -76,12 +77,14 @@ CONFIG_SLAB=y # CONFIG_HAVE_OPROFILE is not set # CONFIG_HAVE_KPROBES is not set # CONFIG_HAVE_KRETPROBES is not set +# CONFIG_HAVE_DMA_ATTRS is not set CONFIG_PROC_PAGE_MONITOR=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set @@ -141,6 +144,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_NEED_MULTIPLE_NODES=y # CONFIG_SPARSEMEM_STATIC is not set # CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 @@ -220,8 +224,10 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m CONFIG_INET6_XFRM_MODE_BEET=m CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m CONFIG_IPV6_SIT=m +CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=m # CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_MROUTE is not set # CONFIG_NETWORK_SECMARK is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set @@ -237,6 +243,7 @@ CONFIG_NF_CONNTRACK=m CONFIG_NF_CT_ACCT=y CONFIG_NF_CONNTRACK_MARK=y # CONFIG_NF_CONNTRACK_EVENTS is not set +# CONFIG_NF_CT_PROTO_DCCP is not set CONFIG_NF_CT_PROTO_GRE=m CONFIG_NF_CT_PROTO_SCTP=m CONFIG_NF_CT_PROTO_UDPLITE=m @@ -315,6 +322,8 @@ CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_NF_NAT_SNMP_BASIC=m CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_PROTO_UDPLITE=m +CONFIG_NF_NAT_PROTO_SCTP=m CONFIG_NF_NAT_FTP=m CONFIG_NF_NAT_IRC=m CONFIG_NF_NAT_TFTP=m @@ -408,8 +417,6 @@ CONFIG_IEEE80211=m CONFIG_IEEE80211_CRYPT_WEP=m CONFIG_IEEE80211_CRYPT_CCMP=m CONFIG_IEEE80211_CRYPT_TKIP=m -CONFIG_IEEE80211_SOFTMAC=m -# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -539,6 +546,7 @@ CONFIG_APOLLO_ELPLUS=y # # CONFIG_WLAN_PRE80211 is not set # CONFIG_WLAN_80211 is not set +# CONFIG_IWLWIFI_LEDS is not set # CONFIG_WAN is not set CONFIG_PPP=m # CONFIG_PPP_MULTILINK is not set @@ -622,6 +630,7 @@ CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_DEVKMEM is not set # CONFIG_SERIAL_NONSTANDARD is not set # @@ -643,12 +652,7 @@ CONFIG_GEN_RTC_X=y # CONFIG_RAW_DRIVER is not set # CONFIG_TCG_TPM is not set # CONFIG_I2C is not set - -# -# SPI support -# # CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set @@ -665,12 +669,22 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set # # Multimedia devices # + +# +# Multimedia core support +# # CONFIG_VIDEO_DEV is not set # CONFIG_DVB_CORE is not set +# CONFIG_VIDEO_MEDIA is not set + +# +# Multimedia drivers +# # CONFIG_DAB is not set # @@ -688,8 +702,8 @@ CONFIG_FB_CFB_IMAGEBLIT=y # CONFIG_FB_SYS_FILLRECT is not set # CONFIG_FB_SYS_COPYAREA is not set # CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set # CONFIG_FB_SYS_FOPS is not set -CONFIG_FB_DEFERRED_IO=y # CONFIG_FB_SVGALIB is not set # CONFIG_FB_MACMODES is not set # CONFIG_FB_BACKLIGHT is not set @@ -737,11 +751,8 @@ CONFIG_HIDRAW=y # CONFIG_MMC is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set # CONFIG_RTC_CLASS is not set - -# -# Userspace I/O -# # CONFIG_UIO is not set # @@ -769,16 +780,15 @@ CONFIG_JFS_FS=m # CONFIG_JFS_SECURITY is not set # CONFIG_JFS_DEBUG is not set # CONFIG_JFS_STATISTICS is not set -CONFIG_FS_POSIX_ACL=y +# CONFIG_FS_POSIX_ACL is not set CONFIG_XFS_FS=m # CONFIG_XFS_QUOTA is not set -# CONFIG_XFS_SECURITY is not set # CONFIG_XFS_POSIX_ACL is not set # CONFIG_XFS_RT is not set -CONFIG_GFS2_FS=m -CONFIG_GFS2_FS_LOCKING_NOLOCK=m -CONFIG_GFS2_FS_LOCKING_DLM=m +# CONFIG_XFS_DEBUG is not set CONFIG_OCFS2_FS=m +CONFIG_OCFS2_FS_O2CB=m +CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set # CONFIG_OCFS2_DEBUG_FS is not set CONFIG_DNOTIFY=y @@ -850,12 +860,10 @@ CONFIG_NFS_FS=y CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set CONFIG_NFS_V4=y -# CONFIG_NFS_DIRECTIO is not set CONFIG_NFSD=m CONFIG_NFSD_V3=y # CONFIG_NFSD_V3_ACL is not set # CONFIG_NFSD_V4 is not set -CONFIG_NFSD_TCP=y CONFIG_ROOT_NFS=y CONFIG_LOCKD=y CONFIG_LOCKD_V4=y @@ -929,6 +937,7 @@ CONFIG_DLM=m # CONFIG_PRINTK_TIME is not set CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set # CONFIG_DEBUG_FS is not set @@ -948,53 +957,82 @@ CONFIG_ASYNC_CORE=m CONFIG_ASYNC_MEMCPY=m CONFIG_ASYNC_XOR=m CONFIG_CRYPTO=y + +# +# Crypto core or helper +# CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_AEAD=m CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_SEQIV=m CONFIG_CRYPTO_HASH=y CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_TEST=m + +# +# Authenticated Encryption with Associated Data +# +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_SEQIV=m + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_CTR=m +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_XTS=m + +# +# Hash modes +# CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_XCBC=m -CONFIG_CRYPTO_NULL=m + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=m CONFIG_CRYPTO_MD4=m CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_SHA1=m CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m -CONFIG_CRYPTO_WP512=m CONFIG_CRYPTO_TGR192=m -CONFIG_CRYPTO_GF128MUL=m -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=y -CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_LRW=m -CONFIG_CRYPTO_XTS=m -CONFIG_CRYPTO_CTR=m -CONFIG_CRYPTO_GCM=m -CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_CRYPTD=m -CONFIG_CRYPTO_DES=y -CONFIG_CRYPTO_FCRYPT=m -CONFIG_CRYPTO_BLOWFISH=m -CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_TWOFISH_COMMON=m -CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_WP512=m + +# +# Ciphers +# CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m CONFIG_CRYPTO_CAST5=m CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_TEA=m -CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_FCRYPT=m CONFIG_CRYPTO_KHAZAD=m -CONFIG_CRYPTO_ANUBIS=m -CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SALSA20=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m + +# +# Compression +# CONFIG_CRYPTO_DEFLATE=m -CONFIG_CRYPTO_MICHAEL_MIC=m -CONFIG_CRYPTO_CRC32C=m -CONFIG_CRYPTO_CAMELLIA=m -CONFIG_CRYPTO_TEST=m -CONFIG_CRYPTO_AUTHENC=m CONFIG_CRYPTO_LZO=m # CONFIG_CRYPTO_HW is not set @@ -1002,9 +1040,11 @@ CONFIG_CRYPTO_LZO=m # Library routines # CONFIG_BITREVERSE=y +# CONFIG_GENERIC_FIND_FIRST_BIT is not set +# CONFIG_GENERIC_FIND_NEXT_BIT is not set CONFIG_CRC_CCITT=m CONFIG_CRC16=m -# CONFIG_CRC_ITU_T is not set +CONFIG_CRC_ITU_T=m CONFIG_CRC32=y # CONFIG_CRC7 is not set CONFIG_LIBCRC32C=m diff --git a/arch/m68k/configs/atari_defconfig b/arch/m68k/configs/atari_defconfig index ba7f971bb026a46a9ec6257089119f2f1e859014..073ae4bbe2646c8161568a2f75908a1bd844c0ac 100644 --- a/arch/m68k/configs/atari_defconfig +++ b/arch/m68k/configs/atari_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.25-rc8 -# Wed Apr 2 20:46:09 2008 +# Linux kernel version: 2.6.26-rc2 +# Sun May 18 14:44:43 2008 # CONFIG_M68K=y CONFIG_MMU=y @@ -52,6 +52,7 @@ CONFIG_SYSCTL=y # CONFIG_EMBEDDED is not set CONFIG_UID16=y CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set CONFIG_HOTPLUG=y @@ -76,12 +77,14 @@ CONFIG_SLAB=y # CONFIG_HAVE_OPROFILE is not set # CONFIG_HAVE_KPROBES is not set # CONFIG_HAVE_KRETPROBES is not set +# CONFIG_HAVE_DMA_ATTRS is not set CONFIG_PROC_PAGE_MONITOR=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set @@ -141,6 +144,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_NEED_MULTIPLE_NODES=y # CONFIG_SPARSEMEM_STATIC is not set # CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 @@ -218,8 +222,10 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m CONFIG_INET6_XFRM_MODE_BEET=m CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m CONFIG_IPV6_SIT=m +CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=m # CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_MROUTE is not set # CONFIG_NETWORK_SECMARK is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set @@ -235,6 +241,7 @@ CONFIG_NF_CONNTRACK=m CONFIG_NF_CT_ACCT=y CONFIG_NF_CONNTRACK_MARK=y # CONFIG_NF_CONNTRACK_EVENTS is not set +# CONFIG_NF_CT_PROTO_DCCP is not set CONFIG_NF_CT_PROTO_GRE=m CONFIG_NF_CT_PROTO_SCTP=m CONFIG_NF_CT_PROTO_UDPLITE=m @@ -313,6 +320,8 @@ CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_NF_NAT_SNMP_BASIC=m CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_PROTO_UDPLITE=m +CONFIG_NF_NAT_PROTO_SCTP=m CONFIG_NF_NAT_FTP=m CONFIG_NF_NAT_IRC=m CONFIG_NF_NAT_TFTP=m @@ -406,8 +415,6 @@ CONFIG_IEEE80211=m CONFIG_IEEE80211_CRYPT_WEP=m CONFIG_IEEE80211_CRYPT_CCMP=m CONFIG_IEEE80211_CRYPT_TKIP=m -CONFIG_IEEE80211_SOFTMAC=m -# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -469,11 +476,10 @@ CONFIG_IDE_PROC_FS=y # # IDE chipset support/bugfixes # -# CONFIG_IDE_GENERIC is not set # CONFIG_BLK_DEV_PLATFORM is not set CONFIG_BLK_DEV_FALCON_IDE=y # CONFIG_BLK_DEV_IDEDMA is not set -# CONFIG_IDE_ARCH_OBSOLETE_INIT is not set +# CONFIG_BLK_DEV_HD_ONLY is not set # CONFIG_BLK_DEV_HD is not set # @@ -572,6 +578,7 @@ CONFIG_ATARILANCE=m # # CONFIG_WLAN_PRE80211 is not set # CONFIG_WLAN_80211 is not set +# CONFIG_IWLWIFI_LEDS is not set # CONFIG_WAN is not set # CONFIG_PLIP is not set CONFIG_PPP=m @@ -662,6 +669,7 @@ CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_DEVKMEM is not set # CONFIG_SERIAL_NONSTANDARD is not set # @@ -687,12 +695,7 @@ CONFIG_GEN_RTC_X=y # CONFIG_RAW_DRIVER is not set # CONFIG_TCG_TPM is not set # CONFIG_I2C is not set - -# -# SPI support -# # CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set @@ -709,12 +712,22 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set # # Multimedia devices # + +# +# Multimedia core support +# # CONFIG_VIDEO_DEV is not set # CONFIG_DVB_CORE is not set +# CONFIG_VIDEO_MEDIA is not set + +# +# Multimedia drivers +# # CONFIG_DAB is not set # @@ -732,8 +745,8 @@ CONFIG_FB_CFB_IMAGEBLIT=y # CONFIG_FB_SYS_FILLRECT is not set # CONFIG_FB_SYS_COPYAREA is not set # CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set # CONFIG_FB_SYS_FOPS is not set -CONFIG_FB_DEFERRED_IO=y # CONFIG_FB_SVGALIB is not set # CONFIG_FB_MACMODES is not set # CONFIG_FB_BACKLIGHT is not set @@ -784,12 +797,9 @@ CONFIG_HIDRAW=y # CONFIG_MMC is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set # CONFIG_RTC_CLASS is not set # CONFIG_AUXDISPLAY is not set - -# -# Userspace I/O -# # CONFIG_UIO is not set # @@ -821,16 +831,15 @@ CONFIG_JFS_FS=m # CONFIG_JFS_SECURITY is not set # CONFIG_JFS_DEBUG is not set # CONFIG_JFS_STATISTICS is not set -CONFIG_FS_POSIX_ACL=y +# CONFIG_FS_POSIX_ACL is not set CONFIG_XFS_FS=m # CONFIG_XFS_QUOTA is not set -# CONFIG_XFS_SECURITY is not set # CONFIG_XFS_POSIX_ACL is not set # CONFIG_XFS_RT is not set -CONFIG_GFS2_FS=m -CONFIG_GFS2_FS_LOCKING_NOLOCK=m -CONFIG_GFS2_FS_LOCKING_DLM=m +# CONFIG_XFS_DEBUG is not set CONFIG_OCFS2_FS=m +CONFIG_OCFS2_FS_O2CB=m +CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set # CONFIG_OCFS2_DEBUG_FS is not set CONFIG_DNOTIFY=y @@ -902,12 +911,10 @@ CONFIG_NFS_FS=m CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set # CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set CONFIG_NFSD=m CONFIG_NFSD_V3=y # CONFIG_NFSD_V3_ACL is not set # CONFIG_NFSD_V4 is not set -CONFIG_NFSD_TCP=y CONFIG_LOCKD=m CONFIG_LOCKD_V4=y CONFIG_EXPORTFS=m @@ -980,6 +987,7 @@ CONFIG_DLM=m # CONFIG_PRINTK_TIME is not set CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set # CONFIG_DEBUG_FS is not set @@ -999,53 +1007,82 @@ CONFIG_ASYNC_CORE=m CONFIG_ASYNC_MEMCPY=m CONFIG_ASYNC_XOR=m CONFIG_CRYPTO=y + +# +# Crypto core or helper +# CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_AEAD=m CONFIG_CRYPTO_BLKCIPHER=m -CONFIG_CRYPTO_SEQIV=m CONFIG_CRYPTO_HASH=y CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_TEST=m + +# +# Authenticated Encryption with Associated Data +# +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_SEQIV=m + +# +# Block modes +# +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_CTR=m +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_XTS=m + +# +# Hash modes +# CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_XCBC=m -CONFIG_CRYPTO_NULL=m + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=m CONFIG_CRYPTO_MD4=m CONFIG_CRYPTO_MD5=m +CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_SHA1=m CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m -CONFIG_CRYPTO_WP512=m CONFIG_CRYPTO_TGR192=m -CONFIG_CRYPTO_GF128MUL=m -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=m -CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_LRW=m -CONFIG_CRYPTO_XTS=m -CONFIG_CRYPTO_CTR=m -CONFIG_CRYPTO_GCM=m -CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_CRYPTD=m -CONFIG_CRYPTO_DES=m -CONFIG_CRYPTO_FCRYPT=m -CONFIG_CRYPTO_BLOWFISH=m -CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_TWOFISH_COMMON=m -CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_WP512=m + +# +# Ciphers +# CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m CONFIG_CRYPTO_CAST5=m CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_TEA=m -CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_FCRYPT=m CONFIG_CRYPTO_KHAZAD=m -CONFIG_CRYPTO_ANUBIS=m -CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SALSA20=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m + +# +# Compression +# CONFIG_CRYPTO_DEFLATE=m -CONFIG_CRYPTO_MICHAEL_MIC=m -CONFIG_CRYPTO_CRC32C=m -CONFIG_CRYPTO_CAMELLIA=m -CONFIG_CRYPTO_TEST=m -CONFIG_CRYPTO_AUTHENC=m CONFIG_CRYPTO_LZO=m # CONFIG_CRYPTO_HW is not set @@ -1053,9 +1090,11 @@ CONFIG_CRYPTO_LZO=m # Library routines # CONFIG_BITREVERSE=y +# CONFIG_GENERIC_FIND_FIRST_BIT is not set +# CONFIG_GENERIC_FIND_NEXT_BIT is not set CONFIG_CRC_CCITT=m CONFIG_CRC16=y -# CONFIG_CRC_ITU_T is not set +CONFIG_CRC_ITU_T=m CONFIG_CRC32=y # CONFIG_CRC7 is not set CONFIG_LIBCRC32C=m diff --git a/arch/m68k/configs/bvme6000_defconfig b/arch/m68k/configs/bvme6000_defconfig index ed98eff708c44c5468c16303b765936d2ed79eff..0789ede2e9eee3875675437400f6e497e6606c7d 100644 --- a/arch/m68k/configs/bvme6000_defconfig +++ b/arch/m68k/configs/bvme6000_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.25-rc8 -# Wed Apr 2 20:46:10 2008 +# Linux kernel version: 2.6.26-rc2 +# Sun May 18 14:44:45 2008 # CONFIG_M68K=y CONFIG_MMU=y @@ -52,6 +52,7 @@ CONFIG_SYSCTL=y # CONFIG_EMBEDDED is not set CONFIG_UID16=y CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set CONFIG_HOTPLUG=y @@ -76,12 +77,14 @@ CONFIG_SLAB=y # CONFIG_HAVE_OPROFILE is not set # CONFIG_HAVE_KPROBES is not set # CONFIG_HAVE_KRETPROBES is not set +# CONFIG_HAVE_DMA_ATTRS is not set CONFIG_PROC_PAGE_MONITOR=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set @@ -144,6 +147,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_NEED_MULTIPLE_NODES=y # CONFIG_SPARSEMEM_STATIC is not set # CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 @@ -222,8 +226,10 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m CONFIG_INET6_XFRM_MODE_BEET=m CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m CONFIG_IPV6_SIT=m +CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=m # CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_MROUTE is not set # CONFIG_NETWORK_SECMARK is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set @@ -239,6 +245,7 @@ CONFIG_NF_CONNTRACK=m CONFIG_NF_CT_ACCT=y CONFIG_NF_CONNTRACK_MARK=y # CONFIG_NF_CONNTRACK_EVENTS is not set +# CONFIG_NF_CT_PROTO_DCCP is not set CONFIG_NF_CT_PROTO_GRE=m CONFIG_NF_CT_PROTO_SCTP=m CONFIG_NF_CT_PROTO_UDPLITE=m @@ -317,6 +324,8 @@ CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_NF_NAT_SNMP_BASIC=m CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_PROTO_UDPLITE=m +CONFIG_NF_NAT_PROTO_SCTP=m CONFIG_NF_NAT_FTP=m CONFIG_NF_NAT_IRC=m CONFIG_NF_NAT_TFTP=m @@ -410,8 +419,6 @@ CONFIG_IEEE80211=m CONFIG_IEEE80211_CRYPT_WEP=m CONFIG_IEEE80211_CRYPT_CCMP=m CONFIG_IEEE80211_CRYPT_TKIP=m -CONFIG_IEEE80211_SOFTMAC=m -# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -543,6 +550,7 @@ CONFIG_BVME6000_NET=y # # CONFIG_WLAN_PRE80211 is not set # CONFIG_WLAN_80211 is not set +# CONFIG_IWLWIFI_LEDS is not set # CONFIG_WAN is not set CONFIG_PPP=m # CONFIG_PPP_MULTILINK is not set @@ -626,6 +634,7 @@ CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_DEVKMEM is not set # CONFIG_SERIAL_NONSTANDARD is not set # @@ -647,12 +656,7 @@ CONFIG_GEN_RTC_X=y # CONFIG_RAW_DRIVER is not set # CONFIG_TCG_TPM is not set # CONFIG_I2C is not set - -# -# SPI support -# # CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set @@ -669,12 +673,22 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set # # Multimedia devices # + +# +# Multimedia core support +# # CONFIG_VIDEO_DEV is not set # CONFIG_DVB_CORE is not set +# CONFIG_VIDEO_MEDIA is not set + +# +# Multimedia drivers +# # CONFIG_DAB is not set # @@ -707,11 +721,8 @@ CONFIG_HIDRAW=y # CONFIG_MMC is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set # CONFIG_RTC_CLASS is not set - -# -# Userspace I/O -# # CONFIG_UIO is not set # @@ -739,16 +750,15 @@ CONFIG_JFS_FS=m # CONFIG_JFS_SECURITY is not set # CONFIG_JFS_DEBUG is not set # CONFIG_JFS_STATISTICS is not set -CONFIG_FS_POSIX_ACL=y +# CONFIG_FS_POSIX_ACL is not set CONFIG_XFS_FS=m # CONFIG_XFS_QUOTA is not set -# CONFIG_XFS_SECURITY is not set # CONFIG_XFS_POSIX_ACL is not set # CONFIG_XFS_RT is not set -CONFIG_GFS2_FS=m -CONFIG_GFS2_FS_LOCKING_NOLOCK=m -CONFIG_GFS2_FS_LOCKING_DLM=m +# CONFIG_XFS_DEBUG is not set CONFIG_OCFS2_FS=m +CONFIG_OCFS2_FS_O2CB=m +CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set # CONFIG_OCFS2_DEBUG_FS is not set CONFIG_DNOTIFY=y @@ -820,12 +830,10 @@ CONFIG_NFS_FS=y CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set CONFIG_NFS_V4=y -# CONFIG_NFS_DIRECTIO is not set CONFIG_NFSD=m CONFIG_NFSD_V3=y # CONFIG_NFSD_V3_ACL is not set # CONFIG_NFSD_V4 is not set -CONFIG_NFSD_TCP=y CONFIG_ROOT_NFS=y CONFIG_LOCKD=y CONFIG_LOCKD_V4=y @@ -900,6 +908,7 @@ CONFIG_DLM=m # CONFIG_PRINTK_TIME is not set CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set # CONFIG_DEBUG_FS is not set @@ -919,53 +928,82 @@ CONFIG_ASYNC_CORE=m CONFIG_ASYNC_MEMCPY=m CONFIG_ASYNC_XOR=m CONFIG_CRYPTO=y + +# +# Crypto core or helper +# CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_AEAD=m CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_SEQIV=m CONFIG_CRYPTO_HASH=y CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_TEST=m + +# +# Authenticated Encryption with Associated Data +# +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_SEQIV=m + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_CTR=m +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_XTS=m + +# +# Hash modes +# CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_XCBC=m -CONFIG_CRYPTO_NULL=m + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=m CONFIG_CRYPTO_MD4=m CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_SHA1=m CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m -CONFIG_CRYPTO_WP512=m CONFIG_CRYPTO_TGR192=m -CONFIG_CRYPTO_GF128MUL=m -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=y -CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_LRW=m -CONFIG_CRYPTO_XTS=m -CONFIG_CRYPTO_CTR=m -CONFIG_CRYPTO_GCM=m -CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_CRYPTD=m -CONFIG_CRYPTO_DES=y -CONFIG_CRYPTO_FCRYPT=m -CONFIG_CRYPTO_BLOWFISH=m -CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_TWOFISH_COMMON=m -CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_WP512=m + +# +# Ciphers +# CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m CONFIG_CRYPTO_CAST5=m CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_TEA=m -CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_FCRYPT=m CONFIG_CRYPTO_KHAZAD=m -CONFIG_CRYPTO_ANUBIS=m -CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SALSA20=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m + +# +# Compression +# CONFIG_CRYPTO_DEFLATE=m -CONFIG_CRYPTO_MICHAEL_MIC=m -CONFIG_CRYPTO_CRC32C=m -CONFIG_CRYPTO_CAMELLIA=m -CONFIG_CRYPTO_TEST=m -CONFIG_CRYPTO_AUTHENC=m CONFIG_CRYPTO_LZO=m # CONFIG_CRYPTO_HW is not set @@ -973,9 +1011,11 @@ CONFIG_CRYPTO_LZO=m # Library routines # CONFIG_BITREVERSE=m +# CONFIG_GENERIC_FIND_FIRST_BIT is not set +# CONFIG_GENERIC_FIND_NEXT_BIT is not set CONFIG_CRC_CCITT=m CONFIG_CRC16=m -# CONFIG_CRC_ITU_T is not set +CONFIG_CRC_ITU_T=m CONFIG_CRC32=m # CONFIG_CRC7 is not set CONFIG_LIBCRC32C=m diff --git a/arch/m68k/configs/hp300_defconfig b/arch/m68k/configs/hp300_defconfig index 38b68c70e567ee3544259bccf98336ac533b4084..3e140bf49b2223854342edfe8b6dc759a0e14ae7 100644 --- a/arch/m68k/configs/hp300_defconfig +++ b/arch/m68k/configs/hp300_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.25-rc8 -# Wed Apr 2 20:46:12 2008 +# Linux kernel version: 2.6.26-rc2 +# Sun May 18 14:44:46 2008 # CONFIG_M68K=y CONFIG_MMU=y @@ -52,6 +52,7 @@ CONFIG_SYSCTL=y # CONFIG_EMBEDDED is not set CONFIG_UID16=y CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set CONFIG_HOTPLUG=y @@ -76,12 +77,14 @@ CONFIG_SLAB=y # CONFIG_HAVE_OPROFILE is not set # CONFIG_HAVE_KPROBES is not set # CONFIG_HAVE_KRETPROBES is not set +# CONFIG_HAVE_DMA_ATTRS is not set CONFIG_PROC_PAGE_MONITOR=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set @@ -142,6 +145,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_NEED_MULTIPLE_NODES=y # CONFIG_SPARSEMEM_STATIC is not set # CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 @@ -221,8 +225,10 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m CONFIG_INET6_XFRM_MODE_BEET=m CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m CONFIG_IPV6_SIT=m +CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=m # CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_MROUTE is not set # CONFIG_NETWORK_SECMARK is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set @@ -238,6 +244,7 @@ CONFIG_NF_CONNTRACK=m CONFIG_NF_CT_ACCT=y CONFIG_NF_CONNTRACK_MARK=y # CONFIG_NF_CONNTRACK_EVENTS is not set +# CONFIG_NF_CT_PROTO_DCCP is not set CONFIG_NF_CT_PROTO_GRE=m CONFIG_NF_CT_PROTO_SCTP=m CONFIG_NF_CT_PROTO_UDPLITE=m @@ -316,6 +323,8 @@ CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_NF_NAT_SNMP_BASIC=m CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_PROTO_UDPLITE=m +CONFIG_NF_NAT_PROTO_SCTP=m CONFIG_NF_NAT_FTP=m CONFIG_NF_NAT_IRC=m CONFIG_NF_NAT_TFTP=m @@ -409,8 +418,6 @@ CONFIG_IEEE80211=m CONFIG_IEEE80211_CRYPT_WEP=m CONFIG_IEEE80211_CRYPT_CCMP=m CONFIG_IEEE80211_CRYPT_TKIP=m -CONFIG_IEEE80211_SOFTMAC=m -# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -540,6 +547,7 @@ CONFIG_HPLANCE=y # # CONFIG_WLAN_PRE80211 is not set # CONFIG_WLAN_80211 is not set +# CONFIG_IWLWIFI_LEDS is not set # CONFIG_WAN is not set CONFIG_PPP=m # CONFIG_PPP_MULTILINK is not set @@ -631,6 +639,7 @@ CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_DEVKMEM is not set # CONFIG_SERIAL_NONSTANDARD is not set # @@ -652,12 +661,7 @@ CONFIG_GEN_RTC_X=y # CONFIG_RAW_DRIVER is not set # CONFIG_TCG_TPM is not set # CONFIG_I2C is not set - -# -# SPI support -# # CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set @@ -674,12 +678,22 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set # # Multimedia devices # + +# +# Multimedia core support +# # CONFIG_VIDEO_DEV is not set # CONFIG_DVB_CORE is not set +# CONFIG_VIDEO_MEDIA is not set + +# +# Multimedia drivers +# # CONFIG_DAB is not set # @@ -690,15 +704,15 @@ CONFIG_SSB_POSSIBLE=y CONFIG_FB=y # CONFIG_FIRMWARE_EDID is not set # CONFIG_FB_DDC is not set -CONFIG_FB_CFB_FILLRECT=y +# CONFIG_FB_CFB_FILLRECT is not set # CONFIG_FB_CFB_COPYAREA is not set CONFIG_FB_CFB_IMAGEBLIT=y # CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set # CONFIG_FB_SYS_FILLRECT is not set # CONFIG_FB_SYS_COPYAREA is not set # CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set # CONFIG_FB_SYS_FOPS is not set -CONFIG_FB_DEFERRED_IO=y # CONFIG_FB_SVGALIB is not set # CONFIG_FB_MACMODES is not set # CONFIG_FB_BACKLIGHT is not set @@ -746,11 +760,8 @@ CONFIG_HIDRAW=y # CONFIG_MMC is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set # CONFIG_RTC_CLASS is not set - -# -# Userspace I/O -# # CONFIG_UIO is not set # @@ -776,16 +787,15 @@ CONFIG_JFS_FS=m # CONFIG_JFS_SECURITY is not set # CONFIG_JFS_DEBUG is not set # CONFIG_JFS_STATISTICS is not set -CONFIG_FS_POSIX_ACL=y +# CONFIG_FS_POSIX_ACL is not set CONFIG_XFS_FS=m # CONFIG_XFS_QUOTA is not set -# CONFIG_XFS_SECURITY is not set # CONFIG_XFS_POSIX_ACL is not set # CONFIG_XFS_RT is not set -CONFIG_GFS2_FS=m -CONFIG_GFS2_FS_LOCKING_NOLOCK=m -CONFIG_GFS2_FS_LOCKING_DLM=m +# CONFIG_XFS_DEBUG is not set CONFIG_OCFS2_FS=m +CONFIG_OCFS2_FS_O2CB=m +CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set # CONFIG_OCFS2_DEBUG_FS is not set CONFIG_DNOTIFY=y @@ -857,12 +867,10 @@ CONFIG_NFS_FS=y CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set CONFIG_NFS_V4=y -# CONFIG_NFS_DIRECTIO is not set CONFIG_NFSD=m CONFIG_NFSD_V3=y # CONFIG_NFSD_V3_ACL is not set # CONFIG_NFSD_V4 is not set -CONFIG_NFSD_TCP=y CONFIG_ROOT_NFS=y CONFIG_LOCKD=y CONFIG_LOCKD_V4=y @@ -936,6 +944,7 @@ CONFIG_DLM=m # CONFIG_PRINTK_TIME is not set CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set # CONFIG_DEBUG_FS is not set @@ -955,53 +964,82 @@ CONFIG_ASYNC_CORE=m CONFIG_ASYNC_MEMCPY=m CONFIG_ASYNC_XOR=m CONFIG_CRYPTO=y + +# +# Crypto core or helper +# CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_AEAD=m CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_SEQIV=m CONFIG_CRYPTO_HASH=y CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_TEST=m + +# +# Authenticated Encryption with Associated Data +# +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_SEQIV=m + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_CTR=m +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_XTS=m + +# +# Hash modes +# CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_XCBC=m -CONFIG_CRYPTO_NULL=m + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=m CONFIG_CRYPTO_MD4=m CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_SHA1=m CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m -CONFIG_CRYPTO_WP512=m CONFIG_CRYPTO_TGR192=m -CONFIG_CRYPTO_GF128MUL=m -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=y -CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_LRW=m -CONFIG_CRYPTO_XTS=m -CONFIG_CRYPTO_CTR=m -CONFIG_CRYPTO_GCM=m -CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_CRYPTD=m -CONFIG_CRYPTO_DES=y -CONFIG_CRYPTO_FCRYPT=m -CONFIG_CRYPTO_BLOWFISH=m -CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_TWOFISH_COMMON=m -CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_WP512=m + +# +# Ciphers +# CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m CONFIG_CRYPTO_CAST5=m CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_TEA=m -CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_FCRYPT=m CONFIG_CRYPTO_KHAZAD=m -CONFIG_CRYPTO_ANUBIS=m -CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SALSA20=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m + +# +# Compression +# CONFIG_CRYPTO_DEFLATE=m -CONFIG_CRYPTO_MICHAEL_MIC=m -CONFIG_CRYPTO_CRC32C=m -CONFIG_CRYPTO_CAMELLIA=m -CONFIG_CRYPTO_TEST=m -CONFIG_CRYPTO_AUTHENC=m CONFIG_CRYPTO_LZO=m # CONFIG_CRYPTO_HW is not set @@ -1009,9 +1047,11 @@ CONFIG_CRYPTO_LZO=m # Library routines # CONFIG_BITREVERSE=y +# CONFIG_GENERIC_FIND_FIRST_BIT is not set +# CONFIG_GENERIC_FIND_NEXT_BIT is not set CONFIG_CRC_CCITT=m CONFIG_CRC16=m -# CONFIG_CRC_ITU_T is not set +CONFIG_CRC_ITU_T=m CONFIG_CRC32=y # CONFIG_CRC7 is not set CONFIG_LIBCRC32C=m diff --git a/arch/m68k/configs/mac_defconfig b/arch/m68k/configs/mac_defconfig index 738bca695a8851636e52846e941ca18549635cb1..ba3a91792cbf93a50a0d72611524f35d99c62c33 100644 --- a/arch/m68k/configs/mac_defconfig +++ b/arch/m68k/configs/mac_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.25-rc8 -# Wed Apr 2 20:46:14 2008 +# Linux kernel version: 2.6.26-rc2 +# Sun May 18 14:44:47 2008 # CONFIG_M68K=y CONFIG_MMU=y @@ -52,6 +52,7 @@ CONFIG_SYSCTL=y # CONFIG_EMBEDDED is not set CONFIG_UID16=y CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set CONFIG_HOTPLUG=y @@ -76,12 +77,14 @@ CONFIG_SLAB=y # CONFIG_HAVE_OPROFILE is not set # CONFIG_HAVE_KPROBES is not set # CONFIG_HAVE_KRETPROBES is not set +# CONFIG_HAVE_DMA_ATTRS is not set CONFIG_PROC_PAGE_MONITOR=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set @@ -143,6 +146,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_NEED_MULTIPLE_NODES=y # CONFIG_SPARSEMEM_STATIC is not set # CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 @@ -219,8 +223,10 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m CONFIG_INET6_XFRM_MODE_BEET=m CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m CONFIG_IPV6_SIT=m +CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=m # CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_MROUTE is not set # CONFIG_NETWORK_SECMARK is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set @@ -236,6 +242,7 @@ CONFIG_NF_CONNTRACK=m CONFIG_NF_CT_ACCT=y CONFIG_NF_CONNTRACK_MARK=y # CONFIG_NF_CONNTRACK_EVENTS is not set +# CONFIG_NF_CT_PROTO_DCCP is not set CONFIG_NF_CT_PROTO_GRE=m CONFIG_NF_CT_PROTO_SCTP=m CONFIG_NF_CT_PROTO_UDPLITE=m @@ -314,6 +321,8 @@ CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_NF_NAT_SNMP_BASIC=m CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_PROTO_UDPLITE=m +CONFIG_NF_NAT_PROTO_SCTP=m CONFIG_NF_NAT_FTP=m CONFIG_NF_NAT_IRC=m CONFIG_NF_NAT_TFTP=m @@ -410,8 +419,6 @@ CONFIG_IEEE80211=m CONFIG_IEEE80211_CRYPT_WEP=m CONFIG_IEEE80211_CRYPT_CCMP=m CONFIG_IEEE80211_CRYPT_TKIP=m -CONFIG_IEEE80211_SOFTMAC=m -# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -467,11 +474,10 @@ CONFIG_IDE_PROC_FS=y # # IDE chipset support/bugfixes # -# CONFIG_IDE_GENERIC is not set # CONFIG_BLK_DEV_PLATFORM is not set CONFIG_BLK_DEV_MAC_IDE=y # CONFIG_BLK_DEV_IDEDMA is not set -# CONFIG_IDE_ARCH_OBSOLETE_INIT is not set +# CONFIG_BLK_DEV_HD_ONLY is not set # CONFIG_BLK_DEV_HD is not set # @@ -520,6 +526,7 @@ CONFIG_SCSI_LOWLEVEL=y CONFIG_ISCSI_TCP=m # CONFIG_SCSI_DEBUG is not set CONFIG_MAC_SCSI=y +CONFIG_SCSI_MAC_ESP=y CONFIG_MD=y CONFIG_BLK_DEV_MD=m CONFIG_MD_LINEAR=m @@ -580,6 +587,7 @@ CONFIG_MACMACE=y # # CONFIG_WLAN_PRE80211 is not set # CONFIG_WLAN_80211 is not set +# CONFIG_IWLWIFI_LEDS is not set # CONFIG_WAN is not set CONFIG_PPP=m # CONFIG_PPP_MULTILINK is not set @@ -665,6 +673,7 @@ CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_DEVKMEM is not set # CONFIG_SERIAL_NONSTANDARD is not set # @@ -686,12 +695,7 @@ CONFIG_GEN_RTC_X=y # CONFIG_RAW_DRIVER is not set # CONFIG_TCG_TPM is not set # CONFIG_I2C is not set - -# -# SPI support -# # CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set @@ -708,12 +712,22 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set # # Multimedia devices # + +# +# Multimedia core support +# # CONFIG_VIDEO_DEV is not set # CONFIG_DVB_CORE is not set +# CONFIG_VIDEO_MEDIA is not set + +# +# Multimedia drivers +# # CONFIG_DAB is not set # @@ -731,8 +745,8 @@ CONFIG_FB_CFB_IMAGEBLIT=y # CONFIG_FB_SYS_FILLRECT is not set # CONFIG_FB_SYS_COPYAREA is not set # CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set # CONFIG_FB_SYS_FOPS is not set -CONFIG_FB_DEFERRED_IO=y # CONFIG_FB_SVGALIB is not set CONFIG_FB_MACMODES=y # CONFIG_FB_BACKLIGHT is not set @@ -783,11 +797,8 @@ CONFIG_HIDRAW=y # CONFIG_MMC is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set # CONFIG_RTC_CLASS is not set - -# -# Userspace I/O -# # CONFIG_UIO is not set # @@ -816,16 +827,15 @@ CONFIG_JFS_FS=m # CONFIG_JFS_SECURITY is not set # CONFIG_JFS_DEBUG is not set # CONFIG_JFS_STATISTICS is not set -CONFIG_FS_POSIX_ACL=y +# CONFIG_FS_POSIX_ACL is not set CONFIG_XFS_FS=m # CONFIG_XFS_QUOTA is not set -# CONFIG_XFS_SECURITY is not set # CONFIG_XFS_POSIX_ACL is not set # CONFIG_XFS_RT is not set -CONFIG_GFS2_FS=m -CONFIG_GFS2_FS_LOCKING_NOLOCK=m -CONFIG_GFS2_FS_LOCKING_DLM=m +# CONFIG_XFS_DEBUG is not set CONFIG_OCFS2_FS=m +CONFIG_OCFS2_FS_O2CB=m +CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set # CONFIG_OCFS2_DEBUG_FS is not set CONFIG_DNOTIFY=y @@ -897,12 +907,10 @@ CONFIG_NFS_FS=m CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set CONFIG_NFS_V4=y -# CONFIG_NFS_DIRECTIO is not set CONFIG_NFSD=m CONFIG_NFSD_V3=y # CONFIG_NFSD_V3_ACL is not set # CONFIG_NFSD_V4 is not set -CONFIG_NFSD_TCP=y CONFIG_LOCKD=m CONFIG_LOCKD_V4=y CONFIG_EXPORTFS=m @@ -976,6 +984,7 @@ CONFIG_DLM=m # CONFIG_PRINTK_TIME is not set CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set # CONFIG_DEBUG_FS is not set @@ -995,53 +1004,82 @@ CONFIG_ASYNC_CORE=m CONFIG_ASYNC_MEMCPY=m CONFIG_ASYNC_XOR=m CONFIG_CRYPTO=y + +# +# Crypto core or helper +# CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_AEAD=m CONFIG_CRYPTO_BLKCIPHER=m -CONFIG_CRYPTO_SEQIV=m CONFIG_CRYPTO_HASH=y CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_TEST=m + +# +# Authenticated Encryption with Associated Data +# +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_SEQIV=m + +# +# Block modes +# +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_CTR=m +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_XTS=m + +# +# Hash modes +# CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_XCBC=m -CONFIG_CRYPTO_NULL=m + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=m CONFIG_CRYPTO_MD4=m CONFIG_CRYPTO_MD5=m +CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_SHA1=m CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m -CONFIG_CRYPTO_WP512=m CONFIG_CRYPTO_TGR192=m -CONFIG_CRYPTO_GF128MUL=m -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=m -CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_LRW=m -CONFIG_CRYPTO_XTS=m -CONFIG_CRYPTO_CTR=m -CONFIG_CRYPTO_GCM=m -CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_CRYPTD=m -CONFIG_CRYPTO_DES=m -CONFIG_CRYPTO_FCRYPT=m -CONFIG_CRYPTO_BLOWFISH=m -CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_TWOFISH_COMMON=m -CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_WP512=m + +# +# Ciphers +# CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m CONFIG_CRYPTO_CAST5=m CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_TEA=m -CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_FCRYPT=m CONFIG_CRYPTO_KHAZAD=m -CONFIG_CRYPTO_ANUBIS=m -CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SALSA20=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m + +# +# Compression +# CONFIG_CRYPTO_DEFLATE=m -CONFIG_CRYPTO_MICHAEL_MIC=m -CONFIG_CRYPTO_CRC32C=m -CONFIG_CRYPTO_CAMELLIA=m -CONFIG_CRYPTO_TEST=m -CONFIG_CRYPTO_AUTHENC=m CONFIG_CRYPTO_LZO=m # CONFIG_CRYPTO_HW is not set @@ -1049,9 +1087,11 @@ CONFIG_CRYPTO_LZO=m # Library routines # CONFIG_BITREVERSE=y +# CONFIG_GENERIC_FIND_FIRST_BIT is not set +# CONFIG_GENERIC_FIND_NEXT_BIT is not set CONFIG_CRC_CCITT=m CONFIG_CRC16=m -# CONFIG_CRC_ITU_T is not set +CONFIG_CRC_ITU_T=m CONFIG_CRC32=y # CONFIG_CRC7 is not set CONFIG_LIBCRC32C=m diff --git a/arch/m68k/configs/multi_defconfig b/arch/m68k/configs/multi_defconfig new file mode 100644 index 0000000000000000000000000000000000000000..4d23f99227f90f3ee91d74ad877cf42dfc117b23 --- /dev/null +++ b/arch/m68k/configs/multi_defconfig @@ -0,0 +1,1269 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.26-rc2 +# Sun May 18 14:42:31 2008 +# +CONFIG_M68K=y +CONFIG_MMU=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_TIME_LOW_RES=y +CONFIG_GENERIC_IOMAP=y +CONFIG_NO_IOPORT=y +# CONFIG_NO_DMA is not set +CONFIG_ARCH_SUPPORTS_AOUT=y +CONFIG_HZ=100 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="-multi" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +# CONFIG_GROUP_SCHED is not set +# CONFIG_SYSFS_DEPRECATED_V2 is not set +CONFIG_RELAY=y +CONFIG_NAMESPACES=y +# CONFIG_UTS_NS is not set +# CONFIG_IPC_NS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +# CONFIG_EMBEDDED is not set +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +# CONFIG_COMPAT_BRK is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +# CONFIG_HAVE_OPROFILE is not set +# CONFIG_HAVE_KPROBES is not set +# CONFIG_HAVE_KRETPROBES is not set +# CONFIG_HAVE_DMA_ATTRS is not set +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +CONFIG_BLK_DEV_BSG=y + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_CLASSIC_RCU=y + +# +# Platform dependent setup +# +# CONFIG_SUN3 is not set +CONFIG_AMIGA=y +CONFIG_ATARI=y +CONFIG_MAC=y +CONFIG_NUBUS=y +CONFIG_M68K_L2_CACHE=y +CONFIG_APOLLO=y +CONFIG_VME=y +CONFIG_MVME147=y +CONFIG_MVME16x=y +CONFIG_BVME6000=y +CONFIG_HP300=y +CONFIG_DIO=y +CONFIG_SUN3X=y +CONFIG_Q40=y + +# +# Processor type +# +CONFIG_M68020=y +CONFIG_M68030=y +CONFIG_M68040=y +CONFIG_M68060=y +CONFIG_MMU_MOTOROLA=y +# CONFIG_M68KFPU_EMU is not set +# CONFIG_ADVANCED is not set +CONFIG_ARCH_DISCONTIGMEM_ENABLE=y +CONFIG_NODES_SHIFT=3 +CONFIG_SELECT_MEMORY_MODEL=y +# CONFIG_FLATMEM_MANUAL is not set +CONFIG_DISCONTIGMEM_MANUAL=y +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_DISCONTIGMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_NEED_MULTIPLE_NODES=y +# CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y + +# +# General setup +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_AOUT=m +CONFIG_BINFMT_MISC=m +CONFIG_ZORRO=y +CONFIG_AMIGA_PCMCIA=y +CONFIG_STRAM_PROC=y +CONFIG_HEARTBEAT=y +CONFIG_PROC_HARDWARE=y +CONFIG_ISA=y +CONFIG_GENERIC_ISA_DMA=y +CONFIG_ZONE_DMA=y +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_ZORRO_NAMES=y + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +CONFIG_XFRM_MIGRATE=y +# CONFIG_XFRM_STATISTICS is not set +CONFIG_NET_KEY=y +CONFIG_NET_KEY_MIGRATE=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE=m +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_LRO=m +CONFIG_INET_DIAG=m +CONFIG_INET_TCP_DIAG=m +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IP_VS is not set +CONFIG_IPV6=m +CONFIG_IPV6_PRIVACY=y +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_ROUTE_INFO=y +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +# CONFIG_IPV6_MIP6 is not set +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_IPV6_SIT=m +CONFIG_IPV6_NDISC_NODETYPE=y +CONFIG_IPV6_TUNNEL=m +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_MROUTE is not set +# CONFIG_NETWORK_SECMARK is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_ADVANCED=y + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CT_ACCT=y +CONFIG_NF_CONNTRACK_MARK=y +# CONFIG_NF_CONNTRACK_EVENTS is not set +# CONFIG_NF_CT_PROTO_DCCP is not set +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_CT_PROTO_UDPLITE=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_SANE=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +# CONFIG_NF_CT_NETLINK is not set +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_RATEEST=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m + +# +# IP: Netfilter Configuration +# +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_NF_NAT=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_PROTO_UDPLITE=m +CONFIG_NF_NAT_PROTO_SCTP=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_TFTP=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_SIP=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m + +# +# IPv6: Netfilter Configuration +# +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP_DCCP=m +CONFIG_INET_DCCP_DIAG=m +CONFIG_IP_DCCP_ACKVEC=y + +# +# DCCP CCIDs Configuration (EXPERIMENTAL) +# +CONFIG_IP_DCCP_CCID2=m +# CONFIG_IP_DCCP_CCID2_DEBUG is not set +CONFIG_IP_DCCP_CCID3=m +# CONFIG_IP_DCCP_CCID3_DEBUG is not set +CONFIG_IP_DCCP_CCID3_RTO=100 +CONFIG_IP_DCCP_TFRC_LIB=m +CONFIG_IP_SCTP=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SCTP_HMAC_MD5=y +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +CONFIG_LLC=m +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +CONFIG_ATALK=m +CONFIG_DEV_APPLETALK=m +# CONFIG_COPS is not set +CONFIG_IPDDP=m +CONFIG_IPDDP_ENCAP=y +CONFIG_IPDDP_DECAP=y +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set +CONFIG_NET_CLS_ROUTE=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +CONFIG_WIRELESS_EXT=y +# CONFIG_MAC80211 is not set +CONFIG_IEEE80211=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_CRYPT_WEP=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=m +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_CONNECTOR=m +# CONFIG_MTD is not set +CONFIG_PARPORT=m +# CONFIG_PARPORT_PC is not set +CONFIG_PARPORT_AMIGA=m +CONFIG_PARPORT_MFC3=m +CONFIG_PARPORT_ATARI=m +# CONFIG_PARPORT_GSC is not set +# CONFIG_PARPORT_AX88796 is not set +CONFIG_PARPORT_1284=y +CONFIG_PARPORT_NOT_PC=y +# CONFIG_PNP is not set +CONFIG_BLK_DEV=y +CONFIG_AMIGA_FLOPPY=y +CONFIG_ATARI_FLOPPY=y +CONFIG_AMIGA_Z2RAM=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_XIP is not set +CONFIG_CDROM_PKTCDVD=m +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set +CONFIG_ATA_OVER_ETH=m +CONFIG_MISC_DEVICES=y +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_ENCLOSURE_SERVICES is not set +CONFIG_HAVE_IDE=y +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +CONFIG_BLK_DEV_IDECD=y +CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y +# CONFIG_BLK_DEV_IDETAPE is not set +CONFIG_BLK_DEV_IDEFLOPPY=m +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL is not set +CONFIG_IDE_PROC_FS=y + +# +# IDE chipset support/bugfixes +# +# CONFIG_BLK_DEV_PLATFORM is not set +CONFIG_BLK_DEV_GAYLE=y +CONFIG_BLK_DEV_IDEDOUBLER=y +CONFIG_BLK_DEV_BUDDHA=y +CONFIG_BLK_DEV_FALCON_IDE=y +CONFIG_BLK_DEV_MAC_IDE=y +CONFIG_BLK_DEV_Q40IDE=y +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_BLK_DEV_HD_ONLY is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +CONFIG_RAID_ATTRS=m +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +CONFIG_SCSI_TGT=m +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_ST=m +CONFIG_CHR_DEV_OSST=m +CONFIG_BLK_DEV_SR=y +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_CHR_DEV_SG=m +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_CONSTANTS=y +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +CONFIG_SCSI_SPI_ATTRS=y +# CONFIG_SCSI_FC_ATTRS is not set +CONFIG_SCSI_ISCSI_ATTRS=m +CONFIG_SCSI_SAS_ATTRS=m +CONFIG_SCSI_SAS_LIBSAS=m +CONFIG_SCSI_SAS_HOST_SMP=y +# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set +CONFIG_SCSI_SRP_ATTRS=m +CONFIG_SCSI_SRP_TGT_ATTRS=y +CONFIG_SCSI_LOWLEVEL=y +CONFIG_ISCSI_TCP=m +# CONFIG_SCSI_AHA152X is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set +# CONFIG_SCSI_NCR53C406A is not set +CONFIG_53C700_BE_BUS=y +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_DEBUG is not set +CONFIG_A3000_SCSI=y +CONFIG_A2091_SCSI=y +CONFIG_GVP11_SCSI=y +CONFIG_SCSI_A4000T=y +CONFIG_SCSI_ZORRO7XX=y +CONFIG_ATARI_SCSI=y +# CONFIG_ATARI_SCSI_TOSHIBA_DELAY is not set +# CONFIG_ATARI_SCSI_RESET_BOOT is not set +CONFIG_MAC_SCSI=y +CONFIG_SCSI_MAC_ESP=y +CONFIG_MVME147_SCSI=y +CONFIG_MVME16x_SCSI=y +CONFIG_BVME6000_SCSI=y +CONFIG_SUN3X_ESP=y +CONFIG_MD=y +CONFIG_BLK_DEV_MD=m +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +# CONFIG_MD_RAID10 is not set +CONFIG_MD_RAID456=m +CONFIG_MD_RAID5_RESHAPE=y +CONFIG_MD_MULTIPATH=m +# CONFIG_MD_FAULTY is not set +CONFIG_BLK_DEV_DM=m +# CONFIG_DM_DEBUG is not set +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_MIRROR=m +CONFIG_DM_ZERO=m +CONFIG_DM_MULTIPATH=m +CONFIG_DM_MULTIPATH_EMC=m +CONFIG_DM_MULTIPATH_RDAC=m +CONFIG_DM_MULTIPATH_HP=m +# CONFIG_DM_DELAY is not set +CONFIG_DM_UEVENT=y +CONFIG_MACINTOSH_DRIVERS=y +CONFIG_ADB=y +CONFIG_ADB_MACII=y +CONFIG_ADB_MACIISI=y +CONFIG_ADB_IOP=y +CONFIG_ADB_PMU68K=y +CONFIG_ADB_CUDA=y +CONFIG_INPUT_ADBHID=y +CONFIG_MAC_EMUMOUSEBTN=y +CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set +CONFIG_DUMMY=m +# CONFIG_BONDING is not set +CONFIG_MACVLAN=m +CONFIG_EQUALIZER=m +# CONFIG_TUN is not set +CONFIG_VETH=m +# CONFIG_ARCNET is not set +# CONFIG_PHYLIB is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=m +CONFIG_ARIADNE=m +CONFIG_A2065=m +CONFIG_HYDRA=m +CONFIG_ZORRO8390=m +CONFIG_APNE=m +CONFIG_APOLLO_ELPLUS=y +CONFIG_MAC8390=y +CONFIG_MAC89x0=m +CONFIG_MACSONIC=m +CONFIG_MACMACE=y +CONFIG_MVME147_NET=y +CONFIG_MVME16x_NET=y +CONFIG_BVME6000_NET=y +CONFIG_ATARILANCE=m +CONFIG_SUN3LANCE=y +CONFIG_HPLANCE=y +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NE2000=m +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_NET_PCI is not set +# CONFIG_B44 is not set +# CONFIG_NET_POCKET is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set +# CONFIG_TR is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set +# CONFIG_IWLWIFI_LEDS is not set +# CONFIG_WAN is not set +# CONFIG_PLIP is not set +CONFIG_PPP=m +# CONFIG_PPP_MULTILINK is not set +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_MPPE=m +CONFIG_PPPOE=m +CONFIG_PPPOL2TP=m +CONFIG_SLIP=m +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLHC=m +CONFIG_SLIP_SMART=y +CONFIG_SLIP_MODE_SLIP6=y +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NET_POLL_CONTROLLER=y +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +CONFIG_INPUT_FF_MEMLESS=m +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ATKBD is not set +CONFIG_KEYBOARD_SUNKBD=y +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +CONFIG_KEYBOARD_AMIGA=y +CONFIG_ATARI_KBD_CORE=y +CONFIG_KEYBOARD_ATARI=y +CONFIG_KEYBOARD_HIL_OLD=y +CONFIG_KEYBOARD_HIL=y +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_TRACKPOINT=y +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +CONFIG_MOUSE_SERIAL=m +# CONFIG_MOUSE_INPORT is not set +# CONFIG_MOUSE_LOGIBM is not set +# CONFIG_MOUSE_PC110PAD is not set +CONFIG_MOUSE_AMIGA=m +CONFIG_MOUSE_ATARI=m +# CONFIG_MOUSE_VSXXXAA is not set +CONFIG_MOUSE_HIL=m +CONFIG_INPUT_JOYSTICK=y +# CONFIG_JOYSTICK_ANALOG is not set +# CONFIG_JOYSTICK_A3D is not set +# CONFIG_JOYSTICK_ADI is not set +# CONFIG_JOYSTICK_COBRA is not set +# CONFIG_JOYSTICK_GF2K is not set +# CONFIG_JOYSTICK_GRIP is not set +# CONFIG_JOYSTICK_GRIP_MP is not set +# CONFIG_JOYSTICK_GUILLEMOT is not set +# CONFIG_JOYSTICK_INTERACT is not set +# CONFIG_JOYSTICK_SIDEWINDER is not set +# CONFIG_JOYSTICK_TMDC is not set +# CONFIG_JOYSTICK_IFORCE is not set +# CONFIG_JOYSTICK_WARRIOR is not set +# CONFIG_JOYSTICK_MAGELLAN is not set +# CONFIG_JOYSTICK_SPACEORB is not set +# CONFIG_JOYSTICK_SPACEBALL is not set +# CONFIG_JOYSTICK_STINGER is not set +# CONFIG_JOYSTICK_TWIDJOY is not set +# CONFIG_JOYSTICK_ZHENHUA is not set +# CONFIG_JOYSTICK_DB9 is not set +# CONFIG_JOYSTICK_GAMECON is not set +# CONFIG_JOYSTICK_TURBOGRAFX is not set +CONFIG_JOYSTICK_AMIGA=m +# CONFIG_JOYSTICK_JOYDUMP is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +CONFIG_INPUT_MISC=y +CONFIG_INPUT_M68K_BEEP=m +# CONFIG_INPUT_UINPUT is not set +CONFIG_HP_SDC_RTC=m + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_SERPORT is not set +CONFIG_SERIO_Q40KBD=m +# CONFIG_SERIO_PARKBD is not set +CONFIG_HP_SDC=y +CONFIG_HIL_MLC=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_DEVKMEM is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_A2232=m + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_PRINTER=m +# CONFIG_LP_CONSOLE is not set +# CONFIG_PPDEV is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +CONFIG_NVRAM=y +CONFIG_GEN_RTC=m +CONFIG_GEN_RTC_X=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +# CONFIG_I2C is not set +# CONFIG_SPI is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_WATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set + +# +# Multimedia devices +# + +# +# Multimedia core support +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DVB_CORE is not set +# CONFIG_VIDEO_MEDIA is not set + +# +# Multimedia drivers +# +# CONFIG_DAB is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +CONFIG_FB_MACMODES=y +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +CONFIG_FB_CIRRUS=y +CONFIG_FB_APOLLO=y +CONFIG_FB_Q40=y +CONFIG_FB_AMIGA=y +CONFIG_FB_AMIGA_OCS=y +CONFIG_FB_AMIGA_ECS=y +CONFIG_FB_AMIGA_AGA=y +CONFIG_FB_FM2=y +CONFIG_FB_ATARI=y +CONFIG_FB_VALKYRIE=y +CONFIG_FB_MAC=y +CONFIG_FB_HP300=y +# CONFIG_FB_UVESA is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_FONT_6x11=y +CONFIG_FONT_PEARL_8x8=y +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y +CONFIG_LOGO_MAC_CLUT224=y + +# +# Sound +# +CONFIG_SOUND=m +CONFIG_DMASOUND_ATARI=m +CONFIG_DMASOUND_PAULA=m +CONFIG_DMASOUND_Q40=m +CONFIG_DMASOUND=m +CONFIG_HID_SUPPORT=y +CONFIG_HID=m +# CONFIG_HID_DEBUG is not set +CONFIG_HIDRAW=y +# CONFIG_USB_SUPPORT is not set +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_RTC_CLASS is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set + +# +# Character devices +# +CONFIG_ATARI_MFPSER=m +CONFIG_ATARI_SCC=y +CONFIG_ATARI_SCC_DMA=y +CONFIG_ATARI_MIDI=m +CONFIG_ATARI_DSP56K=m +CONFIG_AMIGA_BUILTIN_SERIAL=y +CONFIG_MULTIFACE_III_TTY=m +CONFIG_MAC_SCC=y +CONFIG_MAC_HID=y +CONFIG_MVME147_SCC=y +CONFIG_SERIAL167=y +CONFIG_MVME162_SCC=y +CONFIG_BVME6000_SCC=y +CONFIG_DN_SERIAL=y +CONFIG_SERIAL_CONSOLE=y + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_FS_XATTR is not set +# CONFIG_EXT4DEV_FS is not set +CONFIG_JBD=y +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_REISERFS_FS_XATTR is not set +CONFIG_JFS_FS=m +# CONFIG_JFS_POSIX_ACL is not set +# CONFIG_JFS_SECURITY is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +# CONFIG_FS_POSIX_ACL is not set +CONFIG_XFS_FS=m +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_POSIX_ACL is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_DEBUG is not set +CONFIG_OCFS2_FS=m +CONFIG_OCFS2_FS_O2CB=m +CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m +# CONFIG_OCFS2_DEBUG_MASKLOG is not set +# CONFIG_OCFS2_DEBUG_FS is not set +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_QUOTA=y +CONFIG_QUOTA_NETLINK_INTERFACE=y +# CONFIG_PRINT_QUOTA_WARNING is not set +# CONFIG_QFMT_V1 is not set +# CONFIG_QFMT_V2 is not set +CONFIG_QUOTACTL=y +CONFIG_AUTOFS_FS=m +CONFIG_AUTOFS4_FS=m +CONFIG_FUSE_FS=m + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_CONFIGFS_FS=m + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +CONFIG_AFFS_FS=m +CONFIG_HFS_FS=y +CONFIG_HFSPLUS_FS=y +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_CRAMFS=m +# CONFIG_VXFS_FS is not set +CONFIG_MINIX_FS=y +CONFIG_HPFS_FS=m +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_SYSV_FS=m +CONFIG_UFS_FS=m +# CONFIG_UFS_FS_WRITE is not set +# CONFIG_UFS_DEBUG is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +CONFIG_NFSD=m +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set +# CONFIG_NFSD_V4 is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=m +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_SUNRPC_BIND34=y +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_SMB_FS=m +CONFIG_SMB_NLS_DEFAULT=y +CONFIG_SMB_NLS_REMOTE="cp437" +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +CONFIG_CODA_FS=m +# CONFIG_CODA_FS_OLD_API is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_AMIGA_PARTITION=y +CONFIG_ATARI_PARTITION=y +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +CONFIG_SUN_PARTITION=y +CONFIG_SYSV68_PARTITION=y +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ASCII=m +CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=y +CONFIG_DLM=m +# CONFIG_DLM_DEBUG is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_SAMPLES is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_XOR_BLOCKS=m +CONFIG_ASYNC_CORE=m +CONFIG_ASYNC_MEMCPY=m +CONFIG_ASYNC_XOR=m +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_TEST=m + +# +# Authenticated Encryption with Associated Data +# +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_SEQIV=m + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_CTR=m +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_XTS=m + +# +# Hash modes +# +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_XCBC=m + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_WP512=m + +# +# Ciphers +# +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_SALSA20=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m + +# +# Compression +# +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_LZO=m +# CONFIG_CRYPTO_HW is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_GENERIC_FIND_FIRST_BIT is not set +# CONFIG_GENERIC_FIND_NEXT_BIT is not set +CONFIG_CRC_CCITT=m +CONFIG_CRC16=y +CONFIG_CRC_ITU_T=m +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +CONFIG_LIBCRC32C=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=m +CONFIG_LZO_COMPRESS=m +CONFIG_LZO_DECOMPRESS=m +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_DMA=y diff --git a/arch/m68k/configs/mvme147_defconfig b/arch/m68k/configs/mvme147_defconfig index f40b1724254bab4dbf08a0318d75b1a90f642bd2..188847fed8242f5039769a774b1aaae17a0a72bf 100644 --- a/arch/m68k/configs/mvme147_defconfig +++ b/arch/m68k/configs/mvme147_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.25-rc8 -# Wed Apr 2 20:46:17 2008 +# Linux kernel version: 2.6.26-rc2 +# Sun May 18 14:44:49 2008 # CONFIG_M68K=y CONFIG_MMU=y @@ -52,6 +52,7 @@ CONFIG_SYSCTL=y # CONFIG_EMBEDDED is not set CONFIG_UID16=y CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set CONFIG_HOTPLUG=y @@ -76,12 +77,14 @@ CONFIG_SLAB=y # CONFIG_HAVE_OPROFILE is not set # CONFIG_HAVE_KPROBES is not set # CONFIG_HAVE_KRETPROBES is not set +# CONFIG_HAVE_DMA_ATTRS is not set CONFIG_PROC_PAGE_MONITOR=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set @@ -144,6 +147,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_NEED_MULTIPLE_NODES=y # CONFIG_SPARSEMEM_STATIC is not set # CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 @@ -222,8 +226,10 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m CONFIG_INET6_XFRM_MODE_BEET=m CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m CONFIG_IPV6_SIT=m +CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=m # CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_MROUTE is not set # CONFIG_NETWORK_SECMARK is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set @@ -239,6 +245,7 @@ CONFIG_NF_CONNTRACK=m CONFIG_NF_CT_ACCT=y CONFIG_NF_CONNTRACK_MARK=y # CONFIG_NF_CONNTRACK_EVENTS is not set +# CONFIG_NF_CT_PROTO_DCCP is not set CONFIG_NF_CT_PROTO_GRE=m CONFIG_NF_CT_PROTO_SCTP=m CONFIG_NF_CT_PROTO_UDPLITE=m @@ -317,6 +324,8 @@ CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_NF_NAT_SNMP_BASIC=m CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_PROTO_UDPLITE=m +CONFIG_NF_NAT_PROTO_SCTP=m CONFIG_NF_NAT_FTP=m CONFIG_NF_NAT_IRC=m CONFIG_NF_NAT_TFTP=m @@ -410,8 +419,6 @@ CONFIG_IEEE80211=m CONFIG_IEEE80211_CRYPT_WEP=m CONFIG_IEEE80211_CRYPT_CCMP=m CONFIG_IEEE80211_CRYPT_TKIP=m -CONFIG_IEEE80211_SOFTMAC=m -# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -542,6 +549,7 @@ CONFIG_MVME147_NET=y # # CONFIG_WLAN_PRE80211 is not set # CONFIG_WLAN_80211 is not set +# CONFIG_IWLWIFI_LEDS is not set # CONFIG_WAN is not set CONFIG_PPP=m # CONFIG_PPP_MULTILINK is not set @@ -625,6 +633,7 @@ CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_DEVKMEM is not set # CONFIG_SERIAL_NONSTANDARD is not set # @@ -646,12 +655,7 @@ CONFIG_GEN_RTC_X=y # CONFIG_RAW_DRIVER is not set # CONFIG_TCG_TPM is not set # CONFIG_I2C is not set - -# -# SPI support -# # CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set @@ -668,12 +672,22 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set # # Multimedia devices # + +# +# Multimedia core support +# # CONFIG_VIDEO_DEV is not set # CONFIG_DVB_CORE is not set +# CONFIG_VIDEO_MEDIA is not set + +# +# Multimedia drivers +# # CONFIG_DAB is not set # @@ -706,11 +720,8 @@ CONFIG_HIDRAW=y # CONFIG_MMC is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set # CONFIG_RTC_CLASS is not set - -# -# Userspace I/O -# # CONFIG_UIO is not set # @@ -738,16 +749,15 @@ CONFIG_JFS_FS=m # CONFIG_JFS_SECURITY is not set # CONFIG_JFS_DEBUG is not set # CONFIG_JFS_STATISTICS is not set -CONFIG_FS_POSIX_ACL=y +# CONFIG_FS_POSIX_ACL is not set CONFIG_XFS_FS=m # CONFIG_XFS_QUOTA is not set -# CONFIG_XFS_SECURITY is not set # CONFIG_XFS_POSIX_ACL is not set # CONFIG_XFS_RT is not set -CONFIG_GFS2_FS=m -CONFIG_GFS2_FS_LOCKING_NOLOCK=m -CONFIG_GFS2_FS_LOCKING_DLM=m +# CONFIG_XFS_DEBUG is not set CONFIG_OCFS2_FS=m +CONFIG_OCFS2_FS_O2CB=m +CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set # CONFIG_OCFS2_DEBUG_FS is not set CONFIG_DNOTIFY=y @@ -819,12 +829,10 @@ CONFIG_NFS_FS=y CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set CONFIG_NFS_V4=y -# CONFIG_NFS_DIRECTIO is not set CONFIG_NFSD=m CONFIG_NFSD_V3=y # CONFIG_NFSD_V3_ACL is not set # CONFIG_NFSD_V4 is not set -CONFIG_NFSD_TCP=y CONFIG_ROOT_NFS=y CONFIG_LOCKD=y CONFIG_LOCKD_V4=y @@ -899,6 +907,7 @@ CONFIG_DLM=m # CONFIG_PRINTK_TIME is not set CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set # CONFIG_DEBUG_FS is not set @@ -918,53 +927,82 @@ CONFIG_ASYNC_CORE=m CONFIG_ASYNC_MEMCPY=m CONFIG_ASYNC_XOR=m CONFIG_CRYPTO=y + +# +# Crypto core or helper +# CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_AEAD=m CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_SEQIV=m CONFIG_CRYPTO_HASH=y CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_TEST=m + +# +# Authenticated Encryption with Associated Data +# +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_SEQIV=m + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_CTR=m +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_XTS=m + +# +# Hash modes +# CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_XCBC=m -CONFIG_CRYPTO_NULL=m + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=m CONFIG_CRYPTO_MD4=m CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_SHA1=m CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m -CONFIG_CRYPTO_WP512=m CONFIG_CRYPTO_TGR192=m -CONFIG_CRYPTO_GF128MUL=m -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=y -CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_LRW=m -CONFIG_CRYPTO_XTS=m -CONFIG_CRYPTO_CTR=m -CONFIG_CRYPTO_GCM=m -CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_CRYPTD=m -CONFIG_CRYPTO_DES=y -CONFIG_CRYPTO_FCRYPT=m -CONFIG_CRYPTO_BLOWFISH=m -CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_TWOFISH_COMMON=m -CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_WP512=m + +# +# Ciphers +# CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m CONFIG_CRYPTO_CAST5=m CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_TEA=m -CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_FCRYPT=m CONFIG_CRYPTO_KHAZAD=m -CONFIG_CRYPTO_ANUBIS=m -CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SALSA20=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m + +# +# Compression +# CONFIG_CRYPTO_DEFLATE=m -CONFIG_CRYPTO_MICHAEL_MIC=m -CONFIG_CRYPTO_CRC32C=m -CONFIG_CRYPTO_CAMELLIA=m -CONFIG_CRYPTO_TEST=m -CONFIG_CRYPTO_AUTHENC=m CONFIG_CRYPTO_LZO=m # CONFIG_CRYPTO_HW is not set @@ -972,9 +1010,11 @@ CONFIG_CRYPTO_LZO=m # Library routines # CONFIG_BITREVERSE=y +# CONFIG_GENERIC_FIND_FIRST_BIT is not set +# CONFIG_GENERIC_FIND_NEXT_BIT is not set CONFIG_CRC_CCITT=m CONFIG_CRC16=m -# CONFIG_CRC_ITU_T is not set +CONFIG_CRC_ITU_T=m CONFIG_CRC32=y # CONFIG_CRC7 is not set CONFIG_LIBCRC32C=m diff --git a/arch/m68k/configs/mvme16x_defconfig b/arch/m68k/configs/mvme16x_defconfig index e9ccc774334eb0f30f7a103d81d7bba058822111..983e53d990c8de4ac7a6ee3dc28c33ebdec0fcef 100644 --- a/arch/m68k/configs/mvme16x_defconfig +++ b/arch/m68k/configs/mvme16x_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.25-rc8 -# Wed Apr 2 20:46:19 2008 +# Linux kernel version: 2.6.26-rc2 +# Sun May 18 14:44:50 2008 # CONFIG_M68K=y CONFIG_MMU=y @@ -52,6 +52,7 @@ CONFIG_SYSCTL=y # CONFIG_EMBEDDED is not set CONFIG_UID16=y CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set CONFIG_HOTPLUG=y @@ -76,12 +77,14 @@ CONFIG_SLAB=y # CONFIG_HAVE_OPROFILE is not set # CONFIG_HAVE_KPROBES is not set # CONFIG_HAVE_KRETPROBES is not set +# CONFIG_HAVE_DMA_ATTRS is not set CONFIG_PROC_PAGE_MONITOR=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set @@ -144,6 +147,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_NEED_MULTIPLE_NODES=y # CONFIG_SPARSEMEM_STATIC is not set # CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 @@ -222,8 +226,10 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m CONFIG_INET6_XFRM_MODE_BEET=m CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m CONFIG_IPV6_SIT=m +CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=m # CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_MROUTE is not set # CONFIG_NETWORK_SECMARK is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set @@ -239,6 +245,7 @@ CONFIG_NF_CONNTRACK=m CONFIG_NF_CT_ACCT=y CONFIG_NF_CONNTRACK_MARK=y # CONFIG_NF_CONNTRACK_EVENTS is not set +# CONFIG_NF_CT_PROTO_DCCP is not set CONFIG_NF_CT_PROTO_GRE=m CONFIG_NF_CT_PROTO_SCTP=m CONFIG_NF_CT_PROTO_UDPLITE=m @@ -317,6 +324,8 @@ CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_NF_NAT_SNMP_BASIC=m CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_PROTO_UDPLITE=m +CONFIG_NF_NAT_PROTO_SCTP=m CONFIG_NF_NAT_FTP=m CONFIG_NF_NAT_IRC=m CONFIG_NF_NAT_TFTP=m @@ -410,8 +419,6 @@ CONFIG_IEEE80211=m CONFIG_IEEE80211_CRYPT_WEP=m CONFIG_IEEE80211_CRYPT_CCMP=m CONFIG_IEEE80211_CRYPT_TKIP=m -CONFIG_IEEE80211_SOFTMAC=m -# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -543,6 +550,7 @@ CONFIG_MVME16x_NET=y # # CONFIG_WLAN_PRE80211 is not set # CONFIG_WLAN_80211 is not set +# CONFIG_IWLWIFI_LEDS is not set # CONFIG_WAN is not set CONFIG_PPP=m # CONFIG_PPP_MULTILINK is not set @@ -626,6 +634,7 @@ CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_DEVKMEM is not set # CONFIG_SERIAL_NONSTANDARD is not set # @@ -647,12 +656,7 @@ CONFIG_GEN_RTC_X=y # CONFIG_RAW_DRIVER is not set # CONFIG_TCG_TPM is not set # CONFIG_I2C is not set - -# -# SPI support -# # CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set @@ -669,12 +673,22 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set # # Multimedia devices # + +# +# Multimedia core support +# # CONFIG_VIDEO_DEV is not set # CONFIG_DVB_CORE is not set +# CONFIG_VIDEO_MEDIA is not set + +# +# Multimedia drivers +# # CONFIG_DAB is not set # @@ -707,11 +721,8 @@ CONFIG_HIDRAW=y # CONFIG_MMC is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set # CONFIG_RTC_CLASS is not set - -# -# Userspace I/O -# # CONFIG_UIO is not set # @@ -740,16 +751,15 @@ CONFIG_JFS_FS=m # CONFIG_JFS_SECURITY is not set # CONFIG_JFS_DEBUG is not set # CONFIG_JFS_STATISTICS is not set -CONFIG_FS_POSIX_ACL=y +# CONFIG_FS_POSIX_ACL is not set CONFIG_XFS_FS=m # CONFIG_XFS_QUOTA is not set -# CONFIG_XFS_SECURITY is not set # CONFIG_XFS_POSIX_ACL is not set # CONFIG_XFS_RT is not set -CONFIG_GFS2_FS=m -CONFIG_GFS2_FS_LOCKING_NOLOCK=m -CONFIG_GFS2_FS_LOCKING_DLM=m +# CONFIG_XFS_DEBUG is not set CONFIG_OCFS2_FS=m +CONFIG_OCFS2_FS_O2CB=m +CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set # CONFIG_OCFS2_DEBUG_FS is not set CONFIG_DNOTIFY=y @@ -821,12 +831,10 @@ CONFIG_NFS_FS=y CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set CONFIG_NFS_V4=y -# CONFIG_NFS_DIRECTIO is not set CONFIG_NFSD=m CONFIG_NFSD_V3=y # CONFIG_NFSD_V3_ACL is not set # CONFIG_NFSD_V4 is not set -CONFIG_NFSD_TCP=y CONFIG_ROOT_NFS=y CONFIG_LOCKD=y CONFIG_LOCKD_V4=y @@ -901,6 +909,7 @@ CONFIG_DLM=m # CONFIG_PRINTK_TIME is not set CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set # CONFIG_DEBUG_FS is not set @@ -920,53 +929,82 @@ CONFIG_ASYNC_CORE=m CONFIG_ASYNC_MEMCPY=m CONFIG_ASYNC_XOR=m CONFIG_CRYPTO=y + +# +# Crypto core or helper +# CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_AEAD=m CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_SEQIV=m CONFIG_CRYPTO_HASH=y CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_TEST=m + +# +# Authenticated Encryption with Associated Data +# +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_SEQIV=m + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_CTR=m +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_XTS=m + +# +# Hash modes +# CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_XCBC=m -CONFIG_CRYPTO_NULL=m + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=m CONFIG_CRYPTO_MD4=m CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_SHA1=m CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m -CONFIG_CRYPTO_WP512=m CONFIG_CRYPTO_TGR192=m -CONFIG_CRYPTO_GF128MUL=m -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=y -CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_LRW=m -CONFIG_CRYPTO_XTS=m -CONFIG_CRYPTO_CTR=m -CONFIG_CRYPTO_GCM=m -CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_CRYPTD=m -CONFIG_CRYPTO_DES=y -CONFIG_CRYPTO_FCRYPT=m -CONFIG_CRYPTO_BLOWFISH=m -CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_TWOFISH_COMMON=m -CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_WP512=m + +# +# Ciphers +# CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m CONFIG_CRYPTO_CAST5=m CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_TEA=m -CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_FCRYPT=m CONFIG_CRYPTO_KHAZAD=m -CONFIG_CRYPTO_ANUBIS=m -CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SALSA20=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m + +# +# Compression +# CONFIG_CRYPTO_DEFLATE=m -CONFIG_CRYPTO_MICHAEL_MIC=m -CONFIG_CRYPTO_CRC32C=m -CONFIG_CRYPTO_CAMELLIA=m -CONFIG_CRYPTO_TEST=m -CONFIG_CRYPTO_AUTHENC=m CONFIG_CRYPTO_LZO=m # CONFIG_CRYPTO_HW is not set @@ -974,9 +1012,11 @@ CONFIG_CRYPTO_LZO=m # Library routines # CONFIG_BITREVERSE=y +# CONFIG_GENERIC_FIND_FIRST_BIT is not set +# CONFIG_GENERIC_FIND_NEXT_BIT is not set CONFIG_CRC_CCITT=m CONFIG_CRC16=m -# CONFIG_CRC_ITU_T is not set +CONFIG_CRC_ITU_T=m CONFIG_CRC32=y # CONFIG_CRC7 is not set CONFIG_LIBCRC32C=m diff --git a/arch/m68k/configs/q40_defconfig b/arch/m68k/configs/q40_defconfig index 165658fe73ebddd99608cd38fa2def1116d1e2ac..7707f3fb0a70ba5768134496544d79539c9b4988 100644 --- a/arch/m68k/configs/q40_defconfig +++ b/arch/m68k/configs/q40_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.25-rc8 -# Wed Apr 2 20:46:20 2008 +# Linux kernel version: 2.6.26-rc2 +# Sun May 18 14:44:51 2008 # CONFIG_M68K=y CONFIG_MMU=y @@ -12,7 +12,6 @@ CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_TIME_LOW_RES=y CONFIG_GENERIC_IOMAP=y -CONFIG_ARCH_MAY_HAVE_PC_FDC=y CONFIG_NO_IOPORT=y # CONFIG_NO_DMA is not set CONFIG_ARCH_SUPPORTS_AOUT=y @@ -53,6 +52,7 @@ CONFIG_SYSCTL=y # CONFIG_EMBEDDED is not set CONFIG_UID16=y CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set CONFIG_HOTPLUG=y @@ -77,12 +77,14 @@ CONFIG_SLAB=y # CONFIG_HAVE_OPROFILE is not set # CONFIG_HAVE_KPROBES is not set # CONFIG_HAVE_KRETPROBES is not set +# CONFIG_HAVE_DMA_ATTRS is not set CONFIG_PROC_PAGE_MONITOR=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set @@ -142,6 +144,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_NEED_MULTIPLE_NODES=y # CONFIG_SPARSEMEM_STATIC is not set # CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 @@ -220,8 +223,10 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m CONFIG_INET6_XFRM_MODE_BEET=m CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m CONFIG_IPV6_SIT=m +CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=m # CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_MROUTE is not set # CONFIG_NETWORK_SECMARK is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set @@ -237,6 +242,7 @@ CONFIG_NF_CONNTRACK=m CONFIG_NF_CT_ACCT=y CONFIG_NF_CONNTRACK_MARK=y # CONFIG_NF_CONNTRACK_EVENTS is not set +# CONFIG_NF_CT_PROTO_DCCP is not set CONFIG_NF_CT_PROTO_GRE=m CONFIG_NF_CT_PROTO_SCTP=m CONFIG_NF_CT_PROTO_UDPLITE=m @@ -315,6 +321,8 @@ CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_NF_NAT_SNMP_BASIC=m CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_PROTO_UDPLITE=m +CONFIG_NF_NAT_PROTO_SCTP=m CONFIG_NF_NAT_FTP=m CONFIG_NF_NAT_IRC=m CONFIG_NF_NAT_TFTP=m @@ -408,8 +416,6 @@ CONFIG_IEEE80211=m CONFIG_IEEE80211_CRYPT_WEP=m CONFIG_IEEE80211_CRYPT_CCMP=m CONFIG_IEEE80211_CRYPT_TKIP=m -CONFIG_IEEE80211_SOFTMAC=m -# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -430,7 +436,6 @@ CONFIG_CONNECTOR=m # CONFIG_PARPORT is not set # CONFIG_PNP is not set CONFIG_BLK_DEV=y -# CONFIG_BLK_DEV_FD is not set # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_CRYPTOLOOP=m @@ -467,25 +472,10 @@ CONFIG_IDE_PROC_FS=y # # IDE chipset support/bugfixes # -# CONFIG_IDE_GENERIC is not set # CONFIG_BLK_DEV_PLATFORM is not set CONFIG_BLK_DEV_Q40IDE=y - -# -# Other IDE chipsets support -# - -# -# Note: most of these also require special kernel boot parameters -# -# CONFIG_BLK_DEV_4DRIVES is not set -# CONFIG_BLK_DEV_ALI14XX is not set -# CONFIG_BLK_DEV_DTC2278 is not set -# CONFIG_BLK_DEV_HT6560B is not set -# CONFIG_BLK_DEV_QD65XX is not set -# CONFIG_BLK_DEV_UMC8672 is not set # CONFIG_BLK_DEV_IDEDMA is not set -# CONFIG_IDE_ARCH_OBSOLETE_INIT is not set +# CONFIG_BLK_DEV_HD_ONLY is not set # CONFIG_BLK_DEV_HD is not set # @@ -603,6 +593,7 @@ CONFIG_NE2000=m # # CONFIG_WLAN_PRE80211 is not set # CONFIG_WLAN_80211 is not set +# CONFIG_IWLWIFI_LEDS is not set # CONFIG_WAN is not set CONFIG_PPP=m # CONFIG_PPP_MULTILINK is not set @@ -692,6 +683,7 @@ CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_DEVKMEM is not set # CONFIG_SERIAL_NONSTANDARD is not set # @@ -714,12 +706,7 @@ CONFIG_GEN_RTC_X=y # CONFIG_RAW_DRIVER is not set # CONFIG_TCG_TPM is not set # CONFIG_I2C is not set - -# -# SPI support -# # CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set @@ -736,12 +723,22 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set # # Multimedia devices # + +# +# Multimedia core support +# # CONFIG_VIDEO_DEV is not set # CONFIG_DVB_CORE is not set +# CONFIG_VIDEO_MEDIA is not set + +# +# Multimedia drivers +# # CONFIG_DAB is not set # @@ -759,8 +756,8 @@ CONFIG_FB_CFB_IMAGEBLIT=y # CONFIG_FB_SYS_FILLRECT is not set # CONFIG_FB_SYS_COPYAREA is not set # CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set # CONFIG_FB_SYS_FOPS is not set -CONFIG_FB_DEFERRED_IO=y # CONFIG_FB_SVGALIB is not set # CONFIG_FB_MACMODES is not set # CONFIG_FB_BACKLIGHT is not set @@ -810,11 +807,8 @@ CONFIG_HIDRAW=y # CONFIG_MMC is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set # CONFIG_RTC_CLASS is not set - -# -# Userspace I/O -# # CONFIG_UIO is not set # @@ -840,16 +834,15 @@ CONFIG_JFS_FS=m # CONFIG_JFS_SECURITY is not set # CONFIG_JFS_DEBUG is not set # CONFIG_JFS_STATISTICS is not set -CONFIG_FS_POSIX_ACL=y +# CONFIG_FS_POSIX_ACL is not set CONFIG_XFS_FS=m # CONFIG_XFS_QUOTA is not set -# CONFIG_XFS_SECURITY is not set # CONFIG_XFS_POSIX_ACL is not set # CONFIG_XFS_RT is not set -CONFIG_GFS2_FS=m -CONFIG_GFS2_FS_LOCKING_NOLOCK=m -CONFIG_GFS2_FS_LOCKING_DLM=m +# CONFIG_XFS_DEBUG is not set CONFIG_OCFS2_FS=m +CONFIG_OCFS2_FS_O2CB=m +CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set # CONFIG_OCFS2_DEBUG_FS is not set CONFIG_DNOTIFY=y @@ -921,12 +914,10 @@ CONFIG_NFS_FS=y CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set CONFIG_NFS_V4=y -# CONFIG_NFS_DIRECTIO is not set CONFIG_NFSD=m CONFIG_NFSD_V3=y # CONFIG_NFSD_V3_ACL is not set # CONFIG_NFSD_V4 is not set -CONFIG_NFSD_TCP=y CONFIG_LOCKD=y CONFIG_LOCKD_V4=y CONFIG_EXPORTFS=m @@ -999,6 +990,7 @@ CONFIG_DLM=m # CONFIG_PRINTK_TIME is not set CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set # CONFIG_DEBUG_FS is not set @@ -1018,53 +1010,82 @@ CONFIG_ASYNC_CORE=m CONFIG_ASYNC_MEMCPY=m CONFIG_ASYNC_XOR=m CONFIG_CRYPTO=y + +# +# Crypto core or helper +# CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_AEAD=m CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_SEQIV=m CONFIG_CRYPTO_HASH=y CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_TEST=m + +# +# Authenticated Encryption with Associated Data +# +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_SEQIV=m + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_CTR=m +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_XTS=m + +# +# Hash modes +# CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_XCBC=m -CONFIG_CRYPTO_NULL=m + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=m CONFIG_CRYPTO_MD4=m CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_SHA1=m CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m -CONFIG_CRYPTO_WP512=m CONFIG_CRYPTO_TGR192=m -CONFIG_CRYPTO_GF128MUL=m -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=y -CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_LRW=m -CONFIG_CRYPTO_XTS=m -CONFIG_CRYPTO_CTR=m -CONFIG_CRYPTO_GCM=m -CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_CRYPTD=m -CONFIG_CRYPTO_DES=y -CONFIG_CRYPTO_FCRYPT=m -CONFIG_CRYPTO_BLOWFISH=m -CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_TWOFISH_COMMON=m -CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_WP512=m + +# +# Ciphers +# CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m CONFIG_CRYPTO_CAST5=m CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_TEA=m -CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_FCRYPT=m CONFIG_CRYPTO_KHAZAD=m -CONFIG_CRYPTO_ANUBIS=m -CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SALSA20=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m + +# +# Compression +# CONFIG_CRYPTO_DEFLATE=m -CONFIG_CRYPTO_MICHAEL_MIC=m -CONFIG_CRYPTO_CRC32C=m -CONFIG_CRYPTO_CAMELLIA=m -CONFIG_CRYPTO_TEST=m -CONFIG_CRYPTO_AUTHENC=m CONFIG_CRYPTO_LZO=m # CONFIG_CRYPTO_HW is not set @@ -1072,9 +1093,11 @@ CONFIG_CRYPTO_LZO=m # Library routines # CONFIG_BITREVERSE=y +# CONFIG_GENERIC_FIND_FIRST_BIT is not set +# CONFIG_GENERIC_FIND_NEXT_BIT is not set CONFIG_CRC_CCITT=m CONFIG_CRC16=m -# CONFIG_CRC_ITU_T is not set +CONFIG_CRC_ITU_T=m CONFIG_CRC32=y # CONFIG_CRC7 is not set CONFIG_LIBCRC32C=m diff --git a/arch/m68k/configs/sun3_defconfig b/arch/m68k/configs/sun3_defconfig index bd2b9c4927c46d68bf25c71a83c10510aadcf900..a765f6f15d2cd56c468399c74cabdc36d17c386b 100644 --- a/arch/m68k/configs/sun3_defconfig +++ b/arch/m68k/configs/sun3_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.25-rc8 -# Wed Apr 2 20:46:22 2008 +# Linux kernel version: 2.6.26-rc2 +# Sun May 18 14:44:53 2008 # CONFIG_M68K=y CONFIG_MMU=y @@ -52,6 +52,7 @@ CONFIG_SYSCTL=y # CONFIG_EMBEDDED is not set CONFIG_UID16=y CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set CONFIG_HOTPLUG=y @@ -76,12 +77,14 @@ CONFIG_SLAB=y # CONFIG_HAVE_OPROFILE is not set # CONFIG_HAVE_KPROBES is not set # CONFIG_HAVE_KRETPROBES is not set +# CONFIG_HAVE_DMA_ATTRS is not set CONFIG_PROC_PAGE_MONITOR=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set @@ -130,6 +133,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_NEED_MULTIPLE_NODES=y # CONFIG_SPARSEMEM_STATIC is not set # CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 @@ -208,8 +212,10 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m CONFIG_INET6_XFRM_MODE_BEET=m CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m CONFIG_IPV6_SIT=m +CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=m # CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_MROUTE is not set # CONFIG_NETWORK_SECMARK is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set @@ -225,6 +231,7 @@ CONFIG_NF_CONNTRACK=m CONFIG_NF_CT_ACCT=y CONFIG_NF_CONNTRACK_MARK=y # CONFIG_NF_CONNTRACK_EVENTS is not set +# CONFIG_NF_CT_PROTO_DCCP is not set CONFIG_NF_CT_PROTO_GRE=m CONFIG_NF_CT_PROTO_SCTP=m CONFIG_NF_CT_PROTO_UDPLITE=m @@ -303,6 +310,8 @@ CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_NF_NAT_SNMP_BASIC=m CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_PROTO_UDPLITE=m +CONFIG_NF_NAT_PROTO_SCTP=m CONFIG_NF_NAT_FTP=m CONFIG_NF_NAT_IRC=m CONFIG_NF_NAT_TFTP=m @@ -396,8 +405,6 @@ CONFIG_IEEE80211=m CONFIG_IEEE80211_CRYPT_WEP=m CONFIG_IEEE80211_CRYPT_CCMP=m CONFIG_IEEE80211_CRYPT_TKIP=m -CONFIG_IEEE80211_SOFTMAC=m -# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -529,6 +536,7 @@ CONFIG_SUN3_82586=y # # CONFIG_WLAN_PRE80211 is not set # CONFIG_WLAN_80211 is not set +# CONFIG_IWLWIFI_LEDS is not set # CONFIG_WAN is not set CONFIG_PPP=m # CONFIG_PPP_MULTILINK is not set @@ -612,6 +620,7 @@ CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_DEVKMEM is not set # CONFIG_SERIAL_NONSTANDARD is not set # @@ -633,12 +642,7 @@ CONFIG_GEN_RTC_X=y # CONFIG_RAW_DRIVER is not set # CONFIG_TCG_TPM is not set # CONFIG_I2C is not set - -# -# SPI support -# # CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set @@ -655,12 +659,22 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set # # Multimedia devices # + +# +# Multimedia core support +# # CONFIG_VIDEO_DEV is not set # CONFIG_DVB_CORE is not set +# CONFIG_VIDEO_MEDIA is not set + +# +# Multimedia drivers +# # CONFIG_DAB is not set # @@ -678,8 +692,8 @@ CONFIG_FB=y # CONFIG_FB_SYS_FILLRECT is not set # CONFIG_FB_SYS_COPYAREA is not set # CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set # CONFIG_FB_SYS_FOPS is not set -CONFIG_FB_DEFERRED_IO=y # CONFIG_FB_SVGALIB is not set # CONFIG_FB_MACMODES is not set # CONFIG_FB_BACKLIGHT is not set @@ -726,11 +740,8 @@ CONFIG_HIDRAW=y # CONFIG_MMC is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set # CONFIG_RTC_CLASS is not set - -# -# Userspace I/O -# # CONFIG_UIO is not set # @@ -756,16 +767,15 @@ CONFIG_JFS_FS=m # CONFIG_JFS_SECURITY is not set # CONFIG_JFS_DEBUG is not set # CONFIG_JFS_STATISTICS is not set -CONFIG_FS_POSIX_ACL=y +# CONFIG_FS_POSIX_ACL is not set CONFIG_XFS_FS=m # CONFIG_XFS_QUOTA is not set -# CONFIG_XFS_SECURITY is not set # CONFIG_XFS_POSIX_ACL is not set # CONFIG_XFS_RT is not set -CONFIG_GFS2_FS=m -CONFIG_GFS2_FS_LOCKING_NOLOCK=m -CONFIG_GFS2_FS_LOCKING_DLM=m +# CONFIG_XFS_DEBUG is not set CONFIG_OCFS2_FS=m +CONFIG_OCFS2_FS_O2CB=m +CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set # CONFIG_OCFS2_DEBUG_FS is not set CONFIG_DNOTIFY=y @@ -837,12 +847,10 @@ CONFIG_NFS_FS=y CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set CONFIG_NFS_V4=y -# CONFIG_NFS_DIRECTIO is not set CONFIG_NFSD=m CONFIG_NFSD_V3=y # CONFIG_NFSD_V3_ACL is not set # CONFIG_NFSD_V4 is not set -CONFIG_NFSD_TCP=y CONFIG_ROOT_NFS=y CONFIG_LOCKD=y CONFIG_LOCKD_V4=y @@ -917,6 +925,7 @@ CONFIG_DLM=m # CONFIG_PRINTK_TIME is not set CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set # CONFIG_DEBUG_FS is not set @@ -936,53 +945,82 @@ CONFIG_ASYNC_CORE=m CONFIG_ASYNC_MEMCPY=m CONFIG_ASYNC_XOR=m CONFIG_CRYPTO=y + +# +# Crypto core or helper +# CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_AEAD=m CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_SEQIV=m CONFIG_CRYPTO_HASH=y CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_TEST=m + +# +# Authenticated Encryption with Associated Data +# +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_SEQIV=m + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_CTR=m +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_XTS=m + +# +# Hash modes +# CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_XCBC=m -CONFIG_CRYPTO_NULL=m + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=m CONFIG_CRYPTO_MD4=m CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_SHA1=m CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m -CONFIG_CRYPTO_WP512=m CONFIG_CRYPTO_TGR192=m -CONFIG_CRYPTO_GF128MUL=m -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=y -CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_LRW=m -CONFIG_CRYPTO_XTS=m -CONFIG_CRYPTO_CTR=m -CONFIG_CRYPTO_GCM=m -CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_CRYPTD=m -CONFIG_CRYPTO_DES=y -CONFIG_CRYPTO_FCRYPT=m -CONFIG_CRYPTO_BLOWFISH=m -CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_TWOFISH_COMMON=m -CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_WP512=m + +# +# Ciphers +# CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m CONFIG_CRYPTO_CAST5=m CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_TEA=m -CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_FCRYPT=m CONFIG_CRYPTO_KHAZAD=m -CONFIG_CRYPTO_ANUBIS=m -CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SALSA20=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m + +# +# Compression +# CONFIG_CRYPTO_DEFLATE=m -CONFIG_CRYPTO_MICHAEL_MIC=m -CONFIG_CRYPTO_CRC32C=m -CONFIG_CRYPTO_CAMELLIA=m -CONFIG_CRYPTO_TEST=m -CONFIG_CRYPTO_AUTHENC=m CONFIG_CRYPTO_LZO=m # CONFIG_CRYPTO_HW is not set @@ -990,9 +1028,11 @@ CONFIG_CRYPTO_LZO=m # Library routines # CONFIG_BITREVERSE=y +# CONFIG_GENERIC_FIND_FIRST_BIT is not set +# CONFIG_GENERIC_FIND_NEXT_BIT is not set CONFIG_CRC_CCITT=m CONFIG_CRC16=m -# CONFIG_CRC_ITU_T is not set +CONFIG_CRC_ITU_T=m CONFIG_CRC32=y # CONFIG_CRC7 is not set CONFIG_LIBCRC32C=m diff --git a/arch/m68k/configs/sun3x_defconfig b/arch/m68k/configs/sun3x_defconfig index f18154f1ef1fe42b82a07659654465c86dc25fe1..4315139374989933bf2a4d22b531c950ba84b8d6 100644 --- a/arch/m68k/configs/sun3x_defconfig +++ b/arch/m68k/configs/sun3x_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.25-rc8 -# Wed Apr 2 20:46:23 2008 +# Linux kernel version: 2.6.26-rc2 +# Sun May 18 14:44:54 2008 # CONFIG_M68K=y CONFIG_MMU=y @@ -52,6 +52,7 @@ CONFIG_SYSCTL=y # CONFIG_EMBEDDED is not set CONFIG_UID16=y CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set CONFIG_HOTPLUG=y @@ -76,12 +77,14 @@ CONFIG_SLAB=y # CONFIG_HAVE_OPROFILE is not set # CONFIG_HAVE_KPROBES is not set # CONFIG_HAVE_KRETPROBES is not set +# CONFIG_HAVE_DMA_ATTRS is not set CONFIG_PROC_PAGE_MONITOR=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set @@ -141,6 +144,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_NEED_MULTIPLE_NODES=y # CONFIG_SPARSEMEM_STATIC is not set # CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 @@ -219,8 +223,10 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m CONFIG_INET6_XFRM_MODE_BEET=m CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m CONFIG_IPV6_SIT=m +CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=m # CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_MROUTE is not set # CONFIG_NETWORK_SECMARK is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set @@ -236,6 +242,7 @@ CONFIG_NF_CONNTRACK=m CONFIG_NF_CT_ACCT=y CONFIG_NF_CONNTRACK_MARK=y # CONFIG_NF_CONNTRACK_EVENTS is not set +# CONFIG_NF_CT_PROTO_DCCP is not set CONFIG_NF_CT_PROTO_GRE=m CONFIG_NF_CT_PROTO_SCTP=m CONFIG_NF_CT_PROTO_UDPLITE=m @@ -314,6 +321,8 @@ CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_NF_NAT_SNMP_BASIC=m CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_PROTO_UDPLITE=m +CONFIG_NF_NAT_PROTO_SCTP=m CONFIG_NF_NAT_FTP=m CONFIG_NF_NAT_IRC=m CONFIG_NF_NAT_TFTP=m @@ -407,8 +416,6 @@ CONFIG_IEEE80211=m CONFIG_IEEE80211_CRYPT_WEP=m CONFIG_IEEE80211_CRYPT_CCMP=m CONFIG_IEEE80211_CRYPT_TKIP=m -CONFIG_IEEE80211_SOFTMAC=m -# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -539,6 +546,7 @@ CONFIG_SUN3LANCE=y # # CONFIG_WLAN_PRE80211 is not set # CONFIG_WLAN_80211 is not set +# CONFIG_IWLWIFI_LEDS is not set # CONFIG_WAN is not set CONFIG_PPP=m # CONFIG_PPP_MULTILINK is not set @@ -622,6 +630,7 @@ CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_DEVKMEM is not set # CONFIG_SERIAL_NONSTANDARD is not set # @@ -643,12 +652,7 @@ CONFIG_GEN_RTC_X=y # CONFIG_RAW_DRIVER is not set # CONFIG_TCG_TPM is not set # CONFIG_I2C is not set - -# -# SPI support -# # CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set @@ -665,12 +669,22 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set # # Multimedia devices # + +# +# Multimedia core support +# # CONFIG_VIDEO_DEV is not set # CONFIG_DVB_CORE is not set +# CONFIG_VIDEO_MEDIA is not set + +# +# Multimedia drivers +# # CONFIG_DAB is not set # @@ -688,8 +702,8 @@ CONFIG_FB=y # CONFIG_FB_SYS_FILLRECT is not set # CONFIG_FB_SYS_COPYAREA is not set # CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set # CONFIG_FB_SYS_FOPS is not set -CONFIG_FB_DEFERRED_IO=y # CONFIG_FB_SVGALIB is not set # CONFIG_FB_MACMODES is not set # CONFIG_FB_BACKLIGHT is not set @@ -736,11 +750,8 @@ CONFIG_HIDRAW=y # CONFIG_MMC is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set # CONFIG_RTC_CLASS is not set - -# -# Userspace I/O -# # CONFIG_UIO is not set # @@ -766,16 +777,15 @@ CONFIG_JFS_FS=m # CONFIG_JFS_SECURITY is not set # CONFIG_JFS_DEBUG is not set # CONFIG_JFS_STATISTICS is not set -CONFIG_FS_POSIX_ACL=y +# CONFIG_FS_POSIX_ACL is not set CONFIG_XFS_FS=m # CONFIG_XFS_QUOTA is not set -# CONFIG_XFS_SECURITY is not set # CONFIG_XFS_POSIX_ACL is not set # CONFIG_XFS_RT is not set -CONFIG_GFS2_FS=m -CONFIG_GFS2_FS_LOCKING_NOLOCK=m -CONFIG_GFS2_FS_LOCKING_DLM=m +# CONFIG_XFS_DEBUG is not set CONFIG_OCFS2_FS=m +CONFIG_OCFS2_FS_O2CB=m +CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set # CONFIG_OCFS2_DEBUG_FS is not set CONFIG_DNOTIFY=y @@ -847,12 +857,10 @@ CONFIG_NFS_FS=y CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set CONFIG_NFS_V4=y -# CONFIG_NFS_DIRECTIO is not set CONFIG_NFSD=m CONFIG_NFSD_V3=y # CONFIG_NFSD_V3_ACL is not set # CONFIG_NFSD_V4 is not set -CONFIG_NFSD_TCP=y CONFIG_ROOT_NFS=y CONFIG_LOCKD=y CONFIG_LOCKD_V4=y @@ -927,6 +935,7 @@ CONFIG_DLM=m # CONFIG_PRINTK_TIME is not set CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set # CONFIG_DEBUG_FS is not set @@ -946,53 +955,82 @@ CONFIG_ASYNC_CORE=m CONFIG_ASYNC_MEMCPY=m CONFIG_ASYNC_XOR=m CONFIG_CRYPTO=y + +# +# Crypto core or helper +# CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_AEAD=m CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_SEQIV=m CONFIG_CRYPTO_HASH=y CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_TEST=m + +# +# Authenticated Encryption with Associated Data +# +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_SEQIV=m + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_CTR=m +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_XTS=m + +# +# Hash modes +# CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_XCBC=m -CONFIG_CRYPTO_NULL=m + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=m CONFIG_CRYPTO_MD4=m CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_SHA1=m CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m -CONFIG_CRYPTO_WP512=m CONFIG_CRYPTO_TGR192=m -CONFIG_CRYPTO_GF128MUL=m -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=y -CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_LRW=m -CONFIG_CRYPTO_XTS=m -CONFIG_CRYPTO_CTR=m -CONFIG_CRYPTO_GCM=m -CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_CRYPTD=m -CONFIG_CRYPTO_DES=y -CONFIG_CRYPTO_FCRYPT=m -CONFIG_CRYPTO_BLOWFISH=m -CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_TWOFISH_COMMON=m -CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_WP512=m + +# +# Ciphers +# CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m CONFIG_CRYPTO_CAST5=m CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_TEA=m -CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_FCRYPT=m CONFIG_CRYPTO_KHAZAD=m -CONFIG_CRYPTO_ANUBIS=m -CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SALSA20=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m + +# +# Compression +# CONFIG_CRYPTO_DEFLATE=m -CONFIG_CRYPTO_MICHAEL_MIC=m -CONFIG_CRYPTO_CRC32C=m -CONFIG_CRYPTO_CAMELLIA=m -CONFIG_CRYPTO_TEST=m -CONFIG_CRYPTO_AUTHENC=m CONFIG_CRYPTO_LZO=m # CONFIG_CRYPTO_HW is not set @@ -1000,9 +1038,11 @@ CONFIG_CRYPTO_LZO=m # Library routines # CONFIG_BITREVERSE=y +# CONFIG_GENERIC_FIND_FIRST_BIT is not set +# CONFIG_GENERIC_FIND_NEXT_BIT is not set CONFIG_CRC_CCITT=m CONFIG_CRC16=m -# CONFIG_CRC_ITU_T is not set +CONFIG_CRC_ITU_T=m CONFIG_CRC32=y # CONFIG_CRC7 is not set CONFIG_LIBCRC32C=m diff --git a/arch/m68k/kernel/head.S b/arch/m68k/kernel/head.S index faa6764f1d13617c0b9580d0aef9c8641a325691..f513f530de9132670946f0d96705d08ce9d0c58e 100644 --- a/arch/m68k/kernel/head.S +++ b/arch/m68k/kernel/head.S @@ -1434,7 +1434,7 @@ L(mmu_fixup_done): #endif #ifdef CONFIG_HP300 - is_not_hp300(1f) + is_not_hp300(2f) /* * Fix up the iobase register to point to the new location of the LEDs. */ diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c index 5de4e4ed76abd4daf3f2483c2df36d2ede861d74..7888cdf91f5dafba1d157547d8ddb4b1a7f268a9 100644 --- a/arch/m68k/kernel/process.c +++ b/arch/m68k/kernel/process.c @@ -41,7 +41,6 @@ * setup. */ static struct fs_struct init_fs = INIT_FS; -static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS(init_signals); static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); struct mm_struct init_mm = INIT_MM(init_mm); diff --git a/arch/m68k/kernel/setup.c b/arch/m68k/kernel/setup.c index bba650312fd9fa65ac73d3408017cee1e3fb2dce..a9fb83a8c1801fbbc018bb1fb6ed034da3bcea09 100644 --- a/arch/m68k/kernel/setup.c +++ b/arch/m68k/kernel/setup.c @@ -41,11 +41,12 @@ #endif unsigned long m68k_machtype; -unsigned long m68k_cputype; EXPORT_SYMBOL(m68k_machtype); +unsigned long m68k_cputype; EXPORT_SYMBOL(m68k_cputype); unsigned long m68k_fputype; unsigned long m68k_mmutype; +EXPORT_SYMBOL(m68k_mmutype); #ifdef CONFIG_VME unsigned long vme_brdtype; EXPORT_SYMBOL(vme_brdtype); @@ -345,19 +346,19 @@ void __init setup_arch(char **cmdline_p) /* set ISA defs early as possible */ #if defined(CONFIG_ISA) && defined(MULTI_ISA) -#if defined(CONFIG_Q40) if (MACH_IS_Q40) { - isa_type = Q40_ISA; + isa_type = ISA_TYPE_Q40; isa_sex = 0; } -#elif defined(CONFIG_GG2) +#ifdef CONFIG_GG2 if (MACH_IS_AMIGA && AMIGAHW_PRESENT(GG2_ISA)) { - isa_type = GG2_ISA; + isa_type = ISA_TYPE_GG2; isa_sex = 0; } -#elif defined(CONFIG_AMIGA_PCMCIA) +#endif +#ifdef CONFIG_AMIGA_PCMCIA if (MACH_IS_AMIGA && AMIGAHW_PRESENT(PCMCIA)) { - isa_type = AG_ISA; + isa_type = ISA_TYPE_AG; isa_sex = 1; } #endif diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig index 07eb4c4bab8243723ead643a13d6f5611a42d032..8e8441587c22bcb566976360ec34e53d6145fcd8 100644 --- a/arch/m68knommu/Kconfig +++ b/arch/m68knommu/Kconfig @@ -671,6 +671,9 @@ config ROMKERNEL endchoice +if COLDFIRE +source "kernel/Kconfig.preempt" +endif source "mm/Kconfig" endmenu diff --git a/arch/m68knommu/kernel/init_task.c b/arch/m68knommu/kernel/init_task.c index 3897043a126ace45eef56983c764d5d103f2a3ed..344c01aede08b3e85b1b3f7b0b454ca8ae78d879 100644 --- a/arch/m68knommu/kernel/init_task.c +++ b/arch/m68knommu/kernel/init_task.c @@ -13,7 +13,6 @@ #include static struct fs_struct init_fs = INIT_FS; -static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS(init_signals); static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); struct mm_struct init_mm = INIT_MM(init_mm); diff --git a/arch/m68knommu/kernel/vmlinux.lds.S b/arch/m68knommu/kernel/vmlinux.lds.S index 5592e0bf951f555f9efb18c55838215b80cc9db8..93e69236ed6f8bfd1b6b38408aa380fc43d247de 100644 --- a/arch/m68knommu/kernel/vmlinux.lds.S +++ b/arch/m68knommu/kernel/vmlinux.lds.S @@ -114,6 +114,16 @@ SECTIONS { *(__kcrctab_gpl) __stop___kcrctab_gpl = .; + /* Kernel symbol table: Normal unused symbols */ + __start___kcrctab_unused = .; + *(__kcrctab_unused) + __stop___kcrctab_unused = .; + + /* Kernel symbol table: GPL-only unused symbols */ + __start___kcrctab_unused_gpl = .; + *(__kcrctab_unused_gpl) + __stop___kcrctab_unused_gpl = .; + /* Kernel symbol table: GPL-future symbols */ __start___kcrctab_gpl_future = .; *(__kcrctab_gpl_future) diff --git a/arch/mips/au1000/common/Makefile b/arch/mips/au1000/common/Makefile index 90e2d7a46e8e2c7d96a86fb61500b11c9ddad4f5..dd0e19dacfcff444ab7b4ff07912ff8b0bcde082 100644 --- a/arch/mips/au1000/common/Makefile +++ b/arch/mips/au1000/common/Makefile @@ -1,9 +1,8 @@ # -# Copyright 2000 MontaVista Software Inc. -# Author: MontaVista Software, Inc. -# ppopov@mvista.com or source@mvista.com +# Copyright 2000, 2008 MontaVista Software Inc. +# Author: MontaVista Software, Inc. # -# Makefile for the Alchemy Au1000 CPU, generic files. +# Makefile for the Alchemy Au1xx0 CPUs, generic files. # obj-y += prom.o irq.o puts.o time.o reset.o \ diff --git a/arch/mips/au1000/common/au1xxx_irqmap.c b/arch/mips/au1000/common/au1xxx_irqmap.c index 37a10a01de9d30619c2a7c5feeabfac77cbb2c5f..c7ca1596394cc2a4e18c2f83c0f735ed7171d2b6 100644 --- a/arch/mips/au1000/common/au1xxx_irqmap.c +++ b/arch/mips/au1000/common/au1xxx_irqmap.c @@ -40,20 +40,20 @@ struct au1xxx_irqmap __initdata au1xxx_ic0_map[] = { #if defined(CONFIG_SOC_AU1000) - { AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0}, - { AU1000_UART1_INT, INTC_INT_HIGH_LEVEL, 0}, - { AU1000_UART2_INT, INTC_INT_HIGH_LEVEL, 0}, - { AU1000_UART3_INT, INTC_INT_HIGH_LEVEL, 0}, - { AU1000_SSI0_INT, INTC_INT_HIGH_LEVEL, 0}, - { AU1000_SSI1_INT, INTC_INT_HIGH_LEVEL, 0}, - { AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0}, - { AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0}, - { AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0}, - { AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0}, - { AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0}, - { AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0}, - { AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0}, - { AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0 }, + { AU1000_UART1_INT, INTC_INT_HIGH_LEVEL, 0 }, + { AU1000_UART2_INT, INTC_INT_HIGH_LEVEL, 0 }, + { AU1000_UART3_INT, INTC_INT_HIGH_LEVEL, 0 }, + { AU1000_SSI0_INT, INTC_INT_HIGH_LEVEL, 0 }, + { AU1000_SSI1_INT, INTC_INT_HIGH_LEVEL, 0 }, + { AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0 }, + { AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0 }, + { AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0 }, + { AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0 }, + { AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0 }, + { AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0 }, + { AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0 }, + { AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0 }, { AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 }, { AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, { AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, @@ -62,32 +62,32 @@ struct au1xxx_irqmap __initdata au1xxx_ic0_map[] = { { AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, { AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, { AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 }, - { AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0}, - { AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0 }, + { AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0 }, { AU1000_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 }, { AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 }, { AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 }, { AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 }, - { AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, - { AU1000_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0 }, + { AU1000_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0 }, { AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 }, #elif defined(CONFIG_SOC_AU1500) - { AU1500_UART0_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1500_UART0_INT, INTC_INT_HIGH_LEVEL, 0 }, { AU1000_PCI_INTA, INTC_INT_LOW_LEVEL, 0 }, { AU1000_PCI_INTB, INTC_INT_LOW_LEVEL, 0 }, - { AU1500_UART3_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1500_UART3_INT, INTC_INT_HIGH_LEVEL, 0 }, { AU1000_PCI_INTC, INTC_INT_LOW_LEVEL, 0 }, { AU1000_PCI_INTD, INTC_INT_LOW_LEVEL, 0 }, - { AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0}, - { AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0}, - { AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0}, - { AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0}, - { AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0}, - { AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0}, - { AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0}, - { AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0 }, + { AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0 }, + { AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0 }, + { AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0 }, + { AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0 }, + { AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0 }, + { AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0 }, + { AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0 }, { AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 }, { AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, { AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, @@ -100,26 +100,26 @@ struct au1xxx_irqmap __initdata au1xxx_ic0_map[] = { { AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 }, { AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 }, { AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 }, - { AU1500_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, - { AU1500_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1500_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0 }, + { AU1500_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0 }, { AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 }, #elif defined(CONFIG_SOC_AU1100) - { AU1100_UART0_INT, INTC_INT_HIGH_LEVEL, 0}, - { AU1100_UART1_INT, INTC_INT_HIGH_LEVEL, 0}, - { AU1100_SD_INT, INTC_INT_HIGH_LEVEL, 0}, - { AU1100_UART3_INT, INTC_INT_HIGH_LEVEL, 0}, - { AU1000_SSI0_INT, INTC_INT_HIGH_LEVEL, 0}, - { AU1000_SSI1_INT, INTC_INT_HIGH_LEVEL, 0}, - { AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0}, - { AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0}, - { AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0}, - { AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0}, - { AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0}, - { AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0}, - { AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0}, - { AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0}, + { AU1100_UART0_INT, INTC_INT_HIGH_LEVEL, 0 }, + { AU1100_UART1_INT, INTC_INT_HIGH_LEVEL, 0 }, + { AU1100_SD_INT, INTC_INT_HIGH_LEVEL, 0 }, + { AU1100_UART3_INT, INTC_INT_HIGH_LEVEL, 0 }, + { AU1000_SSI0_INT, INTC_INT_HIGH_LEVEL, 0 }, + { AU1000_SSI1_INT, INTC_INT_HIGH_LEVEL, 0 }, + { AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0 }, + { AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0 }, + { AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0 }, + { AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0 }, + { AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0 }, + { AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0 }, + { AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0 }, + { AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0 }, { AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 }, { AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, { AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, @@ -128,33 +128,33 @@ struct au1xxx_irqmap __initdata au1xxx_ic0_map[] = { { AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, { AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, { AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 }, - { AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0}, - { AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0 }, + { AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0 }, { AU1000_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 }, { AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 }, { AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 }, { AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 }, - { AU1100_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, - /*{ AU1000_GPIO215_208_INT, INTC_INT_HIGH_LEVEL, 0},*/ - { AU1100_LCD_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1100_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0 }, + /* { AU1000_GPIO215_208_INT, INTC_INT_HIGH_LEVEL, 0 }, */ + { AU1100_LCD_INT, INTC_INT_HIGH_LEVEL, 0 }, { AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 }, #elif defined(CONFIG_SOC_AU1550) - { AU1550_UART0_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1550_UART0_INT, INTC_INT_HIGH_LEVEL, 0 }, { AU1550_PCI_INTA, INTC_INT_LOW_LEVEL, 0 }, { AU1550_PCI_INTB, INTC_INT_LOW_LEVEL, 0 }, - { AU1550_DDMA_INT, INTC_INT_HIGH_LEVEL, 0}, - { AU1550_CRYPTO_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1550_DDMA_INT, INTC_INT_HIGH_LEVEL, 0 }, + { AU1550_CRYPTO_INT, INTC_INT_HIGH_LEVEL, 0 }, { AU1550_PCI_INTC, INTC_INT_LOW_LEVEL, 0 }, { AU1550_PCI_INTD, INTC_INT_LOW_LEVEL, 0 }, { AU1550_PCI_RST_INT, INTC_INT_LOW_LEVEL, 0 }, - { AU1550_UART1_INT, INTC_INT_HIGH_LEVEL, 0}, - { AU1550_UART3_INT, INTC_INT_HIGH_LEVEL, 0}, - { AU1550_PSC0_INT, INTC_INT_HIGH_LEVEL, 0}, - { AU1550_PSC1_INT, INTC_INT_HIGH_LEVEL, 0}, - { AU1550_PSC2_INT, INTC_INT_HIGH_LEVEL, 0}, - { AU1550_PSC3_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1550_UART1_INT, INTC_INT_HIGH_LEVEL, 0 }, + { AU1550_UART3_INT, INTC_INT_HIGH_LEVEL, 0 }, + { AU1550_PSC0_INT, INTC_INT_HIGH_LEVEL, 0 }, + { AU1550_PSC1_INT, INTC_INT_HIGH_LEVEL, 0 }, + { AU1550_PSC2_INT, INTC_INT_HIGH_LEVEL, 0 }, + { AU1550_PSC3_INT, INTC_INT_HIGH_LEVEL, 0 }, { AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 }, { AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, { AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, @@ -163,26 +163,26 @@ struct au1xxx_irqmap __initdata au1xxx_ic0_map[] = { { AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, { AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, { AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 }, - { AU1550_NAND_INT, INTC_INT_RISE_EDGE, 0}, + { AU1550_NAND_INT, INTC_INT_RISE_EDGE, 0 }, { AU1550_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 }, { AU1550_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 }, { AU1550_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 }, - { AU1550_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, - { AU1550_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1550_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0 }, + { AU1550_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0 }, #elif defined(CONFIG_SOC_AU1200) - { AU1200_UART0_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1200_UART0_INT, INTC_INT_HIGH_LEVEL, 0 }, { AU1200_SWT_INT, INTC_INT_RISE_EDGE, 0 }, - { AU1200_SD_INT, INTC_INT_HIGH_LEVEL, 0}, - { AU1200_DDMA_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1200_SD_INT, INTC_INT_HIGH_LEVEL, 0 }, + { AU1200_DDMA_INT, INTC_INT_HIGH_LEVEL, 0 }, { AU1200_MAE_BE_INT, INTC_INT_HIGH_LEVEL, 0 }, - { AU1200_UART1_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1200_UART1_INT, INTC_INT_HIGH_LEVEL, 0 }, { AU1200_MAE_FE_INT, INTC_INT_HIGH_LEVEL, 0 }, - { AU1200_PSC0_INT, INTC_INT_HIGH_LEVEL, 0}, - { AU1200_PSC1_INT, INTC_INT_HIGH_LEVEL, 0}, - { AU1200_AES_INT, INTC_INT_HIGH_LEVEL, 0}, - { AU1200_CAMERA_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1200_PSC0_INT, INTC_INT_HIGH_LEVEL, 0 }, + { AU1200_PSC1_INT, INTC_INT_HIGH_LEVEL, 0 }, + { AU1200_AES_INT, INTC_INT_HIGH_LEVEL, 0 }, + { AU1200_CAMERA_INT, INTC_INT_HIGH_LEVEL, 0 }, { AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 }, { AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, { AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, @@ -191,10 +191,10 @@ struct au1xxx_irqmap __initdata au1xxx_ic0_map[] = { { AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, { AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, { AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 }, - { AU1200_NAND_INT, INTC_INT_RISE_EDGE, 0}, + { AU1200_NAND_INT, INTC_INT_RISE_EDGE, 0 }, { AU1200_USB_INT, INTC_INT_HIGH_LEVEL, 0 }, - { AU1200_LCD_INT, INTC_INT_HIGH_LEVEL, 0}, - { AU1200_MAE_BOTH_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1200_LCD_INT, INTC_INT_HIGH_LEVEL, 0 }, + { AU1200_MAE_BOTH_INT, INTC_INT_HIGH_LEVEL, 0 }, #else #error "Error: Unknown Alchemy SOC" @@ -203,4 +203,3 @@ struct au1xxx_irqmap __initdata au1xxx_ic0_map[] = { }; int __initdata au1xxx_ic0_nr_irqs = ARRAY_SIZE(au1xxx_ic0_map); - diff --git a/arch/mips/au1000/common/clocks.c b/arch/mips/au1000/common/clocks.c index 3ce6cace0eb0d618294f0701228f0a9761c74e59..46f8ee0e265771be26b8833d54e19d949344ed3d 100644 --- a/arch/mips/au1000/common/clocks.c +++ b/arch/mips/au1000/common/clocks.c @@ -1,10 +1,9 @@ /* * BRIEF MODULE DESCRIPTION - * Simple Au1000 clocks routines. + * Simple Au1xx0 clocks routines. * - * Copyright 2001 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com + * Copyright 2001, 2008 MontaVista Software Inc. + * Author: MontaVista Software, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -30,8 +29,8 @@ #include #include -static unsigned int au1x00_clock; // Hz -static unsigned int lcd_clock; // KHz +static unsigned int au1x00_clock; /* Hz */ +static unsigned int lcd_clock; /* KHz */ static unsigned long uart_baud_base; /* @@ -47,8 +46,6 @@ unsigned int get_au1x00_speed(void) return au1x00_clock; } - - /* * The UART baud base is not known at compile time ... if * we want to be able to use the same code on different @@ -73,24 +70,23 @@ void set_au1x00_uart_baud_base(unsigned long new_baud_base) void set_au1x00_lcd_clock(void) { unsigned int static_cfg0; - unsigned int sys_busclk = - (get_au1x00_speed()/1000) / - ((int)(au_readl(SYS_POWERCTRL)&0x03) + 2); + unsigned int sys_busclk = (get_au1x00_speed() / 1000) / + ((int)(au_readl(SYS_POWERCTRL) & 0x03) + 2); static_cfg0 = au_readl(MEM_STCFG0); - if (static_cfg0 & (1<<11)) + if (static_cfg0 & (1 << 11)) lcd_clock = sys_busclk / 5; /* note: BCLK switching fails with D5 */ else lcd_clock = sys_busclk / 4; if (lcd_clock > 50000) /* Epson MAX */ - printk("warning: LCD clock too high (%d KHz)\n", lcd_clock); + printk(KERN_WARNING "warning: LCD clock too high (%u KHz)\n", + lcd_clock); } unsigned int get_au1x00_lcd_clock(void) { return lcd_clock; } - EXPORT_SYMBOL(get_au1x00_lcd_clock); diff --git a/arch/mips/au1000/common/cputable.c b/arch/mips/au1000/common/cputable.c index 8c93a05d73826e804ff82781ae5f50d28ed35029..ba6430bc2d0300d78b9b66d3fa4870a12083eb82 100644 --- a/arch/mips/au1000/common/cputable.c +++ b/arch/mips/au1000/common/cputable.c @@ -14,7 +14,7 @@ #include -struct cpu_spec* cur_cpu_spec[NR_CPUS]; +struct cpu_spec *cur_cpu_spec[NR_CPUS]; /* With some thought, we can probably use the mask to reduce the * size of the table. @@ -39,8 +39,7 @@ struct cpu_spec cpu_specs[] = { { 0x00000000, 0x00000000, "Unknown Au1xxx", 1, 0, 0 } }; -void -set_cpuspec(void) +void set_cpuspec(void) { struct cpu_spec *sp; u32 prid; diff --git a/arch/mips/au1000/common/dbdma.c b/arch/mips/au1000/common/dbdma.c index 53377dfc0640da33d85db3b7f47db242872ca5b1..42d555236de15bbd4bc731554fb54a8ab305d6d1 100644 --- a/arch/mips/au1000/common/dbdma.c +++ b/arch/mips/au1000/common/dbdma.c @@ -53,12 +53,11 @@ */ static DEFINE_SPINLOCK(au1xxx_dbdma_spin_lock); -/* I couldn't find a macro that did this...... -*/ +/* I couldn't find a macro that did this... */ #define ALIGN_ADDR(x, a) ((((u32)(x)) + (a-1)) & ~(a-1)) static dbdma_global_t *dbdma_gptr = (dbdma_global_t *)DDMA_GLOBAL_BASE; -static int dbdma_initialized=0; +static int dbdma_initialized; static void au1xxx_dbdma_init(void); static dbdev_tab_t dbdev_tab[] = { @@ -149,7 +148,7 @@ static dbdev_tab_t dbdev_tab[] = { { DSCR_CMD0_NAND_FLASH, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 }, -#endif // CONFIG_SOC_AU1200 +#endif /* CONFIG_SOC_AU1200 */ { DSCR_CMD0_THROTTLE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, { DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, @@ -177,8 +176,7 @@ static dbdev_tab_t dbdev_tab[] = { static chan_tab_t *chan_tab_ptr[NUM_DBDMA_CHANS]; -static dbdev_tab_t * -find_dbdev_id(u32 id) +static dbdev_tab_t *find_dbdev_id(u32 id) { int i; dbdev_tab_t *p; @@ -190,29 +188,27 @@ find_dbdev_id(u32 id) return NULL; } -void * au1xxx_ddma_get_nextptr_virt(au1x_ddma_desc_t *dp) +void *au1xxx_ddma_get_nextptr_virt(au1x_ddma_desc_t *dp) { - return phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr)); + return phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr)); } EXPORT_SYMBOL(au1xxx_ddma_get_nextptr_virt); -u32 -au1xxx_ddma_add_device(dbdev_tab_t *dev) +u32 au1xxx_ddma_add_device(dbdev_tab_t *dev) { u32 ret = 0; - dbdev_tab_t *p=NULL; - static u16 new_id=0x1000; + dbdev_tab_t *p; + static u16 new_id = 0x1000; p = find_dbdev_id(~0); - if ( NULL != p ) - { + if (NULL != p) { memcpy(p, dev, sizeof(dbdev_tab_t)); p->dev_id = DSCR_DEV2CUSTOM_ID(new_id, dev->dev_id); ret = p->dev_id; new_id++; #if 0 - printk("add_device: id:%x flags:%x padd:%x\n", - p->dev_id, p->dev_flags, p->dev_physaddr ); + printk(KERN_DEBUG "add_device: id:%x flags:%x padd:%x\n", + p->dev_id, p->dev_flags, p->dev_physaddr); #endif } @@ -220,10 +216,8 @@ au1xxx_ddma_add_device(dbdev_tab_t *dev) } EXPORT_SYMBOL(au1xxx_ddma_add_device); -/* Allocate a channel and return a non-zero descriptor if successful. -*/ -u32 -au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid, +/* Allocate a channel and return a non-zero descriptor if successful. */ +u32 au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid, void (*callback)(int, void *), void *callparam) { unsigned long flags; @@ -234,7 +228,8 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid, chan_tab_t *ctp; au1x_dma_chan_t *cp; - /* We do the intialization on the first channel allocation. + /* + * We do the intialization on the first channel allocation. * We have to wait because of the interrupt handler initialization * which can't be done successfully during board set up. */ @@ -242,16 +237,17 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid, au1xxx_dbdma_init(); dbdma_initialized = 1; - if ((stp = find_dbdev_id(srcid)) == NULL) + stp = find_dbdev_id(srcid); + if (stp == NULL) return 0; - if ((dtp = find_dbdev_id(destid)) == NULL) + dtp = find_dbdev_id(destid); + if (dtp == NULL) return 0; used = 0; rv = 0; - /* Check to see if we can get both channels. - */ + /* Check to see if we can get both channels. */ spin_lock_irqsave(&au1xxx_dbdma_spin_lock, flags); if (!(stp->dev_flags & DEV_FLAGS_INUSE) || (stp->dev_flags & DEV_FLAGS_ANYUSE)) { @@ -261,35 +257,30 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid, (dtp->dev_flags & DEV_FLAGS_ANYUSE)) { /* Got destination */ dtp->dev_flags |= DEV_FLAGS_INUSE; - } - else { - /* Can't get dest. Release src. - */ + } else { + /* Can't get dest. Release src. */ stp->dev_flags &= ~DEV_FLAGS_INUSE; used++; } - } - else { + } else used++; - } spin_unlock_irqrestore(&au1xxx_dbdma_spin_lock, flags); if (!used) { - /* Let's see if we can allocate a channel for it. - */ + /* Let's see if we can allocate a channel for it. */ ctp = NULL; chan = 0; spin_lock_irqsave(&au1xxx_dbdma_spin_lock, flags); - for (i=0; ichan_callback = callback; ctp->chan_callparam = callparam; - /* Initialize channel configuration. - */ + /* Initialize channel configuration. */ i = 0; if (stp->dev_intlevel) i |= DDMA_CFG_SED; @@ -326,8 +316,7 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid, * operations. */ rv = (u32)(&chan_tab_ptr[chan]); - } - else { + } else { /* Release devices */ stp->dev_flags &= ~DEV_FLAGS_INUSE; dtp->dev_flags &= ~DEV_FLAGS_INUSE; @@ -337,11 +326,11 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid, } EXPORT_SYMBOL(au1xxx_dbdma_chan_alloc); -/* Set the device width if source or destination is a FIFO. +/* + * Set the device width if source or destination is a FIFO. * Should be 8, 16, or 32 bits. */ -u32 -au1xxx_dbdma_set_devwidth(u32 chanid, int bits) +u32 au1xxx_dbdma_set_devwidth(u32 chanid, int bits) { u32 rv; chan_tab_t *ctp; @@ -365,10 +354,8 @@ au1xxx_dbdma_set_devwidth(u32 chanid, int bits) } EXPORT_SYMBOL(au1xxx_dbdma_set_devwidth); -/* Allocate a descriptor ring, initializing as much as possible. -*/ -u32 -au1xxx_dbdma_ring_alloc(u32 chanid, int entries) +/* Allocate a descriptor ring, initializing as much as possible. */ +u32 au1xxx_dbdma_ring_alloc(u32 chanid, int entries) { int i; u32 desc_base, srcid, destid; @@ -378,43 +365,45 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries) dbdev_tab_t *stp, *dtp; au1x_ddma_desc_t *dp; - /* I guess we could check this to be within the + /* + * I guess we could check this to be within the * range of the table...... */ ctp = *((chan_tab_t **)chanid); stp = ctp->chan_src; dtp = ctp->chan_dest; - /* The descriptors must be 32-byte aligned. There is a + /* + * The descriptors must be 32-byte aligned. There is a * possibility the allocation will give us such an address, * and if we try that first we are likely to not waste larger * slabs of memory. */ desc_base = (u32)kmalloc(entries * sizeof(au1x_ddma_desc_t), - GFP_KERNEL|GFP_DMA); + GFP_KERNEL|GFP_DMA); if (desc_base == 0) return 0; if (desc_base & 0x1f) { - /* Lost....do it again, allocate extra, and round + /* + * Lost....do it again, allocate extra, and round * the address base. */ kfree((const void *)desc_base); i = entries * sizeof(au1x_ddma_desc_t); i += (sizeof(au1x_ddma_desc_t) - 1); - if ((desc_base = (u32)kmalloc(i, GFP_KERNEL|GFP_DMA)) == 0) + desc_base = (u32)kmalloc(i, GFP_KERNEL|GFP_DMA); + if (desc_base == 0) return 0; desc_base = ALIGN_ADDR(desc_base, sizeof(au1x_ddma_desc_t)); } dp = (au1x_ddma_desc_t *)desc_base; - /* Keep track of the base descriptor. - */ + /* Keep track of the base descriptor. */ ctp->chan_desc_base = dp; - /* Initialize the rings with as much information as we know. - */ + /* Initialize the rings with as much information as we know. */ srcid = stp->dev_id; destid = dtp->dev_id; @@ -426,11 +415,12 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries) cmd0 |= DSCR_CMD0_IE | DSCR_CMD0_CV; cmd0 |= DSCR_CMD0_ST(DSCR_CMD0_ST_NOCHANGE); - /* is it mem to mem transfer? */ - if(((DSCR_CUSTOM2DEV_ID(srcid) == DSCR_CMD0_THROTTLE) || (DSCR_CUSTOM2DEV_ID(srcid) == DSCR_CMD0_ALWAYS)) && - ((DSCR_CUSTOM2DEV_ID(destid) == DSCR_CMD0_THROTTLE) || (DSCR_CUSTOM2DEV_ID(destid) == DSCR_CMD0_ALWAYS))) { - cmd0 |= DSCR_CMD0_MEM; - } + /* Is it mem to mem transfer? */ + if (((DSCR_CUSTOM2DEV_ID(srcid) == DSCR_CMD0_THROTTLE) || + (DSCR_CUSTOM2DEV_ID(srcid) == DSCR_CMD0_ALWAYS)) && + ((DSCR_CUSTOM2DEV_ID(destid) == DSCR_CMD0_THROTTLE) || + (DSCR_CUSTOM2DEV_ID(destid) == DSCR_CMD0_ALWAYS))) + cmd0 |= DSCR_CMD0_MEM; switch (stp->dev_devwidth) { case 8: @@ -458,15 +448,17 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries) break; } - /* If the device is marked as an in/out FIFO, ensure it is + /* + * If the device is marked as an in/out FIFO, ensure it is * set non-coherent. */ if (stp->dev_flags & DEV_FLAGS_IN) - cmd0 |= DSCR_CMD0_SN; /* Source in fifo */ + cmd0 |= DSCR_CMD0_SN; /* Source in FIFO */ if (dtp->dev_flags & DEV_FLAGS_OUT) - cmd0 |= DSCR_CMD0_DN; /* Destination out fifo */ + cmd0 |= DSCR_CMD0_DN; /* Destination out FIFO */ - /* Set up source1. For now, assume no stride and increment. + /* + * Set up source1. For now, assume no stride and increment. * A channel attribute update can change this later. */ switch (stp->dev_tsize) { @@ -485,19 +477,19 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries) break; } - /* If source input is fifo, set static address. - */ + /* If source input is FIFO, set static address. */ if (stp->dev_flags & DEV_FLAGS_IN) { - if ( stp->dev_flags & DEV_FLAGS_BURSTABLE ) + if (stp->dev_flags & DEV_FLAGS_BURSTABLE) src1 |= DSCR_SRC1_SAM(DSCR_xAM_BURST); else - src1 |= DSCR_SRC1_SAM(DSCR_xAM_STATIC); - + src1 |= DSCR_SRC1_SAM(DSCR_xAM_STATIC); } + if (stp->dev_physaddr) src0 = stp->dev_physaddr; - /* Set up dest1. For now, assume no stride and increment. + /* + * Set up dest1. For now, assume no stride and increment. * A channel attribute update can change this later. */ switch (dtp->dev_tsize) { @@ -516,22 +508,24 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries) break; } - /* If destination output is fifo, set static address. - */ + /* If destination output is FIFO, set static address. */ if (dtp->dev_flags & DEV_FLAGS_OUT) { - if ( dtp->dev_flags & DEV_FLAGS_BURSTABLE ) - dest1 |= DSCR_DEST1_DAM(DSCR_xAM_BURST); - else - dest1 |= DSCR_DEST1_DAM(DSCR_xAM_STATIC); + if (dtp->dev_flags & DEV_FLAGS_BURSTABLE) + dest1 |= DSCR_DEST1_DAM(DSCR_xAM_BURST); + else + dest1 |= DSCR_DEST1_DAM(DSCR_xAM_STATIC); } + if (dtp->dev_physaddr) dest0 = dtp->dev_physaddr; #if 0 - printk("did:%x sid:%x cmd0:%x cmd1:%x source0:%x source1:%x dest0:%x dest1:%x\n", - dtp->dev_id, stp->dev_id, cmd0, cmd1, src0, src1, dest0, dest1 ); + printk(KERN_DEBUG "did:%x sid:%x cmd0:%x cmd1:%x source0:%x " + "source1:%x dest0:%x dest1:%x\n", + dtp->dev_id, stp->dev_id, cmd0, cmd1, src0, + src1, dest0, dest1); #endif - for (i=0; idscr_cmd0 = cmd0; dp->dscr_cmd1 = cmd1; dp->dscr_source0 = src0; @@ -545,49 +539,49 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries) dp++; } - /* Make last descrptor point to the first. - */ + /* Make last descrptor point to the first. */ dp--; dp->dscr_nxtptr = DSCR_NXTPTR(virt_to_phys(ctp->chan_desc_base)); ctp->get_ptr = ctp->put_ptr = ctp->cur_ptr = ctp->chan_desc_base; - return (u32)(ctp->chan_desc_base); + return (u32)ctp->chan_desc_base; } EXPORT_SYMBOL(au1xxx_dbdma_ring_alloc); -/* Put a source buffer into the DMA ring. +/* + * Put a source buffer into the DMA ring. * This updates the source pointer and byte count. Normally used * for memory to fifo transfers. */ -u32 -_au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags) +u32 _au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags) { chan_tab_t *ctp; au1x_ddma_desc_t *dp; - /* I guess we could check this to be within the + /* + * I guess we could check this to be within the * range of the table...... */ - ctp = *((chan_tab_t **)chanid); + ctp = *(chan_tab_t **)chanid; - /* We should have multiple callers for a particular channel, + /* + * We should have multiple callers for a particular channel, * an interrupt doesn't affect this pointer nor the descriptor, * so no locking should be needed. */ dp = ctp->put_ptr; - /* If the descriptor is valid, we are way ahead of the DMA + /* + * If the descriptor is valid, we are way ahead of the DMA * engine, so just return an error condition. */ - if (dp->dscr_cmd0 & DSCR_CMD0_V) { + if (dp->dscr_cmd0 & DSCR_CMD0_V) return 0; - } - /* Load up buffer address and byte count. - */ + /* Load up buffer address and byte count. */ dp->dscr_source0 = virt_to_phys(buf); dp->dscr_cmd1 = nbytes; - /* Check flags */ + /* Check flags */ if (flags & DDMA_FLAGS_IE) dp->dscr_cmd0 |= DSCR_CMD0_IE; if (flags & DDMA_FLAGS_NOIE) @@ -595,23 +589,21 @@ _au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags) /* * There is an errata on the Au1200/Au1550 parts that could result - * in "stale" data being DMA'd. It has to do with the snoop logic on - * the dache eviction buffer. NONCOHERENT_IO is on by default for - * these parts. If it is fixedin the future, these dma_cache_inv will + * in "stale" data being DMA'ed. It has to do with the snoop logic on + * the cache eviction buffer. DMA_NONCOHERENT is on by default for + * these parts. If it is fixed in the future, these dma_cache_inv will * just be nothing more than empty macros. See io.h. - * */ + */ dma_cache_wback_inv((unsigned long)buf, nbytes); - dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */ + dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */ au_sync(); dma_cache_wback_inv((unsigned long)dp, sizeof(dp)); - ctp->chan_ptr->ddma_dbell = 0; + ctp->chan_ptr->ddma_dbell = 0; - /* Get next descriptor pointer. - */ + /* Get next descriptor pointer. */ ctp->put_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr)); - /* return something not zero. - */ + /* Return something non-zero. */ return nbytes; } EXPORT_SYMBOL(_au1xxx_dbdma_put_source); @@ -654,81 +646,77 @@ _au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes, u32 flags) dp->dscr_dest0 = virt_to_phys(buf); dp->dscr_cmd1 = nbytes; #if 0 - printk("cmd0:%x cmd1:%x source0:%x source1:%x dest0:%x dest1:%x\n", - dp->dscr_cmd0, dp->dscr_cmd1, dp->dscr_source0, - dp->dscr_source1, dp->dscr_dest0, dp->dscr_dest1 ); + printk(KERN_DEBUG "cmd0:%x cmd1:%x source0:%x source1:%x dest0:%x dest1:%x\n", + dp->dscr_cmd0, dp->dscr_cmd1, dp->dscr_source0, + dp->dscr_source1, dp->dscr_dest0, dp->dscr_dest1); #endif /* * There is an errata on the Au1200/Au1550 parts that could result in - * "stale" data being DMA'd. It has to do with the snoop logic on the - * dache eviction buffer. NONCOHERENT_IO is on by default for these - * parts. If it is fixedin the future, these dma_cache_inv will just + * "stale" data being DMA'ed. It has to do with the snoop logic on the + * cache eviction buffer. DMA_NONCOHERENT is on by default for these + * parts. If it is fixed in the future, these dma_cache_inv will just * be nothing more than empty macros. See io.h. - * */ + */ dma_cache_inv((unsigned long)buf, nbytes); dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */ au_sync(); dma_cache_wback_inv((unsigned long)dp, sizeof(dp)); - ctp->chan_ptr->ddma_dbell = 0; + ctp->chan_ptr->ddma_dbell = 0; - /* Get next descriptor pointer. - */ + /* Get next descriptor pointer. */ ctp->put_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr)); - /* return something not zero. - */ + /* Return something non-zero. */ return nbytes; } EXPORT_SYMBOL(_au1xxx_dbdma_put_dest); -/* Get a destination buffer into the DMA ring. +/* + * Get a destination buffer into the DMA ring. * Normally used to get a full buffer from the ring during fifo * to memory transfers. This does not set the valid bit, you will * have to put another destination buffer to keep the DMA going. */ -u32 -au1xxx_dbdma_get_dest(u32 chanid, void **buf, int *nbytes) +u32 au1xxx_dbdma_get_dest(u32 chanid, void **buf, int *nbytes) { chan_tab_t *ctp; au1x_ddma_desc_t *dp; u32 rv; - /* I guess we could check this to be within the + /* + * I guess we could check this to be within the * range of the table...... */ ctp = *((chan_tab_t **)chanid); - /* We should have multiple callers for a particular channel, + /* + * We should have multiple callers for a particular channel, * an interrupt doesn't affect this pointer nor the descriptor, * so no locking should be needed. */ dp = ctp->get_ptr; - /* If the descriptor is valid, we are way ahead of the DMA + /* + * If the descriptor is valid, we are way ahead of the DMA * engine, so just return an error condition. */ if (dp->dscr_cmd0 & DSCR_CMD0_V) return 0; - /* Return buffer address and byte count. - */ + /* Return buffer address and byte count. */ *buf = (void *)(phys_to_virt(dp->dscr_dest0)); *nbytes = dp->dscr_cmd1; rv = dp->dscr_stat; - /* Get next descriptor pointer. - */ + /* Get next descriptor pointer. */ ctp->get_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr)); - /* return something not zero. - */ + /* Return something non-zero. */ return rv; } - EXPORT_SYMBOL_GPL(au1xxx_dbdma_get_dest); -void -au1xxx_dbdma_stop(u32 chanid) +void au1xxx_dbdma_stop(u32 chanid) { chan_tab_t *ctp; au1x_dma_chan_t *cp; @@ -743,7 +731,7 @@ au1xxx_dbdma_stop(u32 chanid) udelay(1); halt_timeout++; if (halt_timeout > 100) { - printk("warning: DMA channel won't halt\n"); + printk(KERN_WARNING "warning: DMA channel won't halt\n"); break; } } @@ -753,12 +741,12 @@ au1xxx_dbdma_stop(u32 chanid) } EXPORT_SYMBOL(au1xxx_dbdma_stop); -/* Start using the current descriptor pointer. If the dbdma encounters - * a not valid descriptor, it will stop. In this case, we can just +/* + * Start using the current descriptor pointer. If the DBDMA encounters + * a non-valid descriptor, it will stop. In this case, we can just * continue by adding a buffer to the list and starting again. */ -void -au1xxx_dbdma_start(u32 chanid) +void au1xxx_dbdma_start(u32 chanid) { chan_tab_t *ctp; au1x_dma_chan_t *cp; @@ -773,8 +761,7 @@ au1xxx_dbdma_start(u32 chanid) } EXPORT_SYMBOL(au1xxx_dbdma_start); -void -au1xxx_dbdma_reset(u32 chanid) +void au1xxx_dbdma_reset(u32 chanid) { chan_tab_t *ctp; au1x_ddma_desc_t *dp; @@ -784,14 +771,14 @@ au1xxx_dbdma_reset(u32 chanid) ctp = *((chan_tab_t **)chanid); ctp->get_ptr = ctp->put_ptr = ctp->cur_ptr = ctp->chan_desc_base; - /* Run through the descriptors and reset the valid indicator. - */ + /* Run through the descriptors and reset the valid indicator. */ dp = ctp->chan_desc_base; do { dp->dscr_cmd0 &= ~DSCR_CMD0_V; - /* reset our SW status -- this is used to determine - * if a descriptor is in use by upper level SW. Since + /* + * Reset our software status -- this is used to determine + * if a descriptor is in use by upper level software. Since * posting can reset 'V' bit. */ dp->sw_status = 0; @@ -800,8 +787,7 @@ au1xxx_dbdma_reset(u32 chanid) } EXPORT_SYMBOL(au1xxx_dbdma_reset); -u32 -au1xxx_get_dma_residue(u32 chanid) +u32 au1xxx_get_dma_residue(u32 chanid) { chan_tab_t *ctp; au1x_dma_chan_t *cp; @@ -810,18 +796,15 @@ au1xxx_get_dma_residue(u32 chanid) ctp = *((chan_tab_t **)chanid); cp = ctp->chan_ptr; - /* This is only valid if the channel is stopped. - */ + /* This is only valid if the channel is stopped. */ rv = cp->ddma_bytecnt; au_sync(); return rv; } - EXPORT_SYMBOL_GPL(au1xxx_get_dma_residue); -void -au1xxx_dbdma_chan_free(u32 chanid) +void au1xxx_dbdma_chan_free(u32 chanid) { chan_tab_t *ctp; dbdev_tab_t *stp, *dtp; @@ -842,8 +825,7 @@ au1xxx_dbdma_chan_free(u32 chanid) } EXPORT_SYMBOL(au1xxx_dbdma_chan_free); -static irqreturn_t -dbdma_interrupt(int irq, void *dev_id) +static irqreturn_t dbdma_interrupt(int irq, void *dev_id) { u32 intstat; u32 chan_index; @@ -859,13 +841,12 @@ dbdma_interrupt(int irq, void *dev_id) cp = ctp->chan_ptr; dp = ctp->cur_ptr; - /* Reset interrupt. - */ + /* Reset interrupt. */ cp->ddma_irq = 0; au_sync(); if (ctp->chan_callback) - (ctp->chan_callback)(irq, ctp->chan_callparam); + ctp->chan_callback(irq, ctp->chan_callparam); ctp->cur_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr)); return IRQ_RETVAL(1); @@ -890,47 +871,47 @@ static void au1xxx_dbdma_init(void) if (request_irq(irq_nr, dbdma_interrupt, IRQF_DISABLED, "Au1xxx dbdma", (void *)dbdma_gptr)) - printk("Can't get 1550 dbdma irq"); + printk(KERN_ERR "Can't get 1550 dbdma irq"); } -void -au1xxx_dbdma_dump(u32 chanid) +void au1xxx_dbdma_dump(u32 chanid) { - chan_tab_t *ctp; - au1x_ddma_desc_t *dp; - dbdev_tab_t *stp, *dtp; - au1x_dma_chan_t *cp; - u32 i = 0; + chan_tab_t *ctp; + au1x_ddma_desc_t *dp; + dbdev_tab_t *stp, *dtp; + au1x_dma_chan_t *cp; + u32 i = 0; ctp = *((chan_tab_t **)chanid); stp = ctp->chan_src; dtp = ctp->chan_dest; cp = ctp->chan_ptr; - printk("Chan %x, stp %x (dev %d) dtp %x (dev %d) \n", - (u32)ctp, (u32)stp, stp - dbdev_tab, (u32)dtp, dtp - dbdev_tab); - printk("desc base %x, get %x, put %x, cur %x\n", - (u32)(ctp->chan_desc_base), (u32)(ctp->get_ptr), - (u32)(ctp->put_ptr), (u32)(ctp->cur_ptr)); - - printk("dbdma chan %x\n", (u32)cp); - printk("cfg %08x, desptr %08x, statptr %08x\n", - cp->ddma_cfg, cp->ddma_desptr, cp->ddma_statptr); - printk("dbell %08x, irq %08x, stat %08x, bytecnt %08x\n", - cp->ddma_dbell, cp->ddma_irq, cp->ddma_stat, cp->ddma_bytecnt); - - - /* Run through the descriptors - */ + printk(KERN_DEBUG "Chan %x, stp %x (dev %d) dtp %x (dev %d) \n", + (u32)ctp, (u32)stp, stp - dbdev_tab, (u32)dtp, + dtp - dbdev_tab); + printk(KERN_DEBUG "desc base %x, get %x, put %x, cur %x\n", + (u32)(ctp->chan_desc_base), (u32)(ctp->get_ptr), + (u32)(ctp->put_ptr), (u32)(ctp->cur_ptr)); + + printk(KERN_DEBUG "dbdma chan %x\n", (u32)cp); + printk(KERN_DEBUG "cfg %08x, desptr %08x, statptr %08x\n", + cp->ddma_cfg, cp->ddma_desptr, cp->ddma_statptr); + printk(KERN_DEBUG "dbell %08x, irq %08x, stat %08x, bytecnt %08x\n", + cp->ddma_dbell, cp->ddma_irq, cp->ddma_stat, + cp->ddma_bytecnt); + + /* Run through the descriptors */ dp = ctp->chan_desc_base; do { - printk("Dp[%d]= %08x, cmd0 %08x, cmd1 %08x\n", - i++, (u32)dp, dp->dscr_cmd0, dp->dscr_cmd1); - printk("src0 %08x, src1 %08x, dest0 %08x, dest1 %08x\n", - dp->dscr_source0, dp->dscr_source1, dp->dscr_dest0, dp->dscr_dest1); - printk("stat %08x, nxtptr %08x\n", - dp->dscr_stat, dp->dscr_nxtptr); + printk(KERN_DEBUG "Dp[%d]= %08x, cmd0 %08x, cmd1 %08x\n", + i++, (u32)dp, dp->dscr_cmd0, dp->dscr_cmd1); + printk(KERN_DEBUG "src0 %08x, src1 %08x, dest0 %08x, dest1 %08x\n", + dp->dscr_source0, dp->dscr_source1, + dp->dscr_dest0, dp->dscr_dest1); + printk(KERN_DEBUG "stat %08x, nxtptr %08x\n", + dp->dscr_stat, dp->dscr_nxtptr); dp = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr)); } while (dp != ctp->chan_desc_base); } @@ -938,32 +919,33 @@ au1xxx_dbdma_dump(u32 chanid) /* Put a descriptor into the DMA ring. * This updates the source/destination pointers and byte count. */ -u32 -au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr ) +u32 au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr) { chan_tab_t *ctp; au1x_ddma_desc_t *dp; - u32 nbytes=0; + u32 nbytes = 0; - /* I guess we could check this to be within the - * range of the table...... - */ + /* + * I guess we could check this to be within the + * range of the table...... + */ ctp = *((chan_tab_t **)chanid); - /* We should have multiple callers for a particular channel, - * an interrupt doesn't affect this pointer nor the descriptor, - * so no locking should be needed. - */ + /* + * We should have multiple callers for a particular channel, + * an interrupt doesn't affect this pointer nor the descriptor, + * so no locking should be needed. + */ dp = ctp->put_ptr; - /* If the descriptor is valid, we are way ahead of the DMA - * engine, so just return an error condition. - */ + /* + * If the descriptor is valid, we are way ahead of the DMA + * engine, so just return an error condition. + */ if (dp->dscr_cmd0 & DSCR_CMD0_V) return 0; - /* Load up buffer addresses and byte count. - */ + /* Load up buffer addresses and byte count. */ dp->dscr_dest0 = dscr->dscr_dest0; dp->dscr_source0 = dscr->dscr_source0; dp->dscr_dest1 = dscr->dscr_dest1; @@ -975,14 +957,11 @@ au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr ) dp->dscr_cmd0 |= dscr->dscr_cmd0 | DSCR_CMD0_V; ctp->chan_ptr->ddma_dbell = 0; - /* Get next descriptor pointer. - */ + /* Get next descriptor pointer. */ ctp->put_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr)); - /* return something not zero. - */ + /* Return something non-zero. */ return nbytes; } #endif /* defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) */ - diff --git a/arch/mips/au1000/common/dbg_io.c b/arch/mips/au1000/common/dbg_io.c index eae1bb2ca26e72ab115c35e97030fbe52a5d877a..af5be7df2f2a9f379d9c0a06125d20542479029b 100644 --- a/arch/mips/au1000/common/dbg_io.c +++ b/arch/mips/au1000/common/dbg_io.c @@ -1,3 +1,4 @@ +#include #include @@ -8,12 +9,6 @@ * uart to be used for debugging. */ #define DEBUG_BASE UART_DEBUG_BASE -/**/ - -/* we need uint32 uint8 */ -/* #include "types.h" */ -typedef unsigned char uint8; -typedef unsigned int uint32; #define UART16550_BAUD_2400 2400 #define UART16550_BAUD_4800 4800 @@ -51,17 +46,15 @@ typedef unsigned int uint32; #define UART_MOD_CNTRL 0x100 /* Module Control */ /* memory-mapped read/write of the port */ -#define UART16550_READ(y) (au_readl(DEBUG_BASE + y) & 0xff) -#define UART16550_WRITE(y, z) (au_writel(z&0xff, DEBUG_BASE + y)) +#define UART16550_READ(y) (au_readl(DEBUG_BASE + y) & 0xff) +#define UART16550_WRITE(y, z) (au_writel(z & 0xff, DEBUG_BASE + y)) extern unsigned long calc_clock(void); -void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop) +void debugInit(u32 baud, u8 data, u8 parity, u8 stop) { - - if (UART16550_READ(UART_MOD_CNTRL) != 0x3) { + if (UART16550_READ(UART_MOD_CNTRL) != 0x3) UART16550_WRITE(UART_MOD_CNTRL, 3); - } calc_clock(); /* disable interrupts */ @@ -69,7 +62,7 @@ void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop) /* set up baud rate */ { - uint32 divisor; + u32 divisor; /* set divisor */ divisor = get_au1x00_uart_baud_base() / baud; @@ -80,9 +73,9 @@ void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop) UART16550_WRITE(UART_LCR, (data | parity | stop)); } -static int remoteDebugInitialized = 0; +static int remoteDebugInitialized; -uint8 getDebugChar(void) +u8 getDebugChar(void) { if (!remoteDebugInitialized) { remoteDebugInitialized = 1; @@ -92,15 +85,13 @@ uint8 getDebugChar(void) UART16550_STOP_1BIT); } - while((UART16550_READ(UART_LSR) & 0x1) == 0); + while ((UART16550_READ(UART_LSR) & 0x1) == 0); return UART16550_READ(UART_RX); } -int putDebugChar(uint8 byte) +int putDebugChar(u8 byte) { -// int i; - if (!remoteDebugInitialized) { remoteDebugInitialized = 1; debugInit(UART16550_BAUD_115200, @@ -109,9 +100,8 @@ int putDebugChar(uint8 byte) UART16550_STOP_1BIT); } - while ((UART16550_READ(UART_LSR)&0x40) == 0); + while ((UART16550_READ(UART_LSR) & 0x40) == 0); UART16550_WRITE(UART_TX, byte); - //for (i=0;i<0xfff;i++); return 1; } diff --git a/arch/mips/au1000/common/dma.c b/arch/mips/au1000/common/dma.c index 95f69ea146e90a49d5ffdca4605af5fbb64df99e..d6fbda232e6ae5b8cdf92eee346dbdae091fe1f2 100644 --- a/arch/mips/au1000/common/dma.c +++ b/arch/mips/au1000/common/dma.c @@ -1,12 +1,11 @@ /* * * BRIEF MODULE DESCRIPTION - * A DMA channel allocator for Au1000. API is modeled loosely off of + * A DMA channel allocator for Au1x00. API is modeled loosely off of * linux/kernel/dma.c. * - * Copyright 2000 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * stevel@mvista.com or source@mvista.com + * Copyright 2000, 2008 MontaVista Software Inc. + * Author: MontaVista Software, Inc. * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org) * * This program is free software; you can redistribute it and/or modify it @@ -39,7 +38,8 @@ #include #include -#if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1100) +#if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1500) || \ + defined(CONFIG_SOC_AU1100) /* * A note on resource allocation: * @@ -56,7 +56,6 @@ * returned from request_dma. */ - DEFINE_SPINLOCK(au1000_dma_spin_lock); struct dma_chan au1000_dma_table[NUM_AU1000_DMA_CHANNELS] = { @@ -71,7 +70,7 @@ struct dma_chan au1000_dma_table[NUM_AU1000_DMA_CHANNELS] = { }; EXPORT_SYMBOL(au1000_dma_table); -// Device FIFO addresses and default DMA modes +/* Device FIFO addresses and default DMA modes */ static const struct dma_dev { unsigned int fifo_addr; unsigned int dma_mode; @@ -80,8 +79,8 @@ static const struct dma_dev { {UART0_ADDR + UART_RX, 0}, {0, 0}, {0, 0}, - {AC97C_DATA, DMA_DW16 }, // coherent - {AC97C_DATA, DMA_DR | DMA_DW16 }, // coherent + {AC97C_DATA, DMA_DW16 }, /* coherent */ + {AC97C_DATA, DMA_DR | DMA_DW16 }, /* coherent */ {UART3_ADDR + UART_TX, DMA_DW8 | DMA_NC}, {UART3_ADDR + UART_RX, DMA_DR | DMA_DW8 | DMA_NC}, {USBD_EP0RD, DMA_DR | DMA_DW8 | DMA_NC}, @@ -101,10 +100,10 @@ int au1000_dma_read_proc(char *buf, char **start, off_t fpos, struct dma_chan *chan; for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++) { - if ((chan = get_dma_chan(i)) != NULL) { + chan = get_dma_chan(i); + if (chan != NULL) len += sprintf(buf + len, "%2d: %s\n", i, chan->dev_str); - } } if (fpos >= len) { @@ -113,18 +112,19 @@ int au1000_dma_read_proc(char *buf, char **start, off_t fpos, return 0; } *start = buf + fpos; - if ((len -= fpos) > length) + len -= fpos; + if (len > length) return length; *eof = 1; return len; } -// Device FIFO addresses and default DMA modes - 2nd bank +/* Device FIFO addresses and default DMA modes - 2nd bank */ static const struct dma_dev dma_dev_table_bank2[DMA_NUM_DEV_BANK2] = { - {SD0_XMIT_FIFO, DMA_DS | DMA_DW8}, // coherent - {SD0_RECV_FIFO, DMA_DS | DMA_DR | DMA_DW8}, // coherent - {SD1_XMIT_FIFO, DMA_DS | DMA_DW8}, // coherent - {SD1_RECV_FIFO, DMA_DS | DMA_DR | DMA_DW8} // coherent + { SD0_XMIT_FIFO, DMA_DS | DMA_DW8 }, /* coherent */ + { SD0_RECV_FIFO, DMA_DS | DMA_DR | DMA_DW8 }, /* coherent */ + { SD1_XMIT_FIFO, DMA_DS | DMA_DW8 }, /* coherent */ + { SD1_RECV_FIFO, DMA_DS | DMA_DR | DMA_DW8 } /* coherent */ }; void dump_au1000_dma_channel(unsigned int dmanr) @@ -150,7 +150,6 @@ void dump_au1000_dma_channel(unsigned int dmanr) au_readl(chan->io + DMA_BUFFER1_COUNT)); } - /* * Finds a free channel, and binds the requested device to it. * Returns the allocated channel number, or negative on error. @@ -169,14 +168,14 @@ int request_au1000_dma(int dev_id, const char *dev_str, if (dev_id < 0 || dev_id >= (DMA_NUM_DEV + DMA_NUM_DEV_BANK2)) return -EINVAL; #else - if (dev_id < 0 || dev_id >= DMA_NUM_DEV) + if (dev_id < 0 || dev_id >= DMA_NUM_DEV) return -EINVAL; #endif - for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++) { + for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++) if (au1000_dma_table[i].dev_id < 0) break; - } + if (i == NUM_AU1000_DMA_CHANNELS) return -ENODEV; @@ -185,15 +184,15 @@ int request_au1000_dma(int dev_id, const char *dev_str, if (dev_id >= DMA_NUM_DEV) { dev_id -= DMA_NUM_DEV; dev = &dma_dev_table_bank2[dev_id]; - } else { + } else dev = &dma_dev_table[dev_id]; - } if (irqhandler) { chan->irq = AU1000_DMA_INT_BASE + i; chan->irq_dev = irq_dev_id; - if ((ret = request_irq(chan->irq, irqhandler, irqflags, - dev_str, chan->irq_dev))) { + ret = request_irq(chan->irq, irqhandler, irqflags, dev_str, + chan->irq_dev); + if (ret) { chan->irq = 0; chan->irq_dev = NULL; return ret; @@ -203,7 +202,7 @@ int request_au1000_dma(int dev_id, const char *dev_str, chan->irq_dev = NULL; } - // fill it in + /* fill it in */ chan->io = DMA_CHANNEL_BASE + i * DMA_CHANNEL_LEN; chan->dev_id = dev_id; chan->dev_str = dev_str; @@ -220,8 +219,9 @@ EXPORT_SYMBOL(request_au1000_dma); void free_au1000_dma(unsigned int dmanr) { struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) { - printk("Trying to free DMA%d\n", dmanr); + printk(KERN_ERR "Error trying to free DMA%d\n", dmanr); return; } @@ -235,4 +235,4 @@ void free_au1000_dma(unsigned int dmanr) } EXPORT_SYMBOL(free_au1000_dma); -#endif // AU1000 AU1500 AU1100 +#endif /* AU1000 AU1500 AU1100 */ diff --git a/arch/mips/au1000/common/gpio.c b/arch/mips/au1000/common/gpio.c index 52545258997157c5bd849f637ca7acef02a8a4fd..b485d94ce8a5055d4e28b35f8dec1c7fc3b2af9e 100644 --- a/arch/mips/au1000/common/gpio.c +++ b/arch/mips/au1000/common/gpio.c @@ -69,7 +69,7 @@ static int au1xxx_gpio2_direction_output(unsigned gpio, int value) static int au1xxx_gpio1_read(unsigned gpio) { - return ((gpio1->pinstaterd >> gpio) & 0x01); + return (gpio1->pinstaterd >> gpio) & 0x01; } static void au1xxx_gpio1_write(unsigned gpio, int value) @@ -104,7 +104,6 @@ int au1xxx_gpio_get_value(unsigned gpio) else return au1xxx_gpio1_read(gpio); } - EXPORT_SYMBOL(au1xxx_gpio_get_value); void au1xxx_gpio_set_value(unsigned gpio, int value) @@ -118,7 +117,6 @@ void au1xxx_gpio_set_value(unsigned gpio, int value) else au1xxx_gpio1_write(gpio, value); } - EXPORT_SYMBOL(au1xxx_gpio_set_value); int au1xxx_gpio_direction_input(unsigned gpio) @@ -132,7 +130,6 @@ int au1xxx_gpio_direction_input(unsigned gpio) return au1xxx_gpio1_direction_input(gpio); } - EXPORT_SYMBOL(au1xxx_gpio_direction_input); int au1xxx_gpio_direction_output(unsigned gpio, int value) @@ -146,5 +143,4 @@ int au1xxx_gpio_direction_output(unsigned gpio, int value) return au1xxx_gpio1_direction_output(gpio, value); } - EXPORT_SYMBOL(au1xxx_gpio_direction_output); diff --git a/arch/mips/au1000/common/irq.c b/arch/mips/au1000/common/irq.c index f0626992fd75fce7b4f735d91c9db199ccdaba55..40c6ceceb5f9149f4f5a352c504cb6301b22a6fc 100644 --- a/arch/mips/au1000/common/irq.c +++ b/arch/mips/au1000/common/irq.c @@ -210,10 +210,8 @@ static inline void mask_and_ack_either_edge_irq(unsigned int irq_nr) au_sync(); } - static inline void mask_and_ack_level_irq(unsigned int irq_nr) { - local_disable_irq(irq_nr); au_sync(); #if defined(CONFIG_MIPS_PB1000) @@ -263,14 +261,14 @@ void restore_local_and_enable(int controller, unsigned long mask) unsigned long flags, new_mask; spin_lock_irqsave(&irq_lock, flags); - for (i = 0; i < 32; i++) { + for (i = 0; i < 32; i++) if (mask & (1 << i)) { if (controller) local_enable_irq(i + 32); else local_enable_irq(i); } - } + if (controller) new_mask = au_readl(IC1_MASKSET); else diff --git a/arch/mips/au1000/common/pci.c b/arch/mips/au1000/common/pci.c index 7e966b31e3e1e2a383eaff451ba6b572aa2e2592..7866cf50cf99ce7ca5943a8f5a1a9217375d9ea4 100644 --- a/arch/mips/au1000/common/pci.c +++ b/arch/mips/au1000/common/pci.c @@ -2,9 +2,8 @@ * BRIEF MODULE DESCRIPTION * Alchemy/AMD Au1x00 PCI support. * - * Copyright 2001-2003, 2007 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com + * Copyright 2001-2003, 2007-2008 MontaVista Software Inc. + * Author: MontaVista Software, Inc. * * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org) * @@ -86,9 +85,9 @@ static int __init au1x_pci_setup(void) u32 prid = read_c0_prid(); if ((prid & 0xFF000000) == 0x01000000 && prid < 0x01030202) { - au_writel((1 << 16) | au_readl(Au1500_PCI_CFG), - Au1500_PCI_CFG); - printk("Non-coherent PCI accesses enabled\n"); + au_writel((1 << 16) | au_readl(Au1500_PCI_CFG), + Au1500_PCI_CFG); + printk(KERN_INFO "Non-coherent PCI accesses enabled\n"); } } #endif diff --git a/arch/mips/au1000/common/platform.c b/arch/mips/au1000/common/platform.c index 31d2a2270878832354a02e4cd7f6b4b6eaf03516..8cae7753ef79931612eb5070e2236014df07fe78 100644 --- a/arch/mips/au1000/common/platform.c +++ b/arch/mips/au1000/common/platform.c @@ -269,8 +269,8 @@ static struct platform_device au1x00_pcmcia_device = { #ifdef SMBUS_PSC_BASE static struct resource pbdb_smbus_resources[] = { { - .start = SMBUS_PSC_BASE, - .end = SMBUS_PSC_BASE + 0x24 - 1, + .start = CPHYSADDR(SMBUS_PSC_BASE), + .end = CPHYSADDR(SMBUS_PSC_BASE + 0xfffff), .flags = IORESOURCE_MEM, }, }; @@ -302,16 +302,17 @@ static struct platform_device *au1xxx_platform_devices[] __initdata = { #endif }; -int __init au1xxx_platform_init(void) +static int __init au1xxx_platform_init(void) { unsigned int uartclk = get_au1x00_uart_baud_base() * 16; int i; /* Fill up uartclk. */ - for (i = 0; au1x00_uart_data[i].flags ; i++) + for (i = 0; au1x00_uart_data[i].flags; i++) au1x00_uart_data[i].uartclk = uartclk; - return platform_add_devices(au1xxx_platform_devices, ARRAY_SIZE(au1xxx_platform_devices)); + return platform_add_devices(au1xxx_platform_devices, + ARRAY_SIZE(au1xxx_platform_devices)); } arch_initcall(au1xxx_platform_init); diff --git a/arch/mips/au1000/common/power.c b/arch/mips/au1000/common/power.c index a8cd2c1b9e1b59f313ae98a0c6e8579e0afc6dca..2166b9e1e80cf4fe1fe3452a4db5f8f852662005 100644 --- a/arch/mips/au1000/common/power.c +++ b/arch/mips/au1000/common/power.c @@ -1,10 +1,9 @@ /* * BRIEF MODULE DESCRIPTION - * Au1000 Power Management routines. + * Au1xx0 Power Management routines. * - * Copyright 2001 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com + * Copyright 2001, 2008 MontaVista Software Inc. + * Author: MontaVista Software, Inc. * * Some of the routines are right out of init/main.c, whose * copyrights apply here. @@ -43,10 +42,10 @@ #ifdef CONFIG_PM #define DEBUG 1 -#ifdef DEBUG -# define DPRINTK(fmt, args...) printk("%s: " fmt, __func__, ## args) +#ifdef DEBUG +#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__, ## args) #else -# define DPRINTK(fmt, args...) +#define DPRINTK(fmt, args...) #endif static void au1000_calibrate_delay(void); @@ -57,7 +56,8 @@ extern void local_enable_irq(unsigned int irq_nr); static DEFINE_SPINLOCK(pm_lock); -/* We need to save/restore a bunch of core registers that are +/* + * We need to save/restore a bunch of core registers that are * either volatile or reset to some state across a processor sleep. * If reading a register doesn't provide a proper result for a * later restore, we have to provide a function for loading that @@ -78,24 +78,25 @@ static unsigned int sleep_usbhost_enable; static unsigned int sleep_usbdev_enable; static unsigned int sleep_static_memctlr[4][3]; -/* Define this to cause the value you write to /proc/sys/pm/sleep to +/* + * Define this to cause the value you write to /proc/sys/pm/sleep to * set the TOY timer for the amount of time you want to sleep. * This is done mainly for testing, but may be useful in other cases. * The value is number of 32KHz ticks to sleep. */ #define SLEEP_TEST_TIMEOUT 1 -#ifdef SLEEP_TEST_TIMEOUT -static int sleep_ticks; +#ifdef SLEEP_TEST_TIMEOUT +static int sleep_ticks; void wakeup_counter0_set(int ticks); #endif -static void -save_core_regs(void) +static void save_core_regs(void) { extern void save_au1xxx_intctl(void); extern void pm_eth0_shutdown(void); - /* Do the serial ports.....these really should be a pm_* + /* + * Do the serial ports.....these really should be a pm_* * registered function by the driver......but of course the * standard serial driver doesn't understand our Au1xxx * unique registers. @@ -106,27 +107,24 @@ save_core_regs(void) sleep_uart0_clkdiv = au_readl(UART0_ADDR + UART_CLK); sleep_uart0_enable = au_readl(UART0_ADDR + UART_MOD_CNTRL); - /* Shutdown USB host/device. - */ + /* Shutdown USB host/device. */ sleep_usbhost_enable = au_readl(USB_HOST_CONFIG); - /* There appears to be some undocumented reset register.... - */ + /* There appears to be some undocumented reset register.... */ au_writel(0, 0xb0100004); au_sync(); au_writel(0, USB_HOST_CONFIG); au_sync(); sleep_usbdev_enable = au_readl(USBD_ENABLE); au_writel(0, USBD_ENABLE); au_sync(); - /* Save interrupt controller state. - */ + /* Save interrupt controller state. */ save_au1xxx_intctl(); - /* Clocks and PLLs. - */ + /* Clocks and PLLs. */ sleep_aux_pll_cntrl = au_readl(SYS_AUXPLL); - /* We don't really need to do this one, but unless we + /* + * We don't really need to do this one, but unless we * write it again it won't have a valid value if we * happen to read it. */ @@ -134,8 +132,7 @@ save_core_regs(void) sleep_pin_function = au_readl(SYS_PINFUNC); - /* Save the static memory controller configuration. - */ + /* Save the static memory controller configuration. */ sleep_static_memctlr[0][0] = au_readl(MEM_STCFG0); sleep_static_memctlr[0][1] = au_readl(MEM_STTIME0); sleep_static_memctlr[0][2] = au_readl(MEM_STADDR0); @@ -150,8 +147,7 @@ save_core_regs(void) sleep_static_memctlr[3][2] = au_readl(MEM_STADDR3); } -static void -restore_core_regs(void) +static void restore_core_regs(void) { extern void restore_au1xxx_intctl(void); extern void wakeup_counter0_adjust(void); @@ -160,8 +156,7 @@ restore_core_regs(void) au_writel(sleep_cpu_pll_cntrl, SYS_CPUPLL); au_sync(); au_writel(sleep_pin_function, SYS_PINFUNC); au_sync(); - /* Restore the static memory controller configuration. - */ + /* Restore the static memory controller configuration. */ au_writel(sleep_static_memctlr[0][0], MEM_STCFG0); au_writel(sleep_static_memctlr[0][1], MEM_STTIME0); au_writel(sleep_static_memctlr[0][2], MEM_STADDR0); @@ -175,7 +170,8 @@ restore_core_regs(void) au_writel(sleep_static_memctlr[3][1], MEM_STTIME3); au_writel(sleep_static_memctlr[3][2], MEM_STADDR3); - /* Enable the UART if it was enabled before sleep. + /* + * Enable the UART if it was enabled before sleep. * I guess I should define module control bits........ */ if (sleep_uart0_enable & 0x02) { @@ -202,7 +198,7 @@ void wakeup_from_suspend(void) int au_sleep(void) { unsigned long wakeup, flags; - extern void save_and_sleep(void); + extern void save_and_sleep(void); spin_lock_irqsave(&pm_lock, flags); @@ -210,23 +206,22 @@ int au_sleep(void) flush_cache_all(); - /** The code below is all system dependent and we should probably + /** + ** The code below is all system dependent and we should probably ** have a function call out of here to set this up. You need ** to configure the GPIO or timer interrupts that will bring ** you out of sleep. ** For testing, the TOY counter wakeup is useful. **/ - #if 0 au_writel(au_readl(SYS_PINSTATERD) & ~(1 << 11), SYS_PINSTATERD); - /* gpio 6 can cause a wake up event */ + /* GPIO 6 can cause a wake up event */ wakeup = au_readl(SYS_WAKEMSK); wakeup &= ~(1 << 8); /* turn off match20 wakeup */ - wakeup |= 1 << 6; /* turn on gpio 6 wakeup */ + wakeup |= 1 << 6; /* turn on GPIO 6 wakeup */ #else - /* For testing, allow match20 to wake us up. - */ + /* For testing, allow match20 to wake us up. */ #ifdef SLEEP_TEST_TIMEOUT wakeup_counter0_set(sleep_ticks); #endif @@ -240,7 +235,8 @@ int au_sleep(void) save_and_sleep(); - /* after a wakeup, the cpu vectors back to 0x1fc00000 so + /* + * After a wakeup, the cpu vectors back to 0x1fc00000, so * it's up to the boot code to get us back here. */ restore_core_regs(); @@ -248,24 +244,22 @@ int au_sleep(void) return 0; } -static int pm_do_sleep(ctl_table * ctl, int write, struct file *file, - void __user *buffer, size_t * len, loff_t *ppos) +static int pm_do_sleep(ctl_table *ctl, int write, struct file *file, + void __user *buffer, size_t *len, loff_t *ppos) { #ifdef SLEEP_TEST_TIMEOUT #define TMPBUFLEN2 16 char buf[TMPBUFLEN2], *p; #endif - if (!write) { + if (!write) *len = 0; - } else { + else { #ifdef SLEEP_TEST_TIMEOUT - if (*len > TMPBUFLEN2 - 1) { + if (*len > TMPBUFLEN2 - 1) return -EFAULT; - } - if (copy_from_user(buf, buffer, *len)) { + if (copy_from_user(buf, buffer, *len)) return -EFAULT; - } buf[*len] = 0; p = buf; sleep_ticks = simple_strtoul(p, &p, 0); @@ -276,8 +270,8 @@ static int pm_do_sleep(ctl_table * ctl, int write, struct file *file, return 0; } -static int pm_do_freq(ctl_table * ctl, int write, struct file *file, - void __user *buffer, size_t * len, loff_t *ppos) +static int pm_do_freq(ctl_table *ctl, int write, struct file *file, + void __user *buffer, size_t *len, loff_t *ppos) { int retval = 0, i; unsigned long val, pll; @@ -285,14 +279,14 @@ static int pm_do_freq(ctl_table * ctl, int write, struct file *file, #define MAX_CPU_FREQ 396 char buf[TMPBUFLEN], *p; unsigned long flags, intc0_mask, intc1_mask; - unsigned long old_baud_base, old_cpu_freq, baud_rate, old_clk, - old_refresh; + unsigned long old_baud_base, old_cpu_freq, old_clk, old_refresh; unsigned long new_baud_base, new_cpu_freq, new_clk, new_refresh; + unsigned long baud_rate; spin_lock_irqsave(&pm_lock, flags); - if (!write) { + if (!write) *len = 0; - } else { + else { /* Parse the new frequency */ if (*len > TMPBUFLEN - 1) { spin_unlock_irqrestore(&pm_lock, flags); @@ -312,7 +306,7 @@ static int pm_do_freq(ctl_table * ctl, int write, struct file *file, pll = val / 12; if ((pll > 33) || (pll < 7)) { /* 396 MHz max, 84 MHz min */ - /* revisit this for higher speed cpus */ + /* Revisit this for higher speed CPUs */ spin_unlock_irqrestore(&pm_lock, flags); return -EFAULT; } @@ -321,30 +315,28 @@ static int pm_do_freq(ctl_table * ctl, int write, struct file *file, old_cpu_freq = get_au1x00_speed(); new_cpu_freq = pll * 12 * 1000000; - new_baud_base = (new_cpu_freq / (2 * ((int)(au_readl(SYS_POWERCTRL)&0x03) + 2) * 16)); + new_baud_base = (new_cpu_freq / (2 * ((int)(au_readl(SYS_POWERCTRL) + & 0x03) + 2) * 16)); set_au1x00_speed(new_cpu_freq); set_au1x00_uart_baud_base(new_baud_base); old_refresh = au_readl(MEM_SDREFCFG) & 0x1ffffff; - new_refresh = - ((old_refresh * new_cpu_freq) / - old_cpu_freq) | (au_readl(MEM_SDREFCFG) & ~0x1ffffff); + new_refresh = ((old_refresh * new_cpu_freq) / old_cpu_freq) | + (au_readl(MEM_SDREFCFG) & ~0x1ffffff); au_writel(pll, SYS_CPUPLL); au_sync_delay(1); au_writel(new_refresh, MEM_SDREFCFG); au_sync_delay(1); - for (i = 0; i < 4; i++) { - if (au_readl - (UART_BASE + UART_MOD_CNTRL + - i * 0x00100000) == 3) { - old_clk = - au_readl(UART_BASE + UART_CLK + - i * 0x00100000); - // baud_rate = baud_base/clk + for (i = 0; i < 4; i++) + if (au_readl(UART_BASE + UART_MOD_CNTRL + + i * 0x00100000) == 3) { + old_clk = au_readl(UART_BASE + UART_CLK + + i * 0x00100000); baud_rate = old_baud_base / old_clk; - /* we won't get an exact baud rate and the error + /* + * We won't get an exact baud rate and the error * could be significant enough that our new * calculation will result in a clock that will * give us a baud rate that's too far off from @@ -359,18 +351,14 @@ static int pm_do_freq(ctl_table * ctl, int write, struct file *file, else if (baud_rate > 17000) baud_rate = 19200; else - (baud_rate = 9600); - // new_clk = new_baud_base/baud_rate + baud_rate = 9600; new_clk = new_baud_base / baud_rate; - au_writel(new_clk, - UART_BASE + UART_CLK + - i * 0x00100000); + au_writel(new_clk, UART_BASE + UART_CLK + + i * 0x00100000); au_sync_delay(10); } - } } - /* * We don't want _any_ interrupts other than match20. Otherwise our * au1000_calibrate_delay() calculation will be off, potentially a lot. @@ -428,14 +416,15 @@ static int __init pm_init(void) __initcall(pm_init); - /* * This is right out of init/main.c */ -/* This is the number of bits of precision for the loops_per_jiffy. Each - bit takes on average 1.5/HZ seconds. This (like the original) is a little - better than 1% */ +/* + * This is the number of bits of precision for the loops_per_jiffy. + * Each bit takes on average 1.5/HZ seconds. This (like the original) + * is a little better than 1%. + */ #define LPS_PREC 8 static void au1000_calibrate_delay(void) @@ -443,14 +432,14 @@ static void au1000_calibrate_delay(void) unsigned long ticks, loopbit; int lps_precision = LPS_PREC; - loops_per_jiffy = (1 << 12); + loops_per_jiffy = 1 << 12; while (loops_per_jiffy <<= 1) { - /* wait for "start of" clock tick */ + /* Wait for "start of" clock tick */ ticks = jiffies; while (ticks == jiffies) /* nothing */ ; - /* Go .. */ + /* Go ... */ ticks = jiffies; __delay(loops_per_jiffy); ticks = jiffies - ticks; @@ -458,8 +447,10 @@ static void au1000_calibrate_delay(void) break; } -/* Do a binary approximation to get loops_per_jiffy set to equal one clock - (up to lps_precision bits) */ + /* + * Do a binary approximation to get loops_per_jiffy set to be equal + * one clock (up to lps_precision bits) + */ loops_per_jiffy >>= 1; loopbit = loops_per_jiffy; while (lps_precision-- && (loopbit >>= 1)) { @@ -472,4 +463,4 @@ static void au1000_calibrate_delay(void) loops_per_jiffy &= ~loopbit; } } -#endif /* CONFIG_PM */ +#endif /* CONFIG_PM */ diff --git a/arch/mips/au1000/common/prom.c b/arch/mips/au1000/common/prom.c index f10af829e4ec02b1292df103f6c98fca511ab258..18b310b475ca28195904f653637aedbd9bb57d7c 100644 --- a/arch/mips/au1000/common/prom.c +++ b/arch/mips/au1000/common/prom.c @@ -3,9 +3,8 @@ * BRIEF MODULE DESCRIPTION * PROM library initialisation code, supports YAMON and U-Boot. * - * Copyright 2000, 2001, 2006 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com + * Copyright 2000-2001, 2006, 2008 MontaVista Software Inc. + * Author: MontaVista Software, Inc. * * This file was derived from Carsten Langgaard's * arch/mips/mips-boards/xx files. @@ -57,7 +56,7 @@ void prom_init_cmdline(void) actr = 1; /* Always ignore argv[0] */ cp = &(arcs_cmdline[0]); - while(actr < prom_argc) { + while (actr < prom_argc) { strcpy(cp, prom_argv[actr]); cp += strlen(prom_argv[actr]); *cp++ = ' '; @@ -84,10 +83,8 @@ char *prom_getenv(char *envname) if (yamon) { if (strcmp(envname, *env++) == 0) return *env; - } else { - if (strncmp(envname, *env, i) == 0 && (*env)[i] == '=') - return *env + i + 1; - } + } else if (strncmp(envname, *env, i) == 0 && (*env)[i] == '=') + return *env + i + 1; env++; } @@ -110,13 +107,13 @@ static inline void str2eaddr(unsigned char *ea, unsigned char *str) { int i; - for(i = 0; i < 6; i++) { + for (i = 0; i < 6; i++) { unsigned char num; - if((*str == '.') || (*str == ':')) + if ((*str == '.') || (*str == ':')) str++; - num = str2hexnum(*str++) << 4; - num |= (str2hexnum(*str++)); + num = str2hexnum(*str++) << 4; + num |= str2hexnum(*str++); ea[i] = num; } } diff --git a/arch/mips/au1000/common/puts.c b/arch/mips/au1000/common/puts.c index e34c67e892937527fe42f96bb9364c6d59f54475..55bbe24d45b6943e0689161525912171d669c630 100644 --- a/arch/mips/au1000/common/puts.c +++ b/arch/mips/au1000/common/puts.c @@ -1,11 +1,10 @@ /* * * BRIEF MODULE DESCRIPTION - * Low level uart routines to directly access a 16550 uart. + * Low level UART routines to directly access Alchemy UART. * - * Copyright 2001 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com + * Copyright 2001, 2008 MontaVista Software Inc. + * Author: MontaVista Software, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -40,12 +39,12 @@ static volatile unsigned long * const com1 = (unsigned long *)SERIAL_BASE; - #ifdef SLOW_DOWN static inline void slow_down(void) { - int k; - for (k=0; k<10000; k++); + int k; + + for (k = 0; k < 10000; k++); } #else #define slow_down() @@ -54,16 +53,16 @@ static inline void slow_down(void) void prom_putchar(const unsigned char c) { - unsigned char ch; - int i = 0; + unsigned char ch; + int i = 0; + + do { + ch = com1[SER_CMD]; + slow_down(); + i++; + if (i > TIMEOUT) + break; + } while (0 == (ch & TX_BUSY)); - do { - ch = com1[SER_CMD]; - slow_down(); - i++; - if (i>TIMEOUT) { - break; - } - } while (0 == (ch & TX_BUSY)); - com1[SER_DATA] = c; + com1[SER_DATA] = c; } diff --git a/arch/mips/au1000/common/reset.c b/arch/mips/au1000/common/reset.c index 60cec537c7450cd4bb6d129f8dc83a16591f1044..d555429c8d6fff683fb8941cf872d83f3f022950 100644 --- a/arch/mips/au1000/common/reset.c +++ b/arch/mips/au1000/common/reset.c @@ -1,11 +1,10 @@ /* * * BRIEF MODULE DESCRIPTION - * Au1000 reset routines. + * Au1xx0 reset routines. * - * Copyright 2001 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com + * Copyright 2001, 2006, 2008 MontaVista Software Inc. + * Author: MontaVista Software, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -28,10 +27,11 @@ * 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include + #include extern int au_sleep(void); -extern void (*flush_cache_all)(void); void au1000_restart(char *command) { @@ -40,8 +40,8 @@ void au1000_restart(char *command) u32 prid = read_c0_prid(); printk(KERN_NOTICE "\n** Resetting Integrated Peripherals\n"); - switch (prid & 0xFF000000) - { + + switch (prid & 0xFF000000) { case 0x00000000: /* Au1000 */ au_writel(0x02, 0xb0000010); /* ac97_enable */ au_writel(0x08, 0xb017fffc); /* usbh_enable - early errata */ @@ -138,9 +138,6 @@ void au1000_restart(char *command) au_writel(0x00, 0xb1900064); /* sys_auxpll */ au_writel(0x00, 0xb1900100); /* sys_pininputen */ break; - - default: - break; } set_c0_status(ST0_BEV | ST0_ERL); @@ -158,25 +155,25 @@ void au1000_restart(char *command) void au1000_halt(void) { #if defined(CONFIG_MIPS_PB1550) || defined(CONFIG_MIPS_DB1550) - /* power off system */ - printk("\n** Powering off...\n"); - au_writew(au_readw(0xAF00001C) | (3<<14), 0xAF00001C); + /* Power off system */ + printk(KERN_NOTICE "\n** Powering off...\n"); + au_writew(au_readw(0xAF00001C) | (3 << 14), 0xAF00001C); au_sync(); - while(1); /* should not get here */ + while (1); /* should not get here */ #else printk(KERN_NOTICE "\n** You can safely turn off the power\n"); #ifdef CONFIG_MIPS_MIRAGE au_writel((1 << 26) | (1 << 10), GPIO2_OUTPUT); #endif #ifdef CONFIG_MIPS_DB1200 - au_writew(au_readw(0xB980001C) | (1<<14), 0xB980001C); + au_writew(au_readw(0xB980001C) | (1 << 14), 0xB980001C); #endif #ifdef CONFIG_PM au_sleep(); - /* should not get here */ - printk(KERN_ERR "Unable to put cpu in sleep mode\n"); - while(1); + /* Should not get here */ + printk(KERN_ERR "Unable to put CPU in sleep mode\n"); + while (1); #else while (1) __asm__(".set\tmips3\n\t" diff --git a/arch/mips/au1000/common/setup.c b/arch/mips/au1000/common/setup.c index 0e86f7a6b4a7f5ad60fa1a24cab5b14d7c815508..1ac6b06f42a369ef8e8d578bf33c72ef99eafe44 100644 --- a/arch/mips/au1000/common/setup.c +++ b/arch/mips/au1000/common/setup.c @@ -1,7 +1,6 @@ /* - * Copyright 2000 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com + * Copyright 2000, 2007-2008 MontaVista Software Inc. + * Author: MontaVista Software, Inc. cpu_bclk; - if (bclk) - { + if (sp->cpu_bclk) { /* Enable BCLK switching */ - bclk = au_readl(0xB190003C); - au_writel(bclk | 0x60, 0xB190003C); - printk("BCLK switching enabled!\n"); + bclk = au_readl(SYS_POWERCTRL); + au_writel(bclk | 0x60, SYS_POWERCTRL); + printk(KERN_INFO "BCLK switching enabled!\n"); } - if (sp->cpu_od) { - /* Various early Au1000 Errata corrected by this */ - set_c0_config(1<<19); /* Set Config[OD] */ - } - else { + if (sp->cpu_od) + /* Various early Au1xx0 errata corrected by this */ + set_c0_config(1 << 19); /* Set Config[OD] */ + else /* Clear to obtain best system bus performance */ - clear_c0_config(1<<19); /* Clear Config[OD] */ - } + clear_c0_config(1 << 19); /* Clear Config[OD] */ argptr = prom_getcmdline(); #ifdef CONFIG_SERIAL_8250_CONSOLE - if ((argptr = strstr(argptr, "console=")) == NULL) { + argptr = strstr(argptr, "console="); + if (argptr == NULL) { argptr = prom_getcmdline(); strcat(argptr, " console=ttyS0,115200"); } #endif #ifdef CONFIG_FB_AU1100 - if ((argptr = strstr(argptr, "video=")) == NULL) { - argptr = prom_getcmdline(); - /* default panel */ - /*strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16");*/ - } + argptr = strstr(argptr, "video="); + if (argptr == NULL) { + argptr = prom_getcmdline(); + /* default panel */ + /*strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16");*/ + } #endif - #if defined(CONFIG_SOUND_AU1X00) && !defined(CONFIG_SOC_AU1000) /* au1000 does not support vra, au1500 and au1100 do */ strcat(argptr, " au1000_audio=vra"); @@ -129,7 +125,7 @@ void __init plat_mem_setup(void) /* This routine should be valid for all Au1x based boards */ phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) { - /* Don't fixup 36 bit addresses */ + /* Don't fixup 36-bit addresses */ if ((phys_addr >> 32) != 0) return phys_addr; @@ -145,17 +141,17 @@ phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) } #endif - /* All Au1x SOCs have a pcmcia controller */ - /* We setup our 32 bit pseudo addresses to be equal to the - * 36 bit addr >> 4, to make it easier to check the address + /* + * All Au1xx0 SOCs have a PCMCIA controller. + * We setup our 32-bit pseudo addresses to be equal to the + * 36-bit addr >> 4, to make it easier to check the address * and fix it. - * The Au1x socket 0 phys attribute address is 0xF 4000 0000. + * The PCMCIA socket 0 physical attribute address is 0xF 4000 0000. * The pseudo address we use is 0xF400 0000. Any address over - * 0xF400 0000 is a pcmcia pseudo address. + * 0xF400 0000 is a PCMCIA pseudo address. */ - if ((phys_addr >= 0xF4000000) && (phys_addr < 0xFFFFFFFF)) { + if ((phys_addr >= 0xF4000000) && (phys_addr < 0xFFFFFFFF)) return (phys_t)(phys_addr << 4); - } /* default nop */ return phys_addr; diff --git a/arch/mips/au1000/common/time.c b/arch/mips/au1000/common/time.c index bdb6d73b26fb19876ddff6da2da037946f144e10..563d9390a87269889e3dee6118fb8e4dd5f7e9c6 100644 --- a/arch/mips/au1000/common/time.c +++ b/arch/mips/au1000/common/time.c @@ -25,11 +25,9 @@ * * Setting up the clock on the MIPS boards. * - * Update. Always configure the kernel with CONFIG_NEW_TIME_C. This - * will use the user interface gettimeofday() functions from the - * arch/mips/kernel/time.c, and we provide the clock interrupt processing - * and the timer offset compute functions. If CONFIG_PM is selected, - * we also ensure the 32KHz timer is available. -- Dan + * We provide the clock interrupt processing and the timer offset compute + * functions. If CONFIG_PM is selected, we also ensure the 32KHz timer is + * available. -- Dan */ #include @@ -47,8 +45,7 @@ extern int allow_au1k_wait; /* default off for CP0 Counter */ #if HZ < 100 || HZ > 1000 #error "unsupported HZ value! Must be in [100,1000]" #endif -#define MATCH20_INC (328*100/HZ) /* magic number 328 is for HZ=100... */ -extern void startup_match20_interrupt(irq_handler_t handler); +#define MATCH20_INC (328 * 100 / HZ) /* magic number 328 is for HZ=100... */ static unsigned long last_pc0, last_match20; #endif @@ -61,7 +58,7 @@ static irqreturn_t counter0_irq(int irq, void *dev_id) { unsigned long pc0; int time_elapsed; - static int jiffie_drift = 0; + static int jiffie_drift; if (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20) { /* should never happen! */ @@ -70,13 +67,11 @@ static irqreturn_t counter0_irq(int irq, void *dev_id) } pc0 = au_readl(SYS_TOYREAD); - if (pc0 < last_match20) { + if (pc0 < last_match20) /* counter overflowed */ time_elapsed = (0xffffffff - last_match20) + pc0; - } - else { + else time_elapsed = pc0 - last_match20; - } while (time_elapsed > 0) { do_timer(1); @@ -92,8 +87,9 @@ static irqreturn_t counter0_irq(int irq, void *dev_id) au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2); au_sync(); - /* our counter ticks at 10.009765625 ms/tick, we we're running - * almost 10uS too slow per tick. + /* + * Our counter ticks at 10.009765625 ms/tick, we we're running + * almost 10 uS too slow per tick. */ if (jiffie_drift >= 999) { @@ -117,20 +113,17 @@ struct irqaction counter0_action = { /* When we wakeup from sleep, we have to "catch up" on all of the * timer ticks we have missed. */ -void -wakeup_counter0_adjust(void) +void wakeup_counter0_adjust(void) { unsigned long pc0; int time_elapsed; pc0 = au_readl(SYS_TOYREAD); - if (pc0 < last_match20) { + if (pc0 < last_match20) /* counter overflowed */ time_elapsed = (0xffffffff - last_match20) + pc0; - } - else { + else time_elapsed = pc0 - last_match20; - } while (time_elapsed > 0) { time_elapsed -= MATCH20_INC; @@ -143,10 +136,8 @@ wakeup_counter0_adjust(void) } -/* This is just for debugging to set the timer for a sleep delay. -*/ -void -wakeup_counter0_set(int ticks) +/* This is just for debugging to set the timer for a sleep delay. */ +void wakeup_counter0_set(int ticks) { unsigned long pc0; @@ -157,21 +148,22 @@ wakeup_counter0_set(int ticks) } #endif -/* I haven't found anyone that doesn't use a 12 MHz source clock, +/* + * I haven't found anyone that doesn't use a 12 MHz source clock, * but just in case..... */ #define AU1000_SRC_CLK 12000000 /* * We read the real processor speed from the PLL. This is important - * because it is more accurate than computing it from the 32KHz + * because it is more accurate than computing it from the 32 KHz * counter, if it exists. If we don't have an accurate processor * speed, all of the peripherals that derive their clocks based on * this advertised speed will introduce error and sometimes not work * properly. This function is futher convoluted to still allow configurations * to do that in case they have really, really old silicon with a - * write-only PLL register, that we need the 32KHz when power management - * "wait" is enabled, and we need to detect if the 32KHz isn't present + * write-only PLL register, that we need the 32 KHz when power management + * "wait" is enabled, and we need to detect if the 32 KHz isn't present * but requested......got it? :-) -- Dan */ unsigned long calc_clock(void) @@ -182,8 +174,7 @@ unsigned long calc_clock(void) spin_lock_irqsave(&time_lock, flags); - /* Power management cares if we don't have a 32KHz counter. - */ + /* Power management cares if we don't have a 32 KHz counter. */ no_au1xxx_32khz = 0; counter = au_readl(SYS_COUNTER_CNTRL); if (counter & SYS_CNTRL_E0) { @@ -193,7 +184,7 @@ unsigned long calc_clock(void) while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S); /* RTC now ticks at 32.768/16 kHz */ - au_writel(trim_divide-1, SYS_RTCTRIM); + au_writel(trim_divide - 1, SYS_RTCTRIM); while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S); while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S); @@ -215,9 +206,11 @@ unsigned long calc_clock(void) #endif else cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) * AU1000_SRC_CLK; + /* On Alchemy CPU:counter ratio is 1:1 */ mips_hpt_frequency = cpu_speed; - // Equation: Baudrate = CPU / (SD * 2 * CLKDIV * 16) - set_au1x00_uart_baud_base(cpu_speed / (2 * ((int)(au_readl(SYS_POWERCTRL)&0x03) + 2) * 16)); + /* Equation: Baudrate = CPU / (SD * 2 * CLKDIV * 16) */ + set_au1x00_uart_baud_base(cpu_speed / (2 * ((int)(au_readl(SYS_POWERCTRL) + & 0x03) + 2) * 16)); spin_unlock_irqrestore(&time_lock, flags); return cpu_speed; } @@ -228,10 +221,10 @@ void __init plat_time_init(void) est_freq += 5000; /* round */ est_freq -= est_freq%10000; - printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, - (est_freq%1000000)*100/1000000); - set_au1x00_speed(est_freq); - set_au1x00_lcd_clock(); // program the LCD clock + printk(KERN_INFO "CPU frequency %u.%02u MHz\n", + est_freq / 1000000, ((est_freq % 1000000) * 100) / 1000000); + set_au1x00_speed(est_freq); + set_au1x00_lcd_clock(); /* program the LCD clock */ #ifdef CONFIG_PM /* @@ -243,30 +236,29 @@ void __init plat_time_init(void) * counter 0 interrupt as a special irq and it doesn't show * up under /proc/interrupts. * - * Check to ensure we really have a 32KHz oscillator before + * Check to ensure we really have a 32 KHz oscillator before * we do this. */ if (no_au1xxx_32khz) - printk("WARNING: no 32KHz clock found.\n"); + printk(KERN_WARNING "WARNING: no 32KHz clock found.\n"); else { while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S); au_writel(0, SYS_TOYWRITE); while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S); - au_writel(au_readl(SYS_WAKEMSK) | (1<<8), SYS_WAKEMSK); + au_writel(au_readl(SYS_WAKEMSK) | (1 << 8), SYS_WAKEMSK); au_writel(~0, SYS_WAKESRC); au_sync(); while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20); - /* setup match20 to interrupt once every HZ */ + /* Setup match20 to interrupt once every HZ */ last_pc0 = last_match20 = au_readl(SYS_TOYREAD); au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2); au_sync(); while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20); setup_irq(AU1000_TOY_MATCH2_INT, &counter0_action); - /* We can use the real 'wait' instruction. - */ + /* We can use the real 'wait' instruction. */ allow_au1k_wait = 1; } diff --git a/arch/mips/au1000/db1x00/Makefile b/arch/mips/au1000/db1x00/Makefile index 51d62bd5d900f93ad5408e71a3df031e027ea840..274db3b55d829f5d77336cfde244f3b3ab8dfdae 100644 --- a/arch/mips/au1000/db1x00/Makefile +++ b/arch/mips/au1000/db1x00/Makefile @@ -1,8 +1,8 @@ # -# Copyright 2000 MontaVista Software Inc. -# Author: MontaVista Software, Inc. -# ppopov@mvista.com or source@mvista.com +# Copyright 2000, 2008 MontaVista Software Inc. +# Author: MontaVista Software, Inc. +# +# Makefile for the Alchemy Semiconductor DBAu1xx0 boards. # -# Makefile for the Alchemy Semiconductor Db1x00 board. lib-y := init.o board_setup.o irqmap.o diff --git a/arch/mips/au1000/db1x00/board_setup.c b/arch/mips/au1000/db1x00/board_setup.c index b7dcbad5c5861070b267393f3f44e1fce1c036ff..9e5ccbbfcedd83dc8f11ab0a1b2ac86cf480d01b 100644 --- a/arch/mips/au1000/db1x00/board_setup.c +++ b/arch/mips/au1000/db1x00/board_setup.c @@ -3,9 +3,8 @@ * BRIEF MODULE DESCRIPTION * Alchemy Db1x00 board setup. * - * Copyright 2000 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com + * Copyright 2000, 2008 MontaVista Software Inc. + * Author: MontaVista Software, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -37,49 +36,49 @@ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR; void board_reset(void) { - /* Hit BCSR.SYSTEM_CONTROL[SW_RST] */ + /* Hit BCSR.SW_RESET[RESET] */ bcsr->swreset = 0x0000; } void __init board_setup(void) { - u32 pin_func; + u32 pin_func = 0; - pin_func = 0; - /* not valid for 1550 */ - -#if defined(CONFIG_IRDA) && (defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1100)) - /* set IRFIRSEL instead of GPIO15 */ - pin_func = au_readl(SYS_PINFUNC) | (u32)((1<<8)); + /* Not valid for Au1550 */ +#if defined(CONFIG_IRDA) && \ + (defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1100)) + /* Set IRFIRSEL instead of GPIO15 */ + pin_func = au_readl(SYS_PINFUNC) | SYS_PF_IRF; au_writel(pin_func, SYS_PINFUNC); - /* power off until the driver is in use */ + /* Power off until the driver is in use */ bcsr->resets &= ~BCSR_RESETS_IRDA_MODE_MASK; - bcsr->resets |= BCSR_RESETS_IRDA_MODE_OFF; + bcsr->resets |= BCSR_RESETS_IRDA_MODE_OFF; au_sync(); #endif bcsr->pcmcia = 0x0000; /* turn off PCMCIA power */ #ifdef CONFIG_MIPS_MIRAGE - /* enable GPIO[31:0] inputs */ + /* Enable GPIO[31:0] inputs */ au_writel(0, SYS_PININPUTEN); - /* GPIO[20] is output, tristate the other input primary GPIO's */ - au_writel((u32)(~(1<<20)), SYS_TRIOUTCLR); + /* GPIO[20] is output, tristate the other input primary GPIOs */ + au_writel(~(1 << 20), SYS_TRIOUTCLR); - /* set GPIO[210:208] instead of SSI_0 */ - pin_func = au_readl(SYS_PINFUNC) | (u32)(1); + /* Set GPIO[210:208] instead of SSI_0 */ + pin_func = au_readl(SYS_PINFUNC) | SYS_PF_S0; - /* set GPIO[215:211] for LED's */ - pin_func |= (u32)((5<<2)); + /* Set GPIO[215:211] for LEDs */ + pin_func |= 5 << 2; - /* set GPIO[214:213] for more LED's */ - pin_func |= (u32)((5<<12)); + /* Set GPIO[214:213] for more LEDs */ + pin_func |= 5 << 12; - /* set GPIO[207:200] instead of PCMCIA/LCD */ - pin_func |= (u32)((3<<17)); + /* Set GPIO[207:200] instead of PCMCIA/LCD */ + pin_func |= SYS_PF_LCD | SYS_PF_PC; au_writel(pin_func, SYS_PINFUNC); - /* Enable speaker amplifier. This should + /* + * Enable speaker amplifier. This should * be part of the audio driver. */ au_writel(au_readl(GPIO2_DIR) | 0x200, GPIO2_DIR); @@ -89,21 +88,21 @@ void __init board_setup(void) au_sync(); #ifdef CONFIG_MIPS_DB1000 - printk("AMD Alchemy Au1000/Db1000 Board\n"); + printk(KERN_INFO "AMD Alchemy Au1000/Db1000 Board\n"); #endif #ifdef CONFIG_MIPS_DB1500 - printk("AMD Alchemy Au1500/Db1500 Board\n"); + printk(KERN_INFO "AMD Alchemy Au1500/Db1500 Board\n"); #endif #ifdef CONFIG_MIPS_DB1100 - printk("AMD Alchemy Au1100/Db1100 Board\n"); + printk(KERN_INFO "AMD Alchemy Au1100/Db1100 Board\n"); #endif #ifdef CONFIG_MIPS_BOSPORUS - printk("AMD Alchemy Bosporus Board\n"); + printk(KERN_INFO "AMD Alchemy Bosporus Board\n"); #endif #ifdef CONFIG_MIPS_MIRAGE - printk("AMD Alchemy Mirage Board\n"); + printk(KERN_INFO "AMD Alchemy Mirage Board\n"); #endif #ifdef CONFIG_MIPS_DB1550 - printk("AMD Alchemy Au1550/Db1550 Board\n"); + printk(KERN_INFO "AMD Alchemy Au1550/Db1550 Board\n"); #endif } diff --git a/arch/mips/au1000/db1x00/init.c b/arch/mips/au1000/db1x00/init.c index d3b967caf70c10729a7b1bb5a2681890c696a0a9..5ebe0de5e4590e404e8ba11c2a86730fd38bed16 100644 --- a/arch/mips/au1000/db1x00/init.c +++ b/arch/mips/au1000/db1x00/init.c @@ -2,9 +2,8 @@ * BRIEF MODULE DESCRIPTION * PB1000 board setup * - * Copyright 2001 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com + * Copyright 2001, 2008 MontaVista Software Inc. + * Author: MontaVista Software, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -49,8 +48,8 @@ void __init prom_init(void) unsigned long memsize; prom_argc = fw_arg0; - prom_argv = (char **) fw_arg1; - prom_envp = (char **) fw_arg2; + prom_argv = (char **)fw_arg1; + prom_envp = (char **)fw_arg2; prom_init_cmdline(); @@ -58,6 +57,6 @@ void __init prom_init(void) if (!memsize_str) memsize = 0x04000000; else - memsize = simple_strtol(memsize_str, NULL, 0); + memsize = strict_strtol(memsize_str, 0, NULL); add_memory_region(0, memsize, BOOT_MEM_RAM); } diff --git a/arch/mips/au1000/db1x00/irqmap.c b/arch/mips/au1000/db1x00/irqmap.c index eaa50c7b6341cdcf5407fbd58a69827accac7ef4..94c090e8bf7a61e29f04de475d00ef466933e49a 100644 --- a/arch/mips/au1000/db1x00/irqmap.c +++ b/arch/mips/au1000/db1x00/irqmap.c @@ -32,32 +32,32 @@ #ifdef CONFIG_MIPS_DB1500 char irq_tab_alchemy[][5] __initdata = { - [12] = { -1, INTA, INTX, INTX, INTX}, /* IDSEL 12 - HPT371 */ - [13] = { -1, INTA, INTB, INTC, INTD}, /* IDSEL 13 - PCI slot */ + [12] = { -1, INTA, INTX, INTX, INTX }, /* IDSEL 12 - HPT371 */ + [13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot */ }; #endif #ifdef CONFIG_MIPS_BOSPORUS char irq_tab_alchemy[][5] __initdata = { - [11] = { -1, INTA, INTB, INTX, INTX}, /* IDSEL 11 - miniPCI */ - [12] = { -1, INTA, INTX, INTX, INTX}, /* IDSEL 12 - SN1741 */ - [13] = { -1, INTA, INTB, INTC, INTD}, /* IDSEL 13 - PCI slot */ + [11] = { -1, INTA, INTB, INTX, INTX }, /* IDSEL 11 - miniPCI */ + [12] = { -1, INTA, INTX, INTX, INTX }, /* IDSEL 12 - SN1741 */ + [13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot */ }; #endif #ifdef CONFIG_MIPS_MIRAGE char irq_tab_alchemy[][5] __initdata = { - [11] = { -1, INTD, INTX, INTX, INTX}, /* IDSEL 11 - SMI VGX */ - [12] = { -1, INTX, INTX, INTC, INTX}, /* IDSEL 12 - PNX1300 */ - [13] = { -1, INTA, INTB, INTX, INTX}, /* IDSEL 13 - miniPCI */ + [11] = { -1, INTD, INTX, INTX, INTX }, /* IDSEL 11 - SMI VGX */ + [12] = { -1, INTX, INTX, INTC, INTX }, /* IDSEL 12 - PNX1300 */ + [13] = { -1, INTA, INTB, INTX, INTX }, /* IDSEL 13 - miniPCI */ }; #endif #ifdef CONFIG_MIPS_DB1550 char irq_tab_alchemy[][5] __initdata = { - [11] = { -1, INTC, INTX, INTX, INTX}, /* IDSEL 11 - on-board HPT371 */ - [12] = { -1, INTB, INTC, INTD, INTA}, /* IDSEL 12 - PCI slot 2 (left) */ - [13] = { -1, INTA, INTB, INTC, INTD}, /* IDSEL 13 - PCI slot 1 (right) */ + [11] = { -1, INTC, INTX, INTX, INTX }, /* IDSEL 11 - on-board HPT371 */ + [12] = { -1, INTB, INTC, INTD, INTA }, /* IDSEL 12 - PCI slot 2 (left) */ + [13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot 1 (right) */ }; #endif diff --git a/arch/mips/au1000/mtx-1/Makefile b/arch/mips/au1000/mtx-1/Makefile index 85a90941de4ff9c1b900fe52f44e3900e84ec5f2..7c67b3d33bec16a6b132b1e38a12f987d9eeb944 100644 --- a/arch/mips/au1000/mtx-1/Makefile +++ b/arch/mips/au1000/mtx-1/Makefile @@ -1,7 +1,6 @@ # # Copyright 2003 MontaVista Software Inc. -# Author: MontaVista Software, Inc. -# ppopov@mvista.com or source@mvista.com +# Author: MontaVista Software, Inc. # Bruno Randolf # # Makefile for 4G Systems MTX-1 board. diff --git a/arch/mips/au1000/mtx-1/board_setup.c b/arch/mips/au1000/mtx-1/board_setup.c index 5736354829c6a2d4356cba3a978f29694981c720..3f8079186cf2bc62a1a9a5c595df2d3caa4bac47 100644 --- a/arch/mips/au1000/mtx-1/board_setup.c +++ b/arch/mips/au1000/mtx-1/board_setup.c @@ -3,9 +3,8 @@ * BRIEF MODULE DESCRIPTION * 4G Systems MTX-1 board setup. * - * Copyright 2003 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com + * Copyright 2003, 2008 MontaVista Software Inc. + * Author: MontaVista Software, Inc. * Bruno Randolf * * This program is free software; you can redistribute it and/or modify it @@ -34,7 +33,7 @@ #include extern int (*board_pci_idsel)(unsigned int devsel, int assert); -int mtx1_pci_idsel(unsigned int devsel, int assert); +int mtx1_pci_idsel(unsigned int devsel, int assert); void board_reset(void) { @@ -45,36 +44,36 @@ void board_reset(void) void __init board_setup(void) { #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) - // enable USB power switch - au_writel( au_readl(GPIO2_DIR) | 0x10, GPIO2_DIR ); - au_writel( 0x100000, GPIO2_OUTPUT ); + /* Enable USB power switch */ + au_writel(au_readl(GPIO2_DIR) | 0x10, GPIO2_DIR); + au_writel(0x100000, GPIO2_OUTPUT); #endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */ #ifdef CONFIG_PCI #if defined(__MIPSEB__) - au_writel(0xf | (2<<6) | (1<<4), Au1500_PCI_CFG); + au_writel(0xf | (2 << 6) | (1 << 4), Au1500_PCI_CFG); #else au_writel(0xf, Au1500_PCI_CFG); #endif #endif - // initialize sys_pinfunc: - au_writel( SYS_PF_NI2, SYS_PINFUNC ); + /* Initialize sys_pinfunc */ + au_writel(SYS_PF_NI2, SYS_PINFUNC); - // initialize GPIO - au_writel( 0xFFFFFFFF, SYS_TRIOUTCLR ); - au_writel( 0x00000001, SYS_OUTPUTCLR ); // set M66EN (PCI 66MHz) to OFF - au_writel( 0x00000008, SYS_OUTPUTSET ); // set PCI CLKRUN# to OFF - au_writel( 0x00000002, SYS_OUTPUTSET ); // set EXT_IO3 ON - au_writel( 0x00000020, SYS_OUTPUTCLR ); // set eth PHY TX_ER to OFF + /* Initialize GPIO */ + au_writel(0xFFFFFFFF, SYS_TRIOUTCLR); + au_writel(0x00000001, SYS_OUTPUTCLR); /* set M66EN (PCI 66MHz) to OFF */ + au_writel(0x00000008, SYS_OUTPUTSET); /* set PCI CLKRUN# to OFF */ + au_writel(0x00000002, SYS_OUTPUTSET); /* set EXT_IO3 ON */ + au_writel(0x00000020, SYS_OUTPUTCLR); /* set eth PHY TX_ER to OFF */ - // enable LED and set it to green - au_writel( au_readl(GPIO2_DIR) | 0x1800, GPIO2_DIR ); - au_writel( 0x18000800, GPIO2_OUTPUT ); + /* Enable LED and set it to green */ + au_writel(au_readl(GPIO2_DIR) | 0x1800, GPIO2_DIR); + au_writel(0x18000800, GPIO2_OUTPUT); board_pci_idsel = mtx1_pci_idsel; - printk("4G Systems MTX-1 Board\n"); + printk(KERN_INFO "4G Systems MTX-1 Board\n"); } int @@ -82,20 +81,18 @@ mtx1_pci_idsel(unsigned int devsel, int assert) { #define MTX_IDSEL_ONLY_0_AND_3 0 #if MTX_IDSEL_ONLY_0_AND_3 - if (devsel != 0 && devsel != 3) { - printk("*** not 0 or 3\n"); - return 0; - } + if (devsel != 0 && devsel != 3) { + printk(KERN_ERR "*** not 0 or 3\n"); + return 0; + } #endif - if (assert && devsel != 0) { - // suppress signal to cardbus - au_writel( 0x00000002, SYS_OUTPUTCLR ); // set EXT_IO3 OFF - } - else { - au_writel( 0x00000002, SYS_OUTPUTSET ); // set EXT_IO3 ON - } - au_sync_udelay(1); - return 1; + if (assert && devsel != 0) + /* Suppress signal to Cardbus */ + au_writel(0x00000002, SYS_OUTPUTCLR); /* set EXT_IO3 OFF */ + else + au_writel(0x00000002, SYS_OUTPUTSET); /* set EXT_IO3 ON */ + au_sync_udelay(1); + return 1; } diff --git a/arch/mips/au1000/mtx-1/init.c b/arch/mips/au1000/mtx-1/init.c index c015cbce1cca4b0c7b5063b39ffcc3362dd8bc4b..33a4aebe0cba37a33f3d89e918caaa03e1d40673 100644 --- a/arch/mips/au1000/mtx-1/init.c +++ b/arch/mips/au1000/mtx-1/init.c @@ -3,9 +3,8 @@ * BRIEF MODULE DESCRIPTION * 4G Systems MTX-1 board setup * - * Copyright 2003 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com + * Copyright 2003, 2008 MontaVista Software Inc. + * Author: MontaVista Software, Inc. * Bruno Randolf * * This program is free software; you can redistribute it and/or modify it @@ -47,8 +46,8 @@ void __init prom_init(void) unsigned long memsize; prom_argc = fw_arg0; - prom_argv = (char **) fw_arg1; - prom_envp = (char **) fw_arg2; + prom_argv = (char **)fw_arg1; + prom_envp = (char **)fw_arg2; prom_init_cmdline(); @@ -56,6 +55,6 @@ void __init prom_init(void) if (!memsize_str) memsize = 0x04000000; else - memsize = simple_strtol(memsize_str, NULL, 0); + memsize = strict_strtol(memsize_str, 0, NULL); add_memory_region(0, memsize, BOOT_MEM_RAM); } diff --git a/arch/mips/au1000/mtx-1/irqmap.c b/arch/mips/au1000/mtx-1/irqmap.c index 78d70c42c9dbc8265814f164bd51db83fb6741df..f2bf02951e9cb426ea92363963339eff6bcc08e4 100644 --- a/arch/mips/au1000/mtx-1/irqmap.c +++ b/arch/mips/au1000/mtx-1/irqmap.c @@ -31,18 +31,18 @@ #include char irq_tab_alchemy[][5] __initdata = { - [0] = { -1, INTA, INTA, INTX, INTX}, /* IDSEL 00 - AdapterA-Slot0 (top) */ - [1] = { -1, INTB, INTA, INTX, INTX}, /* IDSEL 01 - AdapterA-Slot1 (bottom) */ - [2] = { -1, INTC, INTD, INTX, INTX}, /* IDSEL 02 - AdapterB-Slot0 (top) */ - [3] = { -1, INTD, INTC, INTX, INTX}, /* IDSEL 03 - AdapterB-Slot1 (bottom) */ - [4] = { -1, INTA, INTB, INTX, INTX}, /* IDSEL 04 - AdapterC-Slot0 (top) */ - [5] = { -1, INTB, INTA, INTX, INTX}, /* IDSEL 05 - AdapterC-Slot1 (bottom) */ - [6] = { -1, INTC, INTD, INTX, INTX}, /* IDSEL 06 - AdapterD-Slot0 (top) */ - [7] = { -1, INTD, INTC, INTX, INTX}, /* IDSEL 07 - AdapterD-Slot1 (bottom) */ + [0] = { -1, INTA, INTA, INTX, INTX }, /* IDSEL 00 - AdapterA-Slot0 (top) */ + [1] = { -1, INTB, INTA, INTX, INTX }, /* IDSEL 01 - AdapterA-Slot1 (bottom) */ + [2] = { -1, INTC, INTD, INTX, INTX }, /* IDSEL 02 - AdapterB-Slot0 (top) */ + [3] = { -1, INTD, INTC, INTX, INTX }, /* IDSEL 03 - AdapterB-Slot1 (bottom) */ + [4] = { -1, INTA, INTB, INTX, INTX }, /* IDSEL 04 - AdapterC-Slot0 (top) */ + [5] = { -1, INTB, INTA, INTX, INTX }, /* IDSEL 05 - AdapterC-Slot1 (bottom) */ + [6] = { -1, INTC, INTD, INTX, INTX }, /* IDSEL 06 - AdapterD-Slot0 (top) */ + [7] = { -1, INTD, INTC, INTX, INTX }, /* IDSEL 07 - AdapterD-Slot1 (bottom) */ }; struct au1xxx_irqmap __initdata au1xxx_irq_map[] = { - { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0}, + { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0 }, { AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 }, { AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 }, { AU1500_GPIO_203, INTC_INT_LOW_LEVEL, 0 }, diff --git a/arch/mips/au1000/mtx-1/platform.c b/arch/mips/au1000/mtx-1/platform.c index a7edbf0829ac3b3ff13495421a738c26ef8fc9d7..9807be37c32f6fb61a00c90686599d80f3bf6bc9 100644 --- a/arch/mips/au1000/mtx-1/platform.c +++ b/arch/mips/au1000/mtx-1/platform.c @@ -21,11 +21,10 @@ #include #include #include +#include #include #include -#include - static struct gpio_keys_button mtx1_gpio_button[] = { { .gpio = 207, diff --git a/arch/mips/au1000/pb1000/Makefile b/arch/mips/au1000/pb1000/Makefile index daa1a507e72f878e5af951bdf8f3e03998fd6963..99bbec0ca41bf9bcc6c8abe7cae650d1e6da5046 100644 --- a/arch/mips/au1000/pb1000/Makefile +++ b/arch/mips/au1000/pb1000/Makefile @@ -1,8 +1,8 @@ # -# Copyright 2000 MontaVista Software Inc. -# Author: MontaVista Software, Inc. -# ppopov@mvista.com or source@mvista.com +# Copyright 2000, 2008 MontaVista Software Inc. +# Author: MontaVista Software, Inc. +# +# Makefile for the Alchemy Semiconductor Pb1000 board. # -# Makefile for the Alchemy Semiconductor PB1000 board. lib-y := init.o board_setup.o irqmap.o diff --git a/arch/mips/au1000/pb1000/board_setup.c b/arch/mips/au1000/pb1000/board_setup.c index 33f15acc1b17677bb6ae6b2191142aaec6267e01..25df167a95b3550a8b6599a8f7cc5aa0b464dc46 100644 --- a/arch/mips/au1000/pb1000/board_setup.c +++ b/arch/mips/au1000/pb1000/board_setup.c @@ -1,7 +1,6 @@ /* - * Copyright 2000 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com + * Copyright 2000, 2008 MontaVista Software Inc. + * Author: MontaVista Software, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -40,128 +39,126 @@ void __init board_setup(void) u32 sys_freqctrl, sys_clksrc; u32 prid = read_c0_prid(); - // set AUX clock to 12MHz * 8 = 96 MHz + /* Set AUX clock to 12 MHz * 8 = 96 MHz */ au_writel(8, SYS_AUXPLL); au_writel(0, SYS_PINSTATERD); udelay(100); #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) - /* zero and disable FREQ2 */ + /* Zero and disable FREQ2 */ sys_freqctrl = au_readl(SYS_FREQCTRL0); sys_freqctrl &= ~0xFFF00000; au_writel(sys_freqctrl, SYS_FREQCTRL0); - /* zero and disable USBH/USBD clocks */ + /* Zero and disable USBH/USBD clocks */ sys_clksrc = au_readl(SYS_CLKSRC); - sys_clksrc &= ~0x00007FE0; + sys_clksrc &= ~(SYS_CS_CUD | SYS_CS_DUD | SYS_CS_MUD_MASK | + SYS_CS_CUH | SYS_CS_DUH | SYS_CS_MUH_MASK); au_writel(sys_clksrc, SYS_CLKSRC); sys_freqctrl = au_readl(SYS_FREQCTRL0); sys_freqctrl &= ~0xFFF00000; sys_clksrc = au_readl(SYS_CLKSRC); - sys_clksrc &= ~0x00007FE0; + sys_clksrc &= ~(SYS_CS_CUD | SYS_CS_DUD | SYS_CS_MUD_MASK | + SYS_CS_CUH | SYS_CS_DUH | SYS_CS_MUH_MASK); - switch (prid & 0x000000FF) - { + switch (prid & 0x000000FF) { case 0x00: /* DA */ case 0x01: /* HA */ case 0x02: /* HB */ - /* CPU core freq to 48MHz to slow it way down... */ - au_writel(4, SYS_CPUPLL); + /* CPU core freq to 48 MHz to slow it way down... */ + au_writel(4, SYS_CPUPLL); - /* - * Setup 48MHz FREQ2 from CPUPLL for USB Host - */ - /* FRDIV2=3 -> div by 8 of 384MHz -> 48MHz */ - sys_freqctrl |= ((3<<22) | (1<<21) | (0<<20)); - au_writel(sys_freqctrl, SYS_FREQCTRL0); + /* + * Setup 48 MHz FREQ2 from CPUPLL for USB Host + * FRDIV2 = 3 -> div by 8 of 384 MHz -> 48 MHz + */ + sys_freqctrl |= (3 << SYS_FC_FRDIV2_BIT) | SYS_FC_FE2; + au_writel(sys_freqctrl, SYS_FREQCTRL0); - /* CPU core freq to 384MHz */ - au_writel(0x20, SYS_CPUPLL); + /* CPU core freq to 384 MHz */ + au_writel(0x20, SYS_CPUPLL); - printk("Au1000: 48MHz OHCI workaround enabled\n"); + printk(KERN_INFO "Au1000: 48 MHz OHCI workaround enabled\n"); break; - default: /* HC and newer */ - // FREQ2 = aux/2 = 48 MHz - sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20)); - au_writel(sys_freqctrl, SYS_FREQCTRL0); + default: /* HC and newer */ + /* FREQ2 = aux / 2 = 48 MHz */ + sys_freqctrl |= (0 << SYS_FC_FRDIV2_BIT) | + SYS_FC_FE2 | SYS_FC_FS2; + au_writel(sys_freqctrl, SYS_FREQCTRL0); break; } /* - * Route 48MHz FREQ2 into USB Host and/or Device + * Route 48 MHz FREQ2 into USB Host and/or Device */ -#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) - sys_clksrc |= ((4<<12) | (0<<11) | (0<<10)); -#endif + sys_clksrc |= SYS_CS_MUX_FQ2 << SYS_CS_MUH_BIT; au_writel(sys_clksrc, SYS_CLKSRC); - // configure pins GPIO[14:9] as GPIO - pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8080); + /* Configure pins GPIO[14:9] as GPIO */ + pin_func = au_readl(SYS_PINFUNC) & ~(SYS_PF_UR3 | SYS_PF_USB); - // 2nd USB port is USB host - pin_func |= 0x8000; + /* 2nd USB port is USB host */ + pin_func |= SYS_PF_USB; au_writel(pin_func, SYS_PINFUNC); au_writel(0x2800, SYS_TRIOUTCLR); au_writel(0x0030, SYS_OUTPUTCLR); #endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */ - // make gpio 15 an input (for interrupt line) - pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x100); - // we don't need I2S, so make it available for GPIO[31:29] - pin_func |= (1<<5); + /* Make GPIO 15 an input (for interrupt line) */ + pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_IRF; + /* We don't need I2S, so make it available for GPIO[31:29] */ + pin_func |= SYS_PF_I2S; au_writel(pin_func, SYS_PINFUNC); au_writel(0x8000, SYS_TRIOUTCLR); - static_cfg0 = au_readl(MEM_STCFG0) & (u32)(~0xc00); + static_cfg0 = au_readl(MEM_STCFG0) & ~0xc00; au_writel(static_cfg0, MEM_STCFG0); - // configure RCE2* for LCD + /* configure RCE2* for LCD */ au_writel(0x00000004, MEM_STCFG2); - // MEM_STTIME2 + /* MEM_STTIME2 */ au_writel(0x09000000, MEM_STTIME2); - // Set 32-bit base address decoding for RCE2* + /* Set 32-bit base address decoding for RCE2* */ au_writel(0x10003ff0, MEM_STADDR2); - // PCI CPLD setup - // expand CE0 to cover PCI + /* + * PCI CPLD setup + * Expand CE0 to cover PCI + */ au_writel(0x11803e40, MEM_STADDR1); - // burst visibility on + /* Burst visibility on */ au_writel(au_readl(MEM_STCFG0) | 0x1000, MEM_STCFG0); - au_writel(0x83, MEM_STCFG1); // ewait enabled, flash timing - au_writel(0x33030a10, MEM_STTIME1); // slower timing for FPGA + au_writel(0x83, MEM_STCFG1); /* ewait enabled, flash timing */ + au_writel(0x33030a10, MEM_STTIME1); /* slower timing for FPGA */ - /* setup the static bus controller */ + /* Setup the static bus controller */ au_writel(0x00000002, MEM_STCFG3); /* type = PCMCIA */ au_writel(0x280E3D07, MEM_STTIME3); /* 250ns cycle time */ au_writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */ -#ifdef CONFIG_PCI - au_writel(0, PCI_BRIDGE_CONFIG); // set extend byte to 0 - au_writel(0, SDRAM_MBAR); // set mbar to 0 - au_writel(0x2, SDRAM_CMD); // enable memory accesses - au_sync_delay(1); -#endif - - /* Enable Au1000 BCLK switching - note: sed1356 must not use - * its BCLK (Au1000 LCLK) for any timings */ - switch (prid & 0x000000FF) - { + /* + * Enable Au1000 BCLK switching - note: sed1356 must not use + * its BCLK (Au1000 LCLK) for any timings + */ + switch (prid & 0x000000FF) { case 0x00: /* DA */ case 0x01: /* HA */ case 0x02: /* HB */ break; default: /* HC and newer */ - /* Enable sys bus clock divider when IDLE state or no bus - activity. */ + /* + * Enable sys bus clock divider when IDLE state or no bus + * activity. + */ au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL); break; } diff --git a/arch/mips/au1000/pb1000/init.c b/arch/mips/au1000/pb1000/init.c index 549447df71d6f66d0c118a9860c4af7e8bb48857..3837365d613d54bf65b01acff016eb7e805e12e6 100644 --- a/arch/mips/au1000/pb1000/init.c +++ b/arch/mips/au1000/pb1000/init.c @@ -1,10 +1,9 @@ /* * BRIEF MODULE DESCRIPTION - * PB1000 board setup + * Pb1000 board setup * - * Copyright 2001 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com + * Copyright 2001, 2008 MontaVista Software Inc. + * Author: MontaVista Software, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -44,16 +43,15 @@ void __init prom_init(void) unsigned char *memsize_str; unsigned long memsize; - prom_argc = (int) fw_arg0; - prom_argv = (char **) fw_arg1; - prom_envp = (char **) fw_arg2; + prom_argc = (int)fw_arg0; + prom_argv = (char **)fw_arg1; + prom_envp = (char **)fw_arg2; prom_init_cmdline(); memsize_str = prom_getenv("memsize"); - if (!memsize_str) { + if (!memsize_str) memsize = 0x04000000; - } else { - memsize = simple_strtol(memsize_str, NULL, 0); - } + else + memsize = strict_strtol(memsize_str, 0, NULL); add_memory_region(0, memsize, BOOT_MEM_RAM); } diff --git a/arch/mips/au1000/pb1100/Makefile b/arch/mips/au1000/pb1100/Makefile index 996236df6375b2ddd53ce8361a59cf8e5ef65834..793e97c49e46d7f74871170be1e713d99d0894e9 100644 --- a/arch/mips/au1000/pb1100/Makefile +++ b/arch/mips/au1000/pb1100/Makefile @@ -1,8 +1,8 @@ # -# Copyright 2000,2001 MontaVista Software Inc. -# Author: MontaVista Software, Inc. -# ppopov@mvista.com or source@mvista.com +# Copyright 2000, 2001, 2008 MontaVista Software Inc. +# Author: MontaVista Software, Inc. # # Makefile for the Alchemy Semiconductor Pb1100 board. +# lib-y := init.o board_setup.o irqmap.o diff --git a/arch/mips/au1000/pb1100/board_setup.c b/arch/mips/au1000/pb1100/board_setup.c index 656164c8e9cafb4b4219c15b42fb0d63a8a9a174..c0bfd59a7a368f1dde18c428a5c9aa41df5a6087 100644 --- a/arch/mips/au1000/pb1100/board_setup.c +++ b/arch/mips/au1000/pb1100/board_setup.c @@ -1,7 +1,6 @@ /* - * Copyright 2002 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com + * Copyright 2002, 2008 MontaVista Software Inc. + * Author: MontaVista Software, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -32,15 +31,15 @@ void board_reset(void) { - /* Hit BCSR.SYSTEM_CONTROL[SW_RST] */ - au_writel(0x00000000, 0xAE00001C); + /* Hit BCSR.RST_VDDI[SOFT_RESET] */ + au_writel(0x00000000, PB1100_RST_VDDI); } void __init board_setup(void) { - volatile void __iomem * base = (volatile void __iomem *) 0xac000000UL; + volatile void __iomem *base = (volatile void __iomem *)0xac000000UL; - // set AUX clock to 12MHz * 8 = 96 MHz + /* Set AUX clock to 12 MHz * 8 = 96 MHz */ au_writel(8, SYS_AUXPLL); au_writel(0, SYS_PININPUTEN); udelay(100); @@ -49,44 +48,47 @@ void __init board_setup(void) { u32 pin_func, sys_freqctrl, sys_clksrc; - // configure pins GPIO[14:9] as GPIO - pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x80); + /* Configure pins GPIO[14:9] as GPIO */ + pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_UR3; - /* zero and disable FREQ2 */ + /* Zero and disable FREQ2 */ sys_freqctrl = au_readl(SYS_FREQCTRL0); sys_freqctrl &= ~0xFFF00000; au_writel(sys_freqctrl, SYS_FREQCTRL0); - /* zero and disable USBH/USBD/IrDA clock */ + /* Zero and disable USBH/USBD/IrDA clock */ sys_clksrc = au_readl(SYS_CLKSRC); - sys_clksrc &= ~0x0000001F; + sys_clksrc &= ~(SYS_CS_CIR | SYS_CS_DIR | SYS_CS_MIR_MASK); au_writel(sys_clksrc, SYS_CLKSRC); sys_freqctrl = au_readl(SYS_FREQCTRL0); sys_freqctrl &= ~0xFFF00000; sys_clksrc = au_readl(SYS_CLKSRC); - sys_clksrc &= ~0x0000001F; + sys_clksrc &= ~(SYS_CS_CIR | SYS_CS_DIR | SYS_CS_MIR_MASK); - // FREQ2 = aux/2 = 48 MHz - sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20)); + /* FREQ2 = aux / 2 = 48 MHz */ + sys_freqctrl |= (0 << SYS_FC_FRDIV2_BIT) | + SYS_FC_FE2 | SYS_FC_FS2; au_writel(sys_freqctrl, SYS_FREQCTRL0); /* - * Route 48MHz FREQ2 into USBH/USBD/IrDA + * Route 48 MHz FREQ2 into USBH/USBD/IrDA */ - sys_clksrc |= ((4<<2) | (0<<1) | 0 ); + sys_clksrc |= SYS_CS_MUX_FQ2 << SYS_CS_MIR_BIT; au_writel(sys_clksrc, SYS_CLKSRC); - /* setup the static bus controller */ + /* Setup the static bus controller */ au_writel(0x00000002, MEM_STCFG3); /* type = PCMCIA */ au_writel(0x280E3D07, MEM_STTIME3); /* 250ns cycle time */ au_writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */ - // get USB Functionality pin state (device vs host drive pins) - pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000); - // 2nd USB port is USB host - pin_func |= 0x8000; + /* + * Get USB Functionality pin state (device vs host drive pins). + */ + pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_USB; + /* 2nd USB port is USB host. */ + pin_func |= SYS_PF_USB; au_writel(pin_func, SYS_PINFUNC); } #endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */ @@ -94,12 +96,12 @@ void __init board_setup(void) /* Enable sys bus clock divider when IDLE state or no bus activity. */ au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL); - // Enable the RTC if not already enabled + /* Enable the RTC if not already enabled. */ if (!(readb(base + 0x28) & 0x20)) { writeb(readb(base + 0x28) | 0x20, base + 0x28); au_sync(); } - // Put the clock in BCD mode + /* Put the clock in BCD mode. */ if (readb(base + 0x2C) & 0x4) { /* reg B */ writeb(readb(base + 0x2c) & ~0x4, base + 0x2c); au_sync(); diff --git a/arch/mips/au1000/pb1100/init.c b/arch/mips/au1000/pb1100/init.c index c91344648ed317f8fe5f160395a62c83fd1322b4..8355483f3de2a65503e60ac5801eada3679ee08b 100644 --- a/arch/mips/au1000/pb1100/init.c +++ b/arch/mips/au1000/pb1100/init.c @@ -3,9 +3,8 @@ * BRIEF MODULE DESCRIPTION * Pb1100 board setup * - * Copyright 2002 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com + * Copyright 2002, 2008 MontaVista Software Inc. + * Author: MontaVista Software, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -46,8 +45,8 @@ void __init prom_init(void) unsigned long memsize; prom_argc = fw_arg0; - prom_argv = (char **) fw_arg1; - prom_envp = (char **) fw_arg3; + prom_argv = (char **)fw_arg1; + prom_envp = (char **)fw_arg3; prom_init_cmdline(); @@ -55,7 +54,7 @@ void __init prom_init(void) if (!memsize_str) memsize = 0x04000000; else - memsize = simple_strtol(memsize_str, NULL, 0); + memsize = strict_strtol(memsize_str, 0, NULL); add_memory_region(0, memsize, BOOT_MEM_RAM); } diff --git a/arch/mips/au1000/pb1100/irqmap.c b/arch/mips/au1000/pb1100/irqmap.c index b5021e3d477fcabd3b7db8222487380b14ee97f3..9b7dd8b41283c92e72ec8fa8cbce9ff64abc0c2f 100644 --- a/arch/mips/au1000/pb1100/irqmap.c +++ b/arch/mips/au1000/pb1100/irqmap.c @@ -1,6 +1,6 @@ /* * BRIEF MODULE DESCRIPTION - * Au1xxx irq map table + * Au1xx0 IRQ map table * * Copyright 2003 Embedded Edge, LLC * dan@embeddededge.com @@ -31,10 +31,10 @@ #include struct au1xxx_irqmap __initdata au1xxx_irq_map[] = { - { AU1000_GPIO_9, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card Fully_Interted# - { AU1000_GPIO_10, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card STSCHG# - { AU1000_GPIO_11, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card IRQ# - { AU1000_GPIO_13, INTC_INT_LOW_LEVEL, 0 }, // DC_IRQ# + { AU1000_GPIO_9, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card Fully_Inserted# */ + { AU1000_GPIO_10, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card STSCHG# */ + { AU1000_GPIO_11, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card IRQ# */ + { AU1000_GPIO_13, INTC_INT_LOW_LEVEL, 0 }, /* DC_IRQ# */ }; int __initdata au1xxx_nr_irqs = ARRAY_SIZE(au1xxx_irq_map); diff --git a/arch/mips/au1000/pb1200/Makefile b/arch/mips/au1000/pb1200/Makefile index 4fe02ea65a60e13b20e5706532e95260492c044b..d678adf7ce85fada6e5e7f463b2d062482e559a6 100644 --- a/arch/mips/au1000/pb1200/Makefile +++ b/arch/mips/au1000/pb1200/Makefile @@ -1,5 +1,5 @@ # -# Makefile for the Alchemy Semiconductor PB1200 board. +# Makefile for the Alchemy Semiconductor Pb1200/DBAu1200 boards. # lib-y := init.o board_setup.o irqmap.o diff --git a/arch/mips/au1000/pb1200/board_setup.c b/arch/mips/au1000/pb1200/board_setup.c index 4493a792cc4c5a79d83b058c2066b3aac18a1437..6cb2115059adaf84a73ac6387037f276f625ecb5 100644 --- a/arch/mips/au1000/pb1200/board_setup.c +++ b/arch/mips/au1000/pb1200/board_setup.c @@ -27,16 +27,8 @@ #include #include -#include #include - -#ifdef CONFIG_MIPS_PB1200 -#include -#endif - -#ifdef CONFIG_MIPS_DB1200 -#include -#endif +#include extern void _board_init_irq(void); extern void (*board_init_irq)(void); @@ -53,56 +45,57 @@ void __init board_setup(void) #if 0 { - u32 pin_func; - - /* Enable PSC1 SYNC for AC97. Normaly done in audio driver, - * but it is board specific code, so put it here. - */ - pin_func = au_readl(SYS_PINFUNC); - au_sync(); - pin_func |= SYS_PF_MUST_BE_SET | SYS_PF_PSC1_S1; - au_writel(pin_func, SYS_PINFUNC); - - au_writel(0, (u32)bcsr|0x10); /* turn off pcmcia power */ - au_sync(); + u32 pin_func; + + /* + * Enable PSC1 SYNC for AC97. Normaly done in audio driver, + * but it is board specific code, so put it here. + */ + pin_func = au_readl(SYS_PINFUNC); + au_sync(); + pin_func |= SYS_PF_MUST_BE_SET | SYS_PF_PSC1_S1; + au_writel(pin_func, SYS_PINFUNC); + + au_writel(0, (u32)bcsr | 0x10); /* turn off PCMCIA power */ + au_sync(); } #endif #if defined(CONFIG_I2C_AU1550) { - u32 freq0, clksrc; - u32 pin_func; - - /* Select SMBUS in CPLD */ - bcsr->resets &= ~(BCSR_RESETS_PCS0MUX); - - pin_func = au_readl(SYS_PINFUNC); - au_sync(); - pin_func &= ~(3<<17 | 1<<4); - /* Set GPIOs correctly */ - pin_func |= 2<<17; - au_writel(pin_func, SYS_PINFUNC); - au_sync(); - - /* The i2c driver depends on 50Mhz clock */ - freq0 = au_readl(SYS_FREQCTRL0); - au_sync(); - freq0 &= ~(SYS_FC_FRDIV1_MASK | SYS_FC_FS1 | SYS_FC_FE1); - freq0 |= (3<resets &= ~BCSR_RESETS_PCS0MUX; + + pin_func = au_readl(SYS_PINFUNC); + au_sync(); + pin_func &= ~(SYS_PINFUNC_P0A | SYS_PINFUNC_P0B); + /* Set GPIOs correctly */ + pin_func |= 2 << 17; + au_writel(pin_func, SYS_PINFUNC); + au_sync(); + + /* The I2C driver depends on 50 MHz clock */ + freq0 = au_readl(SYS_FREQCTRL0); + au_sync(); + freq0 &= ~(SYS_FC_FRDIV1_MASK | SYS_FC_FS1 | SYS_FC_FE1); + freq0 |= 3 << SYS_FC_FRDIV1_BIT; + /* 396 MHz / (3 + 1) * 2 == 49.5 MHz */ + au_writel(freq0, SYS_FREQCTRL0); + au_sync(); + freq0 |= SYS_FC_FE1; + au_writel(freq0, SYS_FREQCTRL0); + au_sync(); + + clksrc = au_readl(SYS_CLKSRC); + au_sync(); + clksrc &= ~(SYS_CS_CE0 | SYS_CS_DE0 | SYS_CS_ME0_MASK); + /* Bit 22 is EXTCLK0 for PSC0 */ + clksrc |= SYS_CS_MUX_FQ1 << SYS_CS_ME0_BIT; + au_writel(clksrc, SYS_CLKSRC); + au_sync(); } #endif @@ -116,27 +109,27 @@ void __init board_setup(void) #endif #endif - /* The Pb1200 development board uses external MUX for PSC0 to - support SMB/SPI. bcsr->resets bit 12: 0=SMB 1=SPI - */ + /* + * The Pb1200 development board uses external MUX for PSC0 to + * support SMB/SPI. bcsr->resets bit 12: 0=SMB 1=SPI + */ #ifdef CONFIG_I2C_AU1550 - bcsr->resets &= (~BCSR_RESETS_PCS0MUX); + bcsr->resets &= ~BCSR_RESETS_PCS0MUX; #endif au_sync(); #ifdef CONFIG_MIPS_PB1200 - printk("AMD Alchemy Pb1200 Board\n"); + printk(KERN_INFO "AMD Alchemy Pb1200 Board\n"); #endif #ifdef CONFIG_MIPS_DB1200 - printk("AMD Alchemy Db1200 Board\n"); + printk(KERN_INFO "AMD Alchemy Db1200 Board\n"); #endif /* Setup Pb1200 External Interrupt Controller */ board_init_irq = _board_init_irq; } -int -board_au1200fb_panel(void) +int board_au1200fb_panel(void) { BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR; int p; @@ -147,23 +140,23 @@ board_au1200fb_panel(void) return p; } -int -board_au1200fb_panel_init(void) +int board_au1200fb_panel_init(void) { /* Apply power */ - BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR; - bcsr->board |= (BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD | BCSR_BOARD_LCDBL); - /*printk("board_au1200fb_panel_init()\n"); */ + BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR; + + bcsr->board |= BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD | BCSR_BOARD_LCDBL; + /* printk(KERN_DEBUG "board_au1200fb_panel_init()\n"); */ return 0; } -int -board_au1200fb_panel_shutdown(void) +int board_au1200fb_panel_shutdown(void) { /* Remove power */ - BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR; - bcsr->board &= ~(BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD | BCSR_BOARD_LCDBL); - /*printk("board_au1200fb_panel_shutdown()\n"); */ + BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR; + + bcsr->board &= ~(BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD | + BCSR_BOARD_LCDBL); + /* printk(KERN_DEBUG "board_au1200fb_panel_shutdown()\n"); */ return 0; } - diff --git a/arch/mips/au1000/pb1200/init.c b/arch/mips/au1000/pb1200/init.c index 72af5500660b0517c9f0fec4253da6fdabeaacaf..09fd63b86062060719490113a5ba9cfdee83c74e 100644 --- a/arch/mips/au1000/pb1200/init.c +++ b/arch/mips/au1000/pb1200/init.c @@ -3,9 +3,8 @@ * BRIEF MODULE DESCRIPTION * PB1200 board setup * - * Copyright 2001 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com + * Copyright 2001, 2008 MontaVista Software Inc. + * Author: MontaVista Software, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -45,16 +44,15 @@ void __init prom_init(void) unsigned char *memsize_str; unsigned long memsize; - prom_argc = (int) fw_arg0; - prom_argv = (char **) fw_arg1; - prom_envp = (char **) fw_arg2; + prom_argc = (int)fw_arg0; + prom_argv = (char **)fw_arg1; + prom_envp = (char **)fw_arg2; prom_init_cmdline(); memsize_str = prom_getenv("memsize"); - if (!memsize_str) { + if (!memsize_str) memsize = 0x08000000; - } else { - memsize = simple_strtol(memsize_str, NULL, 0); - } + else + memsize = strict_strtol(memsize_str, 0, NULL); add_memory_region(0, memsize, BOOT_MEM_RAM); } diff --git a/arch/mips/au1000/pb1200/irqmap.c b/arch/mips/au1000/pb1200/irqmap.c index e61eb8e0b76bd96cccc2196a95ff9e86d83f9511..2a505ad8715b482b635a47e5ce4a28f88a59945b 100644 --- a/arch/mips/au1000/pb1200/irqmap.c +++ b/arch/mips/au1000/pb1200/irqmap.c @@ -39,25 +39,25 @@ #endif struct au1xxx_irqmap __initdata au1xxx_irq_map[] = { - { AU1000_GPIO_7, INTC_INT_LOW_LEVEL, 0 }, // This is exteranl interrupt cascade + /* This is external interrupt cascade */ + { AU1000_GPIO_7, INTC_INT_LOW_LEVEL, 0 }, }; int __initdata au1xxx_nr_irqs = ARRAY_SIZE(au1xxx_irq_map); /* - * Support for External interrupts on the PbAu1200 Development platform. + * Support for External interrupts on the Pb1200 Development platform. */ -static volatile int pb1200_cascade_en=0; +static volatile int pb1200_cascade_en; -irqreturn_t pb1200_cascade_handler( int irq, void *dev_id) +irqreturn_t pb1200_cascade_handler(int irq, void *dev_id) { unsigned short bisr = bcsr->int_status; int extirq_nr = 0; - /* Clear all the edge interrupts. This has no effect on level */ + /* Clear all the edge interrupts. This has no effect on level. */ bcsr->int_status = bisr; - for( ; bisr; bisr &= (bisr-1) ) - { + for ( ; bisr; bisr &= bisr - 1) { extirq_nr = PB1200_INT_BEGIN + __ffs(bisr); /* Ack and dispatch IRQ */ do_IRQ(extirq_nr); @@ -68,26 +68,20 @@ irqreturn_t pb1200_cascade_handler( int irq, void *dev_id) inline void pb1200_enable_irq(unsigned int irq_nr) { - bcsr->intset_mask = 1<<(irq_nr - PB1200_INT_BEGIN); - bcsr->intset = 1<<(irq_nr - PB1200_INT_BEGIN); + bcsr->intset_mask = 1 << (irq_nr - PB1200_INT_BEGIN); + bcsr->intset = 1 << (irq_nr - PB1200_INT_BEGIN); } inline void pb1200_disable_irq(unsigned int irq_nr) { - bcsr->intclr_mask = 1<<(irq_nr - PB1200_INT_BEGIN); - bcsr->intclr = 1<<(irq_nr - PB1200_INT_BEGIN); + bcsr->intclr_mask = 1 << (irq_nr - PB1200_INT_BEGIN); + bcsr->intclr = 1 << (irq_nr - PB1200_INT_BEGIN); } static unsigned int pb1200_setup_cascade(void) { - int err; - - err = request_irq(AU1000_GPIO_7, &pb1200_cascade_handler, - 0, "Pb1200 Cascade", &pb1200_cascade_handler); - if (err) - return err; - - return 0; + return request_irq(AU1000_GPIO_7, &pb1200_cascade_handler, + 0, "Pb1200 Cascade", &pb1200_cascade_handler); } static unsigned int pb1200_startup_irq(unsigned int irq) @@ -132,23 +126,23 @@ void _board_init_irq(void) unsigned int irq; #ifdef CONFIG_MIPS_PB1200 - /* We have a problem with CPLD rev3. Enable a workaround */ + /* We have a problem with CPLD rev 3. */ if (((bcsr->whoami & BCSR_WHOAMI_CPLD) >> 4) <= 3) { - printk("\nWARNING!!!\n"); - printk("\nWARNING!!!\n"); - printk("\nWARNING!!!\n"); - printk("\nWARNING!!!\n"); - printk("\nWARNING!!!\n"); - printk("\nWARNING!!!\n"); - printk("Pb1200 must be at CPLD rev4. Please have Pb1200\n"); - printk("updated to latest revision. This software will not\n"); - printk("work on anything less than CPLD rev4\n"); - printk("\nWARNING!!!\n"); - printk("\nWARNING!!!\n"); - printk("\nWARNING!!!\n"); - printk("\nWARNING!!!\n"); - printk("\nWARNING!!!\n"); - printk("\nWARNING!!!\n"); + printk(KERN_ERR "WARNING!!!\n"); + printk(KERN_ERR "WARNING!!!\n"); + printk(KERN_ERR "WARNING!!!\n"); + printk(KERN_ERR "WARNING!!!\n"); + printk(KERN_ERR "WARNING!!!\n"); + printk(KERN_ERR "WARNING!!!\n"); + printk(KERN_ERR "Pb1200 must be at CPLD rev 4. Please have Pb1200\n"); + printk(KERN_ERR "updated to latest revision. This software will\n"); + printk(KERN_ERR "not work on anything less than CPLD rev 4.\n"); + printk(KERN_ERR "WARNING!!!\n"); + printk(KERN_ERR "WARNING!!!\n"); + printk(KERN_ERR "WARNING!!!\n"); + printk(KERN_ERR "WARNING!!!\n"); + printk(KERN_ERR "WARNING!!!\n"); + printk(KERN_ERR "WARNING!!!\n"); panic("Game over. Your score is 0."); } #endif @@ -161,6 +155,6 @@ void _board_init_irq(void) /* * GPIO_7 can not be hooked here, so it is hooked upon first - * request of any source attached to the cascade + * request of any source attached to the cascade. */ } diff --git a/arch/mips/au1000/pb1500/Makefile b/arch/mips/au1000/pb1500/Makefile index 97a730813cd37508ab20bf7f934a54e42f4b60da..602f38df20bbfe659e92bada6685637f2a2f0433 100644 --- a/arch/mips/au1000/pb1500/Makefile +++ b/arch/mips/au1000/pb1500/Makefile @@ -1,8 +1,8 @@ # -# Copyright 2000,2001 MontaVista Software Inc. -# Author: MontaVista Software, Inc. -# ppopov@mvista.com or source@mvista.com +# Copyright 2000, 2001, 2008 MontaVista Software Inc. +# Author: MontaVista Software, Inc. # # Makefile for the Alchemy Semiconductor Pb1500 board. +# lib-y := init.o board_setup.o irqmap.o diff --git a/arch/mips/au1000/pb1500/board_setup.c b/arch/mips/au1000/pb1500/board_setup.c index 24c652e8ec4b7f542b264430ed3e6b4ef4b61fab..035771c6e5b88f0faab9d99ca13a133157f2bdcd 100644 --- a/arch/mips/au1000/pb1500/board_setup.c +++ b/arch/mips/au1000/pb1500/board_setup.c @@ -1,7 +1,6 @@ /* - * Copyright 2000 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com + * Copyright 2000, 2008 MontaVista Software Inc. + * Author: MontaVista Software, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -32,8 +31,8 @@ void board_reset(void) { - /* Hit BCSR.SYSTEM_CONTROL[SW_RST] */ - au_writel(0x00000000, 0xAE00001C); + /* Hit BCSR.RST_VDDI[SOFT_RESET] */ + au_writel(0x00000000, PB1500_RST_VDDI); } void __init board_setup(void) @@ -42,7 +41,7 @@ void __init board_setup(void) u32 sys_freqctrl, sys_clksrc; sys_clksrc = sys_freqctrl = pin_func = 0; - // set AUX clock to 12MHz * 8 = 96 MHz + /* Set AUX clock to 12 MHz * 8 = 96 MHz */ au_writel(8, SYS_AUXPLL); au_writel(0, SYS_PINSTATERD); udelay(100); @@ -51,51 +50,48 @@ void __init board_setup(void) /* GPIO201 is input for PCMCIA card detect */ /* GPIO203 is input for PCMCIA interrupt request */ - au_writel(au_readl(GPIO2_DIR) & (u32)(~((1<<1)|(1<<3))), GPIO2_DIR); + au_writel(au_readl(GPIO2_DIR) & ~((1 << 1) | (1 << 3)), GPIO2_DIR); - /* zero and disable FREQ2 */ + /* Zero and disable FREQ2 */ sys_freqctrl = au_readl(SYS_FREQCTRL0); sys_freqctrl &= ~0xFFF00000; au_writel(sys_freqctrl, SYS_FREQCTRL0); /* zero and disable USBH/USBD clocks */ sys_clksrc = au_readl(SYS_CLKSRC); - sys_clksrc &= ~0x00007FE0; + sys_clksrc &= ~(SYS_CS_CUD | SYS_CS_DUD | SYS_CS_MUD_MASK | + SYS_CS_CUH | SYS_CS_DUH | SYS_CS_MUH_MASK); au_writel(sys_clksrc, SYS_CLKSRC); sys_freqctrl = au_readl(SYS_FREQCTRL0); sys_freqctrl &= ~0xFFF00000; sys_clksrc = au_readl(SYS_CLKSRC); - sys_clksrc &= ~0x00007FE0; + sys_clksrc &= ~(SYS_CS_CUD | SYS_CS_DUD | SYS_CS_MUD_MASK | + SYS_CS_CUH | SYS_CS_DUH | SYS_CS_MUH_MASK); - // FREQ2 = aux/2 = 48 MHz - sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20)); + /* FREQ2 = aux/2 = 48 MHz */ + sys_freqctrl |= (0 << SYS_FC_FRDIV2_BIT) | SYS_FC_FE2 | SYS_FC_FS2; au_writel(sys_freqctrl, SYS_FREQCTRL0); /* * Route 48MHz FREQ2 into USB Host and/or Device */ -#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) - sys_clksrc |= ((4<<12) | (0<<11) | (0<<10)); -#endif + sys_clksrc |= SYS_CS_MUX_FQ2 << SYS_CS_MUH_BIT; au_writel(sys_clksrc, SYS_CLKSRC); - - pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000); - // 2nd USB port is USB host - pin_func |= 0x8000; + pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_USB; + /* 2nd USB port is USB host */ + pin_func |= SYS_PF_USB; au_writel(pin_func, SYS_PINFUNC); #endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */ - - #ifdef CONFIG_PCI - // Setup PCI bus controller + /* Setup PCI bus controller */ au_writel(0, Au1500_PCI_CMEM); au_writel(0x00003fff, Au1500_CFG_BASE); #if defined(__MIPSEB__) - au_writel(0xf | (2<<6) | (1<<4), Au1500_PCI_CFG); + au_writel(0xf | (2 << 6) | (1 << 4), Au1500_PCI_CFG); #else au_writel(0xf, Au1500_PCI_CFG); #endif @@ -112,11 +108,11 @@ void __init board_setup(void) /* Enable the RTC if not already enabled */ if (!(au_readl(0xac000028) & 0x20)) { - printk("enabling clock ...\n"); + printk(KERN_INFO "enabling clock ...\n"); au_writel((au_readl(0xac000028) | 0x20), 0xac000028); } /* Put the clock in BCD mode */ - if (au_readl(0xac00002C) & 0x4) { /* reg B */ + if (au_readl(0xac00002c) & 0x4) { /* reg B */ au_writel(au_readl(0xac00002c) & ~0x4, 0xac00002c); au_sync(); } diff --git a/arch/mips/au1000/pb1500/init.c b/arch/mips/au1000/pb1500/init.c index 488507c07db929e40e5b99dd5d328c88b574b845..49f51e165863d40e004408b4a1199f16c59d29b1 100644 --- a/arch/mips/au1000/pb1500/init.c +++ b/arch/mips/au1000/pb1500/init.c @@ -1,11 +1,10 @@ /* * * BRIEF MODULE DESCRIPTION - * PB1500 board setup + * Pb1500 board setup * - * Copyright 2001 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com + * Copyright 2001, 2008 MontaVista Software Inc. + * Author: MontaVista Software, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -45,16 +44,15 @@ void __init prom_init(void) unsigned char *memsize_str; unsigned long memsize; - prom_argc = (int) fw_arg0; - prom_argv = (char **) fw_arg1; - prom_envp = (char **) fw_arg2; + prom_argc = (int)fw_arg0; + prom_argv = (char **)fw_arg1; + prom_envp = (char **)fw_arg2; prom_init_cmdline(); memsize_str = prom_getenv("memsize"); - if (!memsize_str) { + if (!memsize_str) memsize = 0x04000000; - } else { - memsize = simple_strtol(memsize_str, NULL, 0); - } + else + memsize = strict_strtol(memsize_str, 0, NULL); add_memory_region(0, memsize, BOOT_MEM_RAM); } diff --git a/arch/mips/au1000/pb1500/irqmap.c b/arch/mips/au1000/pb1500/irqmap.c index 4817ab44d07f660e7970703d2e37c0dca4389903..39c4682766a8ec1c696ef97ab4138badbb08443f 100644 --- a/arch/mips/au1000/pb1500/irqmap.c +++ b/arch/mips/au1000/pb1500/irqmap.c @@ -31,12 +31,12 @@ #include char irq_tab_alchemy[][5] __initdata = { - [12] = { -1, INTA, INTX, INTX, INTX}, /* IDSEL 12 - HPT370 */ - [13] = { -1, INTA, INTB, INTC, INTD}, /* IDSEL 13 - PCI slot */ + [12] = { -1, INTA, INTX, INTX, INTX }, /* IDSEL 12 - HPT370 */ + [13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot */ }; struct au1xxx_irqmap __initdata au1xxx_irq_map[] = { - { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0}, + { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0 }, { AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 }, { AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 }, { AU1500_GPIO_203, INTC_INT_LOW_LEVEL, 0 }, diff --git a/arch/mips/au1000/pb1550/Makefile b/arch/mips/au1000/pb1550/Makefile index aa35bc6cb8cf7b9da7569327ea3b2cc8bae50ed3..7d8beca87fa56f8eab2d40f6e26912ab20c9bfb0 100644 --- a/arch/mips/au1000/pb1550/Makefile +++ b/arch/mips/au1000/pb1550/Makefile @@ -1,9 +1,8 @@ # -# Copyright 2000 MontaVista Software Inc. -# Author: MontaVista Software, Inc. -# ppopov@mvista.com or source@mvista.com +# Copyright 2000, 2008 MontaVista Software Inc. +# Author: MontaVista Software, Inc. # -# Makefile for the Alchemy Semiconductor PB1000 board. +# Makefile for the Alchemy Semiconductor Pb1550 board. # lib-y := init.o board_setup.o irqmap.o diff --git a/arch/mips/au1000/pb1550/board_setup.c b/arch/mips/au1000/pb1550/board_setup.c index 45d60872b5655b49905c3e300365c30cd2729ea5..0ed76b64b6ab9d1db957b98dfeb11ac8e37cbca9 100644 --- a/arch/mips/au1000/pb1550/board_setup.c +++ b/arch/mips/au1000/pb1550/board_setup.c @@ -3,9 +3,8 @@ * BRIEF MODULE DESCRIPTION * Alchemy Pb1550 board setup. * - * Copyright 2000 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com + * Copyright 2000, 2008 MontaVista Software Inc. + * Author: MontaVista Software, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -35,15 +34,16 @@ void board_reset(void) { - /* Hit BCSR.SYSTEM_CONTROL[SW_RST] */ - au_writew(au_readw(0xAF00001C) & ~(1<<15), 0xAF00001C); + /* Hit BCSR.SYSTEM[RESET] */ + au_writew(au_readw(0xAF00001C) & ~BCSR_SYSTEM_RESET, 0xAF00001C); } void __init board_setup(void) { u32 pin_func; - /* Enable PSC1 SYNC for AC97. Normaly done in audio driver, + /* + * Enable PSC1 SYNC for AC'97. Normaly done in audio driver, * but it is board specific code, so put it here. */ pin_func = au_readl(SYS_PINFUNC); @@ -51,8 +51,8 @@ void __init board_setup(void) pin_func |= SYS_PF_MUST_BE_SET | SYS_PF_PSC1_S1; au_writel(pin_func, SYS_PINFUNC); - au_writel(0, (u32)bcsr|0x10); /* turn off pcmcia power */ + au_writel(0, (u32)bcsr | 0x10); /* turn off PCMCIA power */ au_sync(); - printk("AMD Alchemy Pb1550 Board\n"); + printk(KERN_INFO "AMD Alchemy Pb1550 Board\n"); } diff --git a/arch/mips/au1000/pb1550/init.c b/arch/mips/au1000/pb1550/init.c index f6b2fc587980102a5f561609143ffb55b7651090..1b5f58434bb78390cad601c8b44bb4bf628a7d46 100644 --- a/arch/mips/au1000/pb1550/init.c +++ b/arch/mips/au1000/pb1550/init.c @@ -1,11 +1,10 @@ /* * * BRIEF MODULE DESCRIPTION - * PB1550 board setup + * Pb1550 board setup * - * Copyright 2001 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com + * Copyright 2001, 2008 MontaVista Software Inc. + * Author: MontaVista Software, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -45,16 +44,15 @@ void __init prom_init(void) unsigned char *memsize_str; unsigned long memsize; - prom_argc = (int) fw_arg0; - prom_argv = (char **) fw_arg1; - prom_envp = (char **) fw_arg2; + prom_argc = (int)fw_arg0; + prom_argv = (char **)fw_arg1; + prom_envp = (char **)fw_arg2; prom_init_cmdline(); memsize_str = prom_getenv("memsize"); - if (!memsize_str) { + if (!memsize_str) memsize = 0x08000000; - } else { - memsize = simple_strtol(memsize_str, NULL, 0); - } + else + memsize = strict_strtol(memsize_str, 0, NULL); add_memory_region(0, memsize, BOOT_MEM_RAM); } diff --git a/arch/mips/au1000/pb1550/irqmap.c b/arch/mips/au1000/pb1550/irqmap.c index e1dac37af08ac3ec426211b382c342e5bfd2afe7..a02a4d1fa899ce6d876ddc914e21e82bcaaf5af7 100644 --- a/arch/mips/au1000/pb1550/irqmap.c +++ b/arch/mips/au1000/pb1550/irqmap.c @@ -1,6 +1,6 @@ /* * BRIEF MODULE DESCRIPTION - * Au1xxx irq map table + * Au1xx0 IRQ map table * * Copyright 2003 Embedded Edge, LLC * dan@embeddededge.com @@ -31,8 +31,8 @@ #include char irq_tab_alchemy[][5] __initdata = { - [12] = { -1, INTB, INTC, INTD, INTA}, /* IDSEL 12 - PCI slot 2 (left) */ - [13] = { -1, INTA, INTB, INTC, INTD}, /* IDSEL 13 - PCI slot 1 (right) */ + [12] = { -1, INTB, INTC, INTD, INTA }, /* IDSEL 12 - PCI slot 2 (left) */ + [13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot 1 (right) */ }; struct au1xxx_irqmap __initdata au1xxx_irq_map[] = { diff --git a/arch/mips/au1000/xxs1500/Makefile b/arch/mips/au1000/xxs1500/Makefile index 44d7f7056ae76d2e7ece1e34510742b772c3f718..db3c526f64d8afd2d7eb39a329ad90d3da627410 100644 --- a/arch/mips/au1000/xxs1500/Makefile +++ b/arch/mips/au1000/xxs1500/Makefile @@ -1,7 +1,6 @@ # # Copyright 2003 MontaVista Software Inc. -# Author: MontaVista Software, Inc. -# ppopov@mvista.com or source@mvista.com +# Author: MontaVista Software, Inc. # # Makefile for MyCable XXS1500 board. # diff --git a/arch/mips/au1000/xxs1500/board_setup.c b/arch/mips/au1000/xxs1500/board_setup.c index 79d1798621bfede35ca23fbaa5bb80532222cfee..4c587acac5c3707a4a21e3ab28f96eb62dbf8b26 100644 --- a/arch/mips/au1000/xxs1500/board_setup.c +++ b/arch/mips/au1000/xxs1500/board_setup.c @@ -1,7 +1,6 @@ /* - * Copyright 2000-2003 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com + * Copyright 2000-2003, 2008 MontaVista Software Inc. + * Author: MontaVista Software, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -39,40 +38,40 @@ void __init board_setup(void) { u32 pin_func; - // set multiple use pins (UART3/GPIO) to UART (it's used as UART too) - pin_func = au_readl(SYS_PINFUNC) & (u32)(~SYS_PF_UR3); + /* Set multiple use pins (UART3/GPIO) to UART (it's used as UART too) */ + pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_UR3; pin_func |= SYS_PF_UR3; au_writel(pin_func, SYS_PINFUNC); - // enable UART - au_writel(0x01, UART3_ADDR+UART_MOD_CNTRL); // clock enable (CE) + /* Enable UART */ + au_writel(0x01, UART3_ADDR + UART_MOD_CNTRL); /* clock enable (CE) */ mdelay(10); - au_writel(0x03, UART3_ADDR+UART_MOD_CNTRL); // CE and "enable" + au_writel(0x03, UART3_ADDR + UART_MOD_CNTRL); /* CE and "enable" */ mdelay(10); - // enable DTR = USB power up - au_writel(0x01, UART3_ADDR+UART_MCR); //? UART_MCR_DTR is 0x01??? + /* Enable DTR = USB power up */ + au_writel(0x01, UART3_ADDR + UART_MCR); /* UART_MCR_DTR is 0x01??? */ #ifdef CONFIG_PCMCIA_XXS1500 - /* setup pcmcia signals */ + /* Setup PCMCIA signals */ au_writel(0, SYS_PININPUTEN); - /* gpio 0, 1, and 4 are inputs */ - au_writel(1 | (1<<1) | (1<<4), SYS_TRIOUTCLR); + /* GPIO 0, 1, and 4 are inputs */ + au_writel(1 | (1 << 1) | (1 << 4), SYS_TRIOUTCLR); - /* enable GPIO2 if not already enabled */ + /* Enable GPIO2 if not already enabled */ au_writel(1, GPIO2_ENABLE); - /* gpio2 208/9/10/11 are inputs */ - au_writel((1<<8) | (1<<9) | (1<<10) | (1<<11), GPIO2_DIR); + /* GPIO2 208/9/10/11 are inputs */ + au_writel((1 << 8) | (1 << 9) | (1 << 10) | (1 << 11), GPIO2_DIR); - /* turn off power */ - au_writel((au_readl(GPIO2_PINSTATE) & ~(1<<14))|(1<<30), GPIO2_OUTPUT); + /* Turn off power */ + au_writel((au_readl(GPIO2_PINSTATE) & ~(1 << 14)) | (1 << 30), + GPIO2_OUTPUT); #endif - #ifdef CONFIG_PCI #if defined(__MIPSEB__) - au_writel(0xf | (2<<6) | (1<<4), Au1500_PCI_CFG); + au_writel(0xf | (2 << 6) | (1 << 4), Au1500_PCI_CFG); #else au_writel(0xf, Au1500_PCI_CFG); #endif diff --git a/arch/mips/au1000/xxs1500/init.c b/arch/mips/au1000/xxs1500/init.c index 24fc6e132dc0276f7916856ee550321c8294e614..b849bf501c0423fb93d8cb82f3474324b971cca1 100644 --- a/arch/mips/au1000/xxs1500/init.c +++ b/arch/mips/au1000/xxs1500/init.c @@ -2,9 +2,8 @@ * BRIEF MODULE DESCRIPTION * XXS1500 board setup * - * Copyright 2003 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com + * Copyright 2003, 2008 MontaVista Software Inc. + * Author: MontaVista Software, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -45,8 +44,8 @@ void __init prom_init(void) unsigned long memsize; prom_argc = fw_arg0; - prom_argv = (char **) fw_arg1; - prom_envp = (char **) fw_arg2; + prom_argv = (char **)fw_arg1; + prom_envp = (char **)fw_arg2; prom_init_cmdline(); @@ -54,6 +53,6 @@ void __init prom_init(void) if (!memsize_str) memsize = 0x04000000; else - memsize = simple_strtol(memsize_str, NULL, 0); + memsize = strict_strtol(memsize_str, 0, NULL); add_memory_region(0, memsize, BOOT_MEM_RAM); } diff --git a/arch/mips/au1000/xxs1500/irqmap.c b/arch/mips/au1000/xxs1500/irqmap.c index dd6e3d1eb4d4da4cf09d531d420de4b4532ca9e2..edf06ed1187000ad3f04fe13f2ab297dc703d894 100644 --- a/arch/mips/au1000/xxs1500/irqmap.c +++ b/arch/mips/au1000/xxs1500/irqmap.c @@ -31,7 +31,7 @@ #include struct au1xxx_irqmap __initdata au1xxx_irq_map[] = { - { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0}, + { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0 }, { AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 }, { AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 }, { AU1500_GPIO_203, INTC_INT_LOW_LEVEL, 0 }, diff --git a/arch/mips/emma2rh/markeins/setup.c b/arch/mips/emma2rh/markeins/setup.c index 82f9e9013e70c9ff38cab59fa9011c313b8af3ea..62bfb455d1b11c9edb89ab6d1683c0aaf6b20fef 100644 --- a/arch/mips/emma2rh/markeins/setup.c +++ b/arch/mips/emma2rh/markeins/setup.c @@ -76,7 +76,9 @@ static void markeins_machine_power_off(void) while (1) ; } -static unsigned long clock[4] = { 166500000, 187312500, 199800000, 210600000 }; +static unsigned long __initdata emma2rh_clock[4] = { + 166500000, 187312500, 199800000, 210600000 +}; static unsigned int __init detect_bus_frequency(unsigned long rtc_base) { @@ -85,7 +87,8 @@ static unsigned int __init detect_bus_frequency(unsigned long rtc_base) /* detect from boot strap */ reg = emma2rh_in32(EMMA2RH_BHIF_STRAP_0); reg = (reg >> 4) & 0x3; - return clock[reg]; + + return emma2rh_clock[reg]; } void __init plat_time_init(void) diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 45545be3eb86ce015cabdc65059a32189d89595a..cc0244036aec793b9f45c983d346151bab3a4ed3 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -56,9 +56,9 @@ obj-$(CONFIG_MIPS_MT_SMP) += smp-mt.o obj-$(CONFIG_MIPS_CMP) += smp-cmp.o obj-$(CONFIG_CPU_MIPSR2) += spram.o -obj-$(CONFIG_MIPS_APSP_KSPD) += kspd.o obj-$(CONFIG_MIPS_VPE_LOADER) += vpe.o obj-$(CONFIG_MIPS_VPE_APSP_API) += rtlx.o +obj-$(CONFIG_MIPS_APSP_KSPD) += kspd.o obj-$(CONFIG_I8259) += i8259.o obj-$(CONFIG_IRQ_CPU) += irq_cpu.o diff --git a/arch/mips/kernel/cpu-bugs64.c b/arch/mips/kernel/cpu-bugs64.c index a1b48af0992ffb297c588c1a2cc5ae22de826871..02b7713cf71c3a8db4c89c98f0b61d9b31316473 100644 --- a/arch/mips/kernel/cpu-bugs64.c +++ b/arch/mips/kernel/cpu-bugs64.c @@ -38,7 +38,7 @@ static inline void align_mod(const int align, const int mod) ".endr\n\t" ".set pop" : - : GCC_IMM_ASM(align), GCC_IMM_ASM(mod)); + : GCC_IMM_ASM() (align), GCC_IMM_ASM() (mod)); } static inline void mult_sh_align_mod(long *v1, long *v2, long *w, diff --git a/arch/mips/kernel/init_task.c b/arch/mips/kernel/init_task.c index aeda7f58391b725b9ba0d33de98e7ce9550c4ec5..d72487ad7c15526fa79722ad4325c38aa8602ecd 100644 --- a/arch/mips/kernel/init_task.c +++ b/arch/mips/kernel/init_task.c @@ -10,7 +10,6 @@ #include static struct fs_struct init_fs = INIT_FS; -static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS(init_signals); static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); struct mm_struct init_mm = INIT_MM(init_mm); diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c index 290d8e3a664d71bd71e2fb582dd004025a06b34d..469c7237e5baf4f3e7b1acc3b32bcde5fb319955 100644 --- a/arch/mips/kernel/irixelf.c +++ b/arch/mips/kernel/irixelf.c @@ -578,7 +578,7 @@ static inline int map_interpreter(struct elf_phdr *epp, struct elfhdr *ihp, * process and the system, here we map the page and fill the * structure */ -static void irix_map_prda_page(void) +static int irix_map_prda_page(void) { unsigned long v; struct prda *pp; @@ -587,8 +587,8 @@ static void irix_map_prda_page(void) v = do_brk(PRDA_ADDRESS, PAGE_SIZE); up_write(¤t->mm->mmap_sem); - if (v < 0) - return; + if (v != PRDA_ADDRESS) + return v; /* v must be an error code */ pp = (struct prda *) v; pp->prda_sys.t_pid = task_pid_vnr(current); @@ -596,6 +596,8 @@ static void irix_map_prda_page(void) pp->prda_sys.t_rpid = task_pid_vnr(current); /* We leave the rest set to zero */ + + return 0; } @@ -781,7 +783,8 @@ static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs) * IRIX maps a page at 0x200000 which holds some system * information. Programs depend on this. */ - irix_map_prda_page(); + if (irix_map_prda_page()) + goto out_free_dentry; padzero(elf_bss); diff --git a/arch/mips/kernel/kspd.c b/arch/mips/kernel/kspd.c index ceb62dce1c9c6872966d05e33dacdc96acd5218f..b0591ae0ce566456ed7c88eaa955d191a17bcaaa 100644 --- a/arch/mips/kernel/kspd.c +++ b/arch/mips/kernel/kspd.c @@ -257,7 +257,7 @@ void sp_work_handle_request(void) vcwd = vpe_getcwd(tclimit); - /* change to the cwd of the process that loaded the SP program */ + /* change to cwd of the process that loaded the SP program */ old_fs = get_fs(); set_fs(KERNEL_DS); sys_chdir(vcwd); @@ -323,6 +323,9 @@ static void sp_cleanup(void) set >>= 1; } } + + /* Put daemon cwd back to root to avoid umount problems */ + sys_chdir("/"); } static int channel_open = 0; diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c index 0233798f71552c4c64b85e9a61e45f3aafc9fe6c..b88f1c18ff4dc2fe7b5877972ec39314e0d5639d 100644 --- a/arch/mips/kernel/rtlx.c +++ b/arch/mips/kernel/rtlx.c @@ -72,6 +72,15 @@ static void rtlx_dispatch(void) static irqreturn_t rtlx_interrupt(int irq, void *dev_id) { int i; + unsigned int flags, vpeflags; + + /* Ought not to be strictly necessary for SMTC builds */ + local_irq_save(flags); + vpeflags = dvpe(); + set_c0_status(0x100 << MIPS_CPU_RTLX_IRQ); + irq_enable_hazard(); + evpe(vpeflags); + local_irq_restore(flags); for (i = 0; i < RTLX_CHANNELS; i++) { wake_up(&channel_wqs[i].lx_queue); @@ -108,7 +117,8 @@ static void __used dump_rtlx(void) static int rtlx_init(struct rtlx_info *rtlxi) { if (rtlxi->id != RTLX_ID) { - printk(KERN_ERR "no valid RTLX id at 0x%p 0x%lx\n", rtlxi, rtlxi->id); + printk(KERN_ERR "no valid RTLX id at 0x%p 0x%lx\n", + rtlxi, rtlxi->id); return -ENOEXEC; } @@ -162,18 +172,17 @@ int rtlx_open(int index, int can_sleep) if (rtlx == NULL) { if( (p = vpe_get_shared(tclimit)) == NULL) { - if (can_sleep) { - __wait_event_interruptible(channel_wqs[index].lx_queue, - (p = vpe_get_shared(tclimit)), - ret); - if (ret) - goto out_fail; - } else { - printk(KERN_DEBUG "No SP program loaded, and device " - "opened with O_NONBLOCK\n"); - ret = -ENOSYS; + if (can_sleep) { + __wait_event_interruptible(channel_wqs[index].lx_queue, + (p = vpe_get_shared(tclimit)), ret); + if (ret) goto out_fail; - } + } else { + printk(KERN_DEBUG "No SP program loaded, and device " + "opened with O_NONBLOCK\n"); + ret = -ENOSYS; + goto out_fail; + } } smp_rmb(); @@ -182,7 +191,9 @@ int rtlx_open(int index, int can_sleep) DEFINE_WAIT(wait); for (;;) { - prepare_to_wait(&channel_wqs[index].lx_queue, &wait, TASK_INTERRUPTIBLE); + prepare_to_wait( + &channel_wqs[index].lx_queue, + &wait, TASK_INTERRUPTIBLE); smp_rmb(); if (*p != NULL) break; @@ -195,7 +206,7 @@ int rtlx_open(int index, int can_sleep) } finish_wait(&channel_wqs[index].lx_queue, &wait); } else { - printk(" *vpe_get_shared is NULL. " + pr_err(" *vpe_get_shared is NULL. " "Has an SP program been loaded?\n"); ret = -ENOSYS; goto out_fail; @@ -203,8 +214,9 @@ int rtlx_open(int index, int can_sleep) } if ((unsigned int)*p < KSEG0) { - printk(KERN_WARNING "vpe_get_shared returned an invalid pointer " - "maybe an error code %d\n", (int)*p); + printk(KERN_WARNING "vpe_get_shared returned an " + "invalid pointer maybe an error code %d\n", + (int)*p); ret = -ENOSYS; goto out_fail; } @@ -232,6 +244,10 @@ out_ret: int rtlx_release(int index) { + if (rtlx == NULL) { + pr_err("rtlx_release() with null rtlx\n"); + return 0; + } rtlx->channel[index].lx_state = RTLX_STATE_UNUSED; return 0; } @@ -251,8 +267,8 @@ unsigned int rtlx_read_poll(int index, int can_sleep) int ret = 0; __wait_event_interruptible(channel_wqs[index].lx_queue, - chan->lx_read != chan->lx_write || sp_stopping, - ret); + (chan->lx_read != chan->lx_write) || + sp_stopping, ret); if (ret) return ret; @@ -282,7 +298,9 @@ static inline int write_spacefree(int read, int write, int size) unsigned int rtlx_write_poll(int index) { struct rtlx_channel *chan = &rtlx->channel[index]; - return write_spacefree(chan->rt_read, chan->rt_write, chan->buffer_size); + + return write_spacefree(chan->rt_read, chan->rt_write, + chan->buffer_size); } ssize_t rtlx_read(int index, void __user *buff, size_t count) @@ -344,8 +362,8 @@ ssize_t rtlx_write(int index, const void __user *buffer, size_t count) rt_read = rt->rt_read; /* total number of bytes to copy */ - count = min(count, - (size_t)write_spacefree(rt_read, rt->rt_write, rt->buffer_size)); + count = min(count, (size_t)write_spacefree(rt_read, rt->rt_write, + rt->buffer_size)); /* first bit from write pointer to the end of the buffer, or count */ fl = min(count, (size_t) rt->buffer_size - rt->rt_write); @@ -514,6 +532,11 @@ static int __init rtlx_module_init(void) if (cpu_has_vint) set_vi_handler(MIPS_CPU_RTLX_IRQ, rtlx_dispatch); + else { + pr_err("APRP RTLX init on non-vectored-interrupt processor\n"); + err = -ENODEV; + goto out_chrdev; + } rtlx_irq.dev_id = rtlx; setup_irq(rtlx_irq_num, &rtlx_irq); diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 39f3dfe134fb9cb619c3c49d48de00be105a9490..c6a063b2a0d9fcc9a7296a580f8c4ee65b0b89f3 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -331,6 +331,7 @@ static void __init bootmem_init(void) /* * Determine low and high memory ranges */ + max_pfn = max_low_pfn; if (max_low_pfn > PFN_DOWN(HIGHMEM_START)) { #ifdef CONFIG_HIGHMEM highstart_pfn = PFN_DOWN(HIGHMEM_START); diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 33780cc61ce902e80a289410d46bded866e582f2..63370cdd3c90f83f4ed04fcb926148fa8f4d061f 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -87,8 +87,8 @@ struct plat_smp_ops *mp_ops; __cpuinit void register_smp_ops(struct plat_smp_ops *ops) { - if (ops) - printk(KERN_WARNING "Overriding previous set SMP ops\n"); + if (mp_ops) + printk(KERN_WARNING "Overriding previously set SMP ops\n"); mp_ops = ops; } diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c index 39804c584eddbaf794a3eda5526bd8122f3bb817..2794501ff302923b38afe00c3e90531379307bf2 100644 --- a/arch/mips/kernel/vpe.c +++ b/arch/mips/kernel/vpe.c @@ -269,7 +269,7 @@ static void *alloc_progmem(unsigned long len) * This means you must tell Linux to use less memory than you * physically have, for example by passing a mem= boot argument. */ - addr = pfn_to_kaddr(max_pfn); + addr = pfn_to_kaddr(max_low_pfn); memset(addr, 0, len); #else /* simple grab some mem for now */ @@ -781,10 +781,15 @@ static int vpe_run(struct vpe * v) /* take system out of configuration state */ clear_c0_mvpcontrol(MVPCONTROL_VPC); + /* + * SMTC/SMVP kernels manage VPE enable independently, + * but uniprocessor kernels need to turn it on, even + * if that wasn't the pre-dvpe() state. + */ #ifdef CONFIG_SMP - evpe(EVPE_ENABLE); -#else evpe(vpeflags); +#else + evpe(EVPE_ENABLE); #endif emt(dmt_flag); local_irq_restore(flags); @@ -840,7 +845,7 @@ static int vpe_elfload(struct vpe * v) /* Sanity checks against insmoding binaries or wrong arch, weird elf version */ - if (memcmp(hdr->e_ident, ELFMAG, 4) != 0 + if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0 || (hdr->e_type != ET_REL && hdr->e_type != ET_EXEC) || !elf_check_arch(hdr) || hdr->e_shentsize != sizeof(*sechdrs)) { @@ -947,12 +952,14 @@ static int vpe_elfload(struct vpe * v) struct elf_phdr *phdr = (struct elf_phdr *) ((char *)hdr + hdr->e_phoff); for (i = 0; i < hdr->e_phnum; i++) { - if (phdr->p_type != PT_LOAD) - continue; - - memcpy((void *)phdr->p_paddr, (char *)hdr + phdr->p_offset, phdr->p_filesz); - memset((void *)phdr->p_paddr + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz); - phdr++; + if (phdr->p_type == PT_LOAD) { + memcpy((void *)phdr->p_paddr, + (char *)hdr + phdr->p_offset, + phdr->p_filesz); + memset((void *)phdr->p_paddr + phdr->p_filesz, + 0, phdr->p_memsz - phdr->p_filesz); + } + phdr++; } for (i = 0; i < hdr->e_shnum; i++) { @@ -1107,7 +1114,7 @@ static int vpe_release(struct inode *inode, struct file *filp) return -ENODEV; hdr = (Elf_Ehdr *) v->pbuffer; - if (memcmp(hdr->e_ident, ELFMAG, 4) == 0) { + if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) == 0) { if (vpe_elfload(v) >= 0) { vpe_run(v); } else { diff --git a/arch/mips/mm/highmem.c b/arch/mips/mm/highmem.c index 10dd2af2343bfa791a9f63657869fa4b9641272c..8f2cd8eda7415c37d0a2ff2da7a8c3e1d587ebd0 100644 --- a/arch/mips/mm/highmem.c +++ b/arch/mips/mm/highmem.c @@ -116,4 +116,3 @@ EXPORT_SYMBOL(__kmap); EXPORT_SYMBOL(__kunmap); EXPORT_SYMBOL(__kmap_atomic); EXPORT_SYMBOL(__kunmap_atomic); -EXPORT_SYMBOL(__kmap_atomic_to_page); diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c index da8cbb6899dcde8cb439fd53766f0281dad78c1d..b40df7d2cf4465858abb998497d384a46af32cb2 100644 --- a/arch/mips/oprofile/op_model_mipsxx.c +++ b/arch/mips/oprofile/op_model_mipsxx.c @@ -281,7 +281,7 @@ static inline int n_counters(void) static void reset_counters(void *arg) { - int counters = (int)arg; + int counters = (int)(long)arg; switch (counters) { case 4: w_c0_perfctrl3(0); @@ -313,7 +313,7 @@ static int __init mipsxx_init(void) if (!cpu_has_mipsmt_pertccounters) counters = counters_total_to_per_cpu(counters); #endif - on_each_cpu(reset_counters, (void *)counters, 0, 1); + on_each_cpu(reset_counters, (void *)(long)counters, 0, 1); op_model_mipsxx_ops.num_counters = counters; switch (current_cpu_type()) { @@ -382,7 +382,7 @@ static void mipsxx_exit(void) int counters = op_model_mipsxx_ops.num_counters; counters = counters_per_cpu_to_total(counters); - on_each_cpu(reset_counters, (void *)counters, 0, 1); + on_each_cpu(reset_counters, (void *)(long)counters, 0, 1); perf_irq = save_perf_irq; } diff --git a/arch/mips/pci/fixup-au1000.c b/arch/mips/pci/fixup-au1000.c index 00c36c9dbe0e9ccd3ddc2429d22fe5e69701ed40..e2ddfc49237c5d9f54e6f3b87a5f3fc8ce75ed01 100644 --- a/arch/mips/pci/fixup-au1000.c +++ b/arch/mips/pci/fixup-au1000.c @@ -1,10 +1,9 @@ /* * BRIEF MODULE DESCRIPTION - * Board specific pci fixups. + * Board specific PCI fixups. * - * Copyright 2001-2003 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com + * Copyright 2001-2003, 2008 MontaVista Software Inc. + * Author: MontaVista Software, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the diff --git a/arch/mips/pci/ops-au1000.c b/arch/mips/pci/ops-au1000.c index 1314bd58f0365415a4553a8282d981e36ff54c73..9a57c5ab91dd515fdd83319f918e2ac7ce1922b5 100644 --- a/arch/mips/pci/ops-au1000.c +++ b/arch/mips/pci/ops-au1000.c @@ -1,10 +1,9 @@ /* * BRIEF MODULE DESCRIPTION - * Alchemy/AMD Au1x00 PCI support. + * Alchemy/AMD Au1xx0 PCI support. * - * Copyright 2001-2003, 2007 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com + * Copyright 2001-2003, 2007-2008 MontaVista Software Inc. + * Author: MontaVista Software, Inc. * * Support for all devices (greater than 16) added by David Gathright. * @@ -28,6 +27,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ + #include #include #include @@ -36,9 +36,9 @@ #include -#undef DEBUG -#ifdef DEBUG -#define DBG(x...) printk(x) +#undef DEBUG +#ifdef DEBUG +#define DBG(x...) printk(KERN_DEBUG x) #else #define DBG(x...) #endif @@ -46,7 +46,6 @@ #define PCI_ACCESS_READ 0 #define PCI_ACCESS_WRITE 1 - int (*board_pci_idsel)(unsigned int devsel, int assert); void mod_wired_entry(int entry, unsigned long entrylo0, @@ -92,10 +91,9 @@ void __init au1x_pci_cfg_init(void) } static int config_access(unsigned char access_type, struct pci_bus *bus, - unsigned int dev_fn, unsigned char where, - u32 * data) + unsigned int dev_fn, unsigned char where, u32 *data) { -#if defined( CONFIG_SOC_AU1500 ) || defined( CONFIG_SOC_AU1550 ) +#if defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550) unsigned int device = PCI_SLOT(dev_fn); unsigned int function = PCI_FUNC(dev_fn); unsigned long offset, status; @@ -114,38 +112,36 @@ static int config_access(unsigned char access_type, struct pci_bus *bus, Au1500_PCI_STATCMD); au_sync_udelay(1); - /* Allow board vendors to implement their own off-chip idsel. + /* + * Allow board vendors to implement their own off-chip IDSEL. * If it doesn't succeed, may as well bail out at this point. */ - if (board_pci_idsel) { - if (board_pci_idsel(device, 1) == 0) { - *data = 0xffffffff; - local_irq_restore(flags); - return -1; - } + if (board_pci_idsel && board_pci_idsel(device, 1) == 0) { + *data = 0xffffffff; + local_irq_restore(flags); + return -1; } - /* setup the config window */ - if (bus->number == 0) { - cfg_base = ((1<number<<16) | (device<<11); - } + /* Setup the config window */ + if (bus->number == 0) + cfg_base = (1 << device) << 11; + else + cfg_base = 0x80000000 | (bus->number << 16) | (device << 11); - /* setup the lower bits of the 36 bit address */ - offset = (function << 8) | (where & ~0x3); - /* pick up any address that falls below the page mask */ + /* Setup the lower bits of the 36-bit address */ + offset = (function << 8) | (where & ~0x3); + /* Pick up any address that falls below the page mask */ offset |= cfg_base & ~PAGE_MASK; - /* page boundary */ + /* Page boundary */ cfg_base = cfg_base & PAGE_MASK; /* * To improve performance, if the current device is the same as * the last device accessed, we don't touch the TLB. */ - entryLo0 = (6 << 26) | (cfg_base >> 6) | (2 << 3) | 7; - entryLo1 = (6 << 26) | (cfg_base >> 6) | (0x1000 >> 6) | (2 << 3) | 7; + entryLo0 = (6 << 26) | (cfg_base >> 6) | (2 << 3) | 7; + entryLo1 = (6 << 26) | (cfg_base >> 6) | (0x1000 >> 6) | (2 << 3) | 7; if ((entryLo0 != last_entryLo0) || (entryLo1 != last_entryLo1)) { mod_wired_entry(pci_cfg_wired_entry, entryLo0, entryLo1, (unsigned long)pci_cfg_vm->addr, PM_4K); @@ -153,38 +149,37 @@ static int config_access(unsigned char access_type, struct pci_bus *bus, last_entryLo1 = entryLo1; } - if (access_type == PCI_ACCESS_WRITE) { + if (access_type == PCI_ACCESS_WRITE) au_writel(*data, (int)(pci_cfg_vm->addr + offset)); - } else { + else *data = au_readl((int)(pci_cfg_vm->addr + offset)); - } + au_sync_udelay(2); - DBG("cfg_access %d bus->number %d dev %d at %x *data %x conf %x\n", - access_type, bus->number, device, where, *data, offset); + DBG("cfg_access %d bus->number %u dev %u at %x *data %x conf %lx\n", + access_type, bus->number, device, where, *data, offset); - /* check master abort */ + /* Check master abort */ status = au_readl(Au1500_PCI_STATCMD); - if (status & (1<<29)) { + if (status & (1 << 29)) { *data = 0xffffffff; error = -1; DBG("Au1x Master Abort\n"); } else if ((status >> 28) & 0xf) { - DBG("PCI ERR detected: device %d, status %x\n", device, ((status >> 28) & 0xf)); + DBG("PCI ERR detected: device %u, status %lx\n", + device, (status >> 28) & 0xf); - /* clear errors */ + /* Clear errors */ au_writel(status & 0xf000ffff, Au1500_PCI_STATCMD); *data = 0xffffffff; error = -1; } - /* Take away the idsel. - */ - if (board_pci_idsel) { + /* Take away the IDSEL. */ + if (board_pci_idsel) (void)board_pci_idsel(device, 0); - } local_irq_restore(flags); return error; @@ -192,7 +187,7 @@ static int config_access(unsigned char access_type, struct pci_bus *bus, } static int read_config_byte(struct pci_bus *bus, unsigned int devfn, - int where, u8 * val) + int where, u8 *val) { u32 data; int ret; @@ -206,9 +201,8 @@ static int read_config_byte(struct pci_bus *bus, unsigned int devfn, return ret; } - static int read_config_word(struct pci_bus *bus, unsigned int devfn, - int where, u16 * val) + int where, u16 *val) { u32 data; int ret; @@ -221,7 +215,7 @@ static int read_config_word(struct pci_bus *bus, unsigned int devfn, } static int read_config_dword(struct pci_bus *bus, unsigned int devfn, - int where, u32 * val) + int where, u32 *val) { int ret; @@ -229,9 +223,8 @@ static int read_config_dword(struct pci_bus *bus, unsigned int devfn, return ret; } -static int -write_config_byte(struct pci_bus *bus, unsigned int devfn, int where, - u8 val) +static int write_config_byte(struct pci_bus *bus, unsigned int devfn, + int where, u8 val) { u32 data = 0; @@ -239,7 +232,7 @@ write_config_byte(struct pci_bus *bus, unsigned int devfn, int where, return -1; data = (data & ~(0xff << ((where & 3) << 3))) | - (val << ((where & 3) << 3)); + (val << ((where & 3) << 3)); if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data)) return -1; @@ -247,9 +240,8 @@ write_config_byte(struct pci_bus *bus, unsigned int devfn, int where, return PCIBIOS_SUCCESSFUL; } -static int -write_config_word(struct pci_bus *bus, unsigned int devfn, int where, - u16 val) +static int write_config_word(struct pci_bus *bus, unsigned int devfn, + int where, u16 val) { u32 data = 0; @@ -257,18 +249,16 @@ write_config_word(struct pci_bus *bus, unsigned int devfn, int where, return -1; data = (data & ~(0xffff << ((where & 3) << 3))) | - (val << ((where & 3) << 3)); + (val << ((where & 3) << 3)); if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data)) return -1; - return PCIBIOS_SUCCESSFUL; } -static int -write_config_dword(struct pci_bus *bus, unsigned int devfn, int where, - u32 val) +static int write_config_dword(struct pci_bus *bus, unsigned int devfn, + int where, u32 val) { if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &val)) return -1; @@ -277,18 +267,20 @@ write_config_dword(struct pci_bus *bus, unsigned int devfn, int where, } static int config_read(struct pci_bus *bus, unsigned int devfn, - int where, int size, u32 * val) + int where, int size, u32 *val) { switch (size) { case 1: { u8 _val; int rc = read_config_byte(bus, devfn, where, &_val); + *val = _val; return rc; } - case 2: { + case 2: { u16 _val; int rc = read_config_word(bus, devfn, where, &_val); + *val = _val; return rc; } @@ -310,7 +302,6 @@ static int config_write(struct pci_bus *bus, unsigned int devfn, } } - struct pci_ops au1x_pci_ops = { config_read, config_write diff --git a/arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c b/arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c index ab96a2d7f4c4fc63c0c7594918342e0f98b4e489..11769b55438c27da2c113da9d21c39e21affa31e 100644 --- a/arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c +++ b/arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c @@ -126,9 +126,6 @@ static irqreturn_t hwbutton_handler(int irq, void *data) struct hwbutton_interrupt *hirq = data; unsigned long cic_ext = *CIC_EXT_CFG_REG; - if (irq != hirq->irq) - return IRQ_NONE; - if (CIC_EXT_IS_ACTIVE_HI(cic_ext, hirq->eirq)) { /* Interrupt: pin is now HI */ CIC_EXT_SET_ACTIVE_LO(cic_ext, hirq->eirq); @@ -164,7 +161,7 @@ static int msp_hwbutton_register(struct hwbutton_interrupt *hirq) *CIC_EXT_CFG_REG = cic_ext; return request_irq(hirq->irq, hwbutton_handler, IRQF_DISABLED, - hirq->name, (void *)hirq); + hirq->name, hirq); } static int __init msp_hwbutton_setup(void) diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c index 25d3baf0ebc4362a8c6cb02fa11468759c0f0b28..9cebc9e7da63ad4c926fbd142f39da54313d8594 100644 --- a/arch/mips/sgi-ip27/ip27-timer.c +++ b/arch/mips/sgi-ip27/ip27-timer.c @@ -158,7 +158,7 @@ static void rt_set_mode(enum clock_event_mode mode, } } -unsigned int rt_timer_irq; +int rt_timer_irq; static irqreturn_t hub_rt_counter_handler(int irq, void *dev_id) { @@ -219,7 +219,7 @@ static void __cpuinit hub_rt_clock_event_init(void) static void __init hub_rt_clock_event_global_init(void) { - unsigned int irq; + int irq; do { smp_wmb(); diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig index 6a6409adc56403c34ced10eee3d51c638c8314e2..e856218da90d36098e719602be9ffaa78c28f606 100644 --- a/arch/mn10300/Kconfig +++ b/arch/mn10300/Kconfig @@ -186,17 +186,6 @@ config PREEMPT Say Y here if you are building a kernel for a desktop, embedded or real-time system. Say N if you are unsure. -config PREEMPT_BKL - bool "Preempt The Big Kernel Lock" - depends on PREEMPT - default y - help - This option reduces the latency of the kernel by making the - big kernel lock preemptible. - - Say Y here if you are building a kernel for a desktop system. - Say N if you are unsure. - config MN10300_CURRENT_IN_E2 bool "Hold current task address in E2 register" default y diff --git a/arch/mn10300/boot/install.sh b/arch/mn10300/boot/install.sh index 072951c83976a22f41adf2098b5df95b8761ce2b..abba30971191bd900808b2e47bd356b6cbac713e 100644 --- a/arch/mn10300/boot/install.sh +++ b/arch/mn10300/boot/install.sh @@ -26,42 +26,42 @@ rm -fr $4/../usr/include/linux $4/../usr/include/asm install -c -m 0755 $2 $4/vmlinuz install -c -m 0755 $5 $4/boot.rom install -c -m 0755 -d $4/../usr/include/linux -cd $TOPDIR/include/linux +cd ${srctree}/include/linux for i in `find . -maxdepth 1 -name '*.h' -print`; do install -c -m 0644 $i $4/../usr/include/linux done install -c -m 0755 -d $4/../usr/include/linux/byteorder -cd $TOPDIR/include/linux/byteorder +cd ${srctree}/include/linux/byteorder for i in `find . -name '*.h' -print`; do install -c -m 0644 $i $4/../usr/include/linux/byteorder done install -c -m 0755 -d $4/../usr/include/linux/lockd -cd $TOPDIR/include/linux/lockd +cd ${srctree}/include/linux/lockd for i in `find . -name '*.h' -print`; do install -c -m 0644 $i $4/../usr/include/linux/lockd done install -c -m 0755 -d $4/../usr/include/linux/netfilter_ipv4 -cd $TOPDIR/include/linux/netfilter_ipv4 +cd ${srctree}/include/linux/netfilter_ipv4 for i in `find . -name '*.h' -print`; do install -c -m 0644 $i $4/../usr/include/linux/netfilter_ipv4 done install -c -m 0755 -d $4/../usr/include/linux/nfsd -cd $TOPDIR/include/linux/nfsd +cd ${srctree}/include/linux/nfsd for i in `find . -name '*.h' -print`; do install -c -m 0644 $i $4/../usr/include/linux/nfsd/$i done install -c -m 0755 -d $4/../usr/include/linux/raid -cd $TOPDIR/include/linux/raid +cd ${srctree}/include/linux/raid for i in `find . -name '*.h' -print`; do install -c -m 0644 $i $4/../usr/include/linux/raid done install -c -m 0755 -d $4/../usr/include/linux/sunrpc -cd $TOPDIR/include/linux/sunrpc +cd ${srctree}/include/linux/sunrpc for i in `find . -name '*.h' -print`; do install -c -m 0644 $i $4/../usr/include/linux/sunrpc done install -c -m 0755 -d $4/../usr/include/asm -cd $TOPDIR/include/asm +cd ${srctree}/include/asm for i in `find . -name '*.h' -print`; do install -c -m 0644 $i $4/../usr/include/asm done diff --git a/arch/mn10300/kernel/init_task.c b/arch/mn10300/kernel/init_task.c index 39fe6882dd1ddd67e68a4a92f6f6b8ec1e9fbaa6..af16f6e5c918870d9545419bcba180fcfe1f9e8f 100644 --- a/arch/mn10300/kernel/init_task.c +++ b/arch/mn10300/kernel/init_task.c @@ -19,7 +19,6 @@ #include static struct fs_struct init_fs = INIT_FS; -static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS(init_signals); static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); struct mm_struct init_mm = INIT_MM(init_mm); diff --git a/arch/parisc/hpux/gate.S b/arch/parisc/hpux/gate.S index 38a1c1b8d4e8e11093b3a35db9d95ca98749ed1a..f0b18ce89842937b0b134fa5a8957e01d5369cba 100644 --- a/arch/parisc/hpux/gate.S +++ b/arch/parisc/hpux/gate.S @@ -13,9 +13,10 @@ #include #include #include +#include .level LEVEL - .text + __HEAD .import hpux_call_table .import hpux_syscall_exit,code diff --git a/arch/parisc/hpux/wrappers.S b/arch/parisc/hpux/wrappers.S index 58c53c879c02773d427eb699af11b20e244b198c..ccd3a50c0995edec74134b56a705ad1f85902b2d 100644 --- a/arch/parisc/hpux/wrappers.S +++ b/arch/parisc/hpux/wrappers.S @@ -28,9 +28,10 @@ #include #include #include +#include .level LEVEL - .text + __HEAD /* These should probably go in a header file somewhere. * They are duplicated in kernel/wrappers.S diff --git a/arch/parisc/kernel/Makefile b/arch/parisc/kernel/Makefile index 1f6585a56f972775eee9f366443ca4249f1599f3..016d3fc4111c6bf3d22872dd23737cc880c15eb4 100644 --- a/arch/parisc/kernel/Makefile +++ b/arch/parisc/kernel/Makefile @@ -4,9 +4,6 @@ extra-y := init_task.o head.o vmlinux.lds -AFLAGS_entry.o := -traditional -AFLAGS_pacache.o := -traditional - obj-y := cache.o pacache.o setup.o traps.o time.o irq.o \ pa7300lc.o syscall.o entry.o sys_parisc.o firmware.o \ ptrace.o hardware.o inventory.o drivers.o \ diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index 111d47284eacc8c492a2ce55d8f7f006005daa8b..5d0837458c19b5ede71f9427935c9b070011ac52 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -38,18 +38,11 @@ #include #include +#include #ifdef CONFIG_64BIT -#define CMPIB cmpib,* -#define CMPB cmpb,* -#define COND(x) *x - .level 2.0w #else -#define CMPIB cmpib, -#define CMPB cmpb, -#define COND(x) x - .level 2.0 #endif @@ -629,7 +622,7 @@ * the static part of the kernel address space. */ - .text + __HEAD .align PAGE_SIZE @@ -957,9 +950,9 @@ intr_check_sig: * Only do signals if we are returning to user space */ LDREG PT_IASQ0(%r16), %r20 - CMPIB=,n 0,%r20,intr_restore /* backward */ + cmpib,COND(=),n 0,%r20,intr_restore /* backward */ LDREG PT_IASQ1(%r16), %r20 - CMPIB=,n 0,%r20,intr_restore /* backward */ + cmpib,COND(=),n 0,%r20,intr_restore /* backward */ copy %r0, %r25 /* long in_syscall = 0 */ #ifdef CONFIG_64BIT @@ -1013,10 +1006,10 @@ intr_do_resched: * we jump back to intr_restore. */ LDREG PT_IASQ0(%r16), %r20 - CMPIB= 0, %r20, intr_do_preempt + cmpib,COND(=) 0, %r20, intr_do_preempt nop LDREG PT_IASQ1(%r16), %r20 - CMPIB= 0, %r20, intr_do_preempt + cmpib,COND(=) 0, %r20, intr_do_preempt nop #ifdef CONFIG_64BIT @@ -1045,7 +1038,7 @@ intr_do_preempt: /* current_thread_info()->preempt_count */ mfctl %cr30, %r1 LDREG TI_PRE_COUNT(%r1), %r19 - CMPIB<> 0, %r19, intr_restore /* if preempt_count > 0 */ + cmpib,COND(<>) 0, %r19, intr_restore /* if preempt_count > 0 */ nop /* prev insn branched backwards */ /* check if we interrupted a critical path */ @@ -1064,7 +1057,7 @@ intr_do_preempt: */ intr_extint: - CMPIB=,n 0,%r16,1f + cmpib,COND(=),n 0,%r16,1f get_stack_use_cr30 b,n 2f @@ -1099,7 +1092,7 @@ ENDPROC(syscall_exit_rfi) ENTRY(intr_save) /* for os_hpmc */ mfsp %sr7,%r16 - CMPIB=,n 0,%r16,1f + cmpib,COND(=),n 0,%r16,1f get_stack_use_cr30 b 2f copy %r8,%r26 @@ -1121,7 +1114,7 @@ ENTRY(intr_save) /* for os_hpmc */ * adjust isr/ior below. */ - CMPIB=,n 6,%r26,skip_save_ior + cmpib,COND(=),n 6,%r26,skip_save_ior mfctl %cr20, %r16 /* isr */ @@ -1450,11 +1443,11 @@ nadtlb_emulate: bb,>=,n %r9,26,nadtlb_nullify /* m bit not set, just nullify */ BL get_register,%r25 extrw,u %r9,15,5,%r8 /* Get index register # */ - CMPIB=,n -1,%r1,nadtlb_fault /* have to use slow path */ + cmpib,COND(=),n -1,%r1,nadtlb_fault /* have to use slow path */ copy %r1,%r24 BL get_register,%r25 extrw,u %r9,10,5,%r8 /* Get base register # */ - CMPIB=,n -1,%r1,nadtlb_fault /* have to use slow path */ + cmpib,COND(=),n -1,%r1,nadtlb_fault /* have to use slow path */ BL set_register,%r25 add,l %r1,%r24,%r1 /* doesn't affect c/b bits */ @@ -1486,7 +1479,7 @@ nadtlb_probe_check: cmpb,<>,n %r16,%r17,nadtlb_fault /* Must be probe,[rw]*/ BL get_register,%r25 /* Find the target register */ extrw,u %r9,31,5,%r8 /* Get target register */ - CMPIB=,n -1,%r1,nadtlb_fault /* have to use slow path */ + cmpib,COND(=),n -1,%r1,nadtlb_fault /* have to use slow path */ BL set_register,%r25 copy %r0,%r1 /* Write zero to target register */ b nadtlb_nullify /* Nullify return insn */ @@ -1570,12 +1563,12 @@ dbit_trap_20w: L3_ptep ptp,pte,t0,va,dbit_fault #ifdef CONFIG_SMP - CMPIB=,n 0,spc,dbit_nolock_20w + cmpib,COND(=),n 0,spc,dbit_nolock_20w load32 PA(pa_dbit_lock),t0 dbit_spin_20w: LDCW 0(t0),t1 - cmpib,= 0,t1,dbit_spin_20w + cmpib,COND(=) 0,t1,dbit_spin_20w nop dbit_nolock_20w: @@ -1586,7 +1579,7 @@ dbit_nolock_20w: idtlbt pte,prot #ifdef CONFIG_SMP - CMPIB=,n 0,spc,dbit_nounlock_20w + cmpib,COND(=),n 0,spc,dbit_nounlock_20w ldi 1,t1 stw t1,0(t0) @@ -1606,7 +1599,7 @@ dbit_trap_11: L2_ptep ptp,pte,t0,va,dbit_fault #ifdef CONFIG_SMP - CMPIB=,n 0,spc,dbit_nolock_11 + cmpib,COND(=),n 0,spc,dbit_nolock_11 load32 PA(pa_dbit_lock),t0 dbit_spin_11: @@ -1628,7 +1621,7 @@ dbit_nolock_11: mtsp t1, %sr1 /* Restore sr1 */ #ifdef CONFIG_SMP - CMPIB=,n 0,spc,dbit_nounlock_11 + cmpib,COND(=),n 0,spc,dbit_nounlock_11 ldi 1,t1 stw t1,0(t0) @@ -1646,7 +1639,7 @@ dbit_trap_20: L2_ptep ptp,pte,t0,va,dbit_fault #ifdef CONFIG_SMP - CMPIB=,n 0,spc,dbit_nolock_20 + cmpib,COND(=),n 0,spc,dbit_nolock_20 load32 PA(pa_dbit_lock),t0 dbit_spin_20: @@ -1665,7 +1658,7 @@ dbit_nolock_20: idtlbt pte,prot #ifdef CONFIG_SMP - CMPIB=,n 0,spc,dbit_nounlock_20 + cmpib,COND(=),n 0,spc,dbit_nounlock_20 ldi 1,t1 stw t1,0(t0) @@ -1994,7 +1987,7 @@ ENTRY(syscall_exit) /* We can't use "CMPIB<> PER_HPUX" since "im5" field is sign extended */ ldo -PER_HPUX(%r19), %r19 - CMPIB<>,n 0,%r19,1f + cmpib,COND(<>),n 0,%r19,1f /* Save other hpux returns if personality is PER_HPUX */ STREG %r22,TASK_PT_GR22(%r1) diff --git a/arch/parisc/kernel/head.S b/arch/parisc/kernel/head.S index ec2482dc1beb39f4a62a7e17c28b7238d8291709..5680a2c3b13d6d69446c0f468e40323ced0e423c 100644 --- a/arch/parisc/kernel/head.S +++ b/arch/parisc/kernel/head.S @@ -32,7 +32,7 @@ ENTRY(boot_args) .word 0 /* arg3 */ END(boot_args) - .section .text.head + __HEAD .align 4 .import init_thread_union,data .import fault_vector_20,code /* IVA parisc 2.0 32 bit */ diff --git a/arch/parisc/kernel/hpmc.S b/arch/parisc/kernel/hpmc.S index 2cbf13b3ef11d0a1ff62f7eb5cec9b1c96333371..068322eb8c9bf3f49ad51ea7a36c9f75aff17e8c 100644 --- a/arch/parisc/kernel/hpmc.S +++ b/arch/parisc/kernel/hpmc.S @@ -47,6 +47,7 @@ #include #include +#include /* * stack for os_hpmc, the HPMC handler. @@ -76,7 +77,7 @@ ENTRY(hpmc_pim_data) .block HPMC_PIM_DATA_SIZE END(hpmc_pim_data) - .text + __HEAD .import intr_save, code ENTRY(os_hpmc) diff --git a/arch/parisc/kernel/init_task.c b/arch/parisc/kernel/init_task.c index 26198a074d672fa724c9b21299e7a63bb53a953f..f5941c086551e09c2578821988037dd3628db712 100644 --- a/arch/parisc/kernel/init_task.c +++ b/arch/parisc/kernel/init_task.c @@ -35,7 +35,6 @@ #include static struct fs_struct init_fs = INIT_FS; -static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS(init_signals); static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); struct mm_struct init_mm = INIT_MM(init_mm); diff --git a/arch/parisc/kernel/inventory.c b/arch/parisc/kernel/inventory.c index 4845a64446330d6a1e5e793a31c4c565df21a7b1..bd1f7f1ff74e7b6589c4a97f6fcebd28453a1d19 100644 --- a/arch/parisc/kernel/inventory.c +++ b/arch/parisc/kernel/inventory.c @@ -499,7 +499,7 @@ add_system_map_addresses(struct parisc_device *dev, int num_addrs, dev->addr = kmalloc(num_addrs * sizeof(unsigned long), GFP_KERNEL); if(!dev->addr) { printk(KERN_ERR "%s %s(): memory allocation failure\n", - __FILE__, __FUNCTION__); + __FILE__, __func__); return; } diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S index 5901092e0196b855e64845f0c483fedb774a62d4..e3246a5ca74f01dd25fa847b1c801fea938fdfdc 100644 --- a/arch/parisc/kernel/pacache.S +++ b/arch/parisc/kernel/pacache.S @@ -37,8 +37,9 @@ #include #include #include +#include - .text + __HEAD .align 128 ENTRY(flush_tlb_all_local) @@ -85,7 +86,7 @@ ENTRY(flush_tlb_all_local) LDREG ITLB_OFF_COUNT(%r1), %arg2 LDREG ITLB_LOOP(%r1), %arg3 - ADDIB= -1, %arg3, fitoneloop /* Preadjust and test */ + addib,COND(=) -1, %arg3, fitoneloop /* Preadjust and test */ movb,<,n %arg3, %r31, fitdone /* If loop < 0, skip */ copy %arg0, %r28 /* Init base addr */ @@ -95,14 +96,14 @@ fitmanyloop: /* Loop if LOOP >= 2 */ copy %arg2, %r29 /* Init middle loop count */ fitmanymiddle: /* Loop if LOOP >= 2 */ - ADDIB> -1, %r31, fitmanymiddle /* Adjusted inner loop decr */ + addib,COND(>) -1, %r31, fitmanymiddle /* Adjusted inner loop decr */ pitlbe 0(%sr1, %r28) pitlbe,m %arg1(%sr1, %r28) /* Last pitlbe and addr adjust */ - ADDIB> -1, %r29, fitmanymiddle /* Middle loop decr */ + addib,COND(>) -1, %r29, fitmanymiddle /* Middle loop decr */ copy %arg3, %r31 /* Re-init inner loop count */ movb,tr %arg0, %r28, fitmanyloop /* Re-init base addr */ - ADDIB<=,n -1, %r22, fitdone /* Outer loop count decr */ + addib,COND(<=),n -1, %r22, fitdone /* Outer loop count decr */ fitoneloop: /* Loop if LOOP = 1 */ mtsp %r20, %sr1 @@ -110,10 +111,10 @@ fitoneloop: /* Loop if LOOP = 1 */ copy %arg2, %r29 /* init middle loop count */ fitonemiddle: /* Loop if LOOP = 1 */ - ADDIB> -1, %r29, fitonemiddle /* Middle loop count decr */ + addib,COND(>) -1, %r29, fitonemiddle /* Middle loop count decr */ pitlbe,m %arg1(%sr1, %r28) /* pitlbe for one loop */ - ADDIB> -1, %r22, fitoneloop /* Outer loop count decr */ + addib,COND(>) -1, %r22, fitoneloop /* Outer loop count decr */ add %r21, %r20, %r20 /* increment space */ fitdone: @@ -128,7 +129,7 @@ fitdone: LDREG DTLB_OFF_COUNT(%r1), %arg2 LDREG DTLB_LOOP(%r1), %arg3 - ADDIB= -1, %arg3, fdtoneloop /* Preadjust and test */ + addib,COND(=) -1, %arg3, fdtoneloop /* Preadjust and test */ movb,<,n %arg3, %r31, fdtdone /* If loop < 0, skip */ copy %arg0, %r28 /* Init base addr */ @@ -138,14 +139,14 @@ fdtmanyloop: /* Loop if LOOP >= 2 */ copy %arg2, %r29 /* Init middle loop count */ fdtmanymiddle: /* Loop if LOOP >= 2 */ - ADDIB> -1, %r31, fdtmanymiddle /* Adjusted inner loop decr */ + addib,COND(>) -1, %r31, fdtmanymiddle /* Adjusted inner loop decr */ pdtlbe 0(%sr1, %r28) pdtlbe,m %arg1(%sr1, %r28) /* Last pdtlbe and addr adjust */ - ADDIB> -1, %r29, fdtmanymiddle /* Middle loop decr */ + addib,COND(>) -1, %r29, fdtmanymiddle /* Middle loop decr */ copy %arg3, %r31 /* Re-init inner loop count */ movb,tr %arg0, %r28, fdtmanyloop /* Re-init base addr */ - ADDIB<=,n -1, %r22,fdtdone /* Outer loop count decr */ + addib,COND(<=),n -1, %r22,fdtdone /* Outer loop count decr */ fdtoneloop: /* Loop if LOOP = 1 */ mtsp %r20, %sr1 @@ -153,10 +154,10 @@ fdtoneloop: /* Loop if LOOP = 1 */ copy %arg2, %r29 /* init middle loop count */ fdtonemiddle: /* Loop if LOOP = 1 */ - ADDIB> -1, %r29, fdtonemiddle /* Middle loop count decr */ + addib,COND(>) -1, %r29, fdtonemiddle /* Middle loop count decr */ pdtlbe,m %arg1(%sr1, %r28) /* pdtlbe for one loop */ - ADDIB> -1, %r22, fdtoneloop /* Outer loop count decr */ + addib,COND(>) -1, %r22, fdtoneloop /* Outer loop count decr */ add %r21, %r20, %r20 /* increment space */ @@ -209,18 +210,18 @@ ENTRY(flush_instruction_cache_local) LDREG ICACHE_COUNT(%r1), %arg2 LDREG ICACHE_LOOP(%r1), %arg3 rsm PSW_SM_I, %r22 /* No mmgt ops during loop*/ - ADDIB= -1, %arg3, fioneloop /* Preadjust and test */ + addib,COND(=) -1, %arg3, fioneloop /* Preadjust and test */ movb,<,n %arg3, %r31, fisync /* If loop < 0, do sync */ fimanyloop: /* Loop if LOOP >= 2 */ - ADDIB> -1, %r31, fimanyloop /* Adjusted inner loop decr */ + addib,COND(>) -1, %r31, fimanyloop /* Adjusted inner loop decr */ fice %r0(%sr1, %arg0) fice,m %arg1(%sr1, %arg0) /* Last fice and addr adjust */ movb,tr %arg3, %r31, fimanyloop /* Re-init inner loop count */ - ADDIB<=,n -1, %arg2, fisync /* Outer loop decr */ + addib,COND(<=),n -1, %arg2, fisync /* Outer loop decr */ fioneloop: /* Loop if LOOP = 1 */ - ADDIB> -1, %arg2, fioneloop /* Outer loop count decr */ + addib,COND(>) -1, %arg2, fioneloop /* Outer loop count decr */ fice,m %arg1(%sr1, %arg0) /* Fice for one loop */ fisync: @@ -250,18 +251,18 @@ ENTRY(flush_data_cache_local) LDREG DCACHE_COUNT(%r1), %arg2 LDREG DCACHE_LOOP(%r1), %arg3 rsm PSW_SM_I, %r22 - ADDIB= -1, %arg3, fdoneloop /* Preadjust and test */ + addib,COND(=) -1, %arg3, fdoneloop /* Preadjust and test */ movb,<,n %arg3, %r31, fdsync /* If loop < 0, do sync */ fdmanyloop: /* Loop if LOOP >= 2 */ - ADDIB> -1, %r31, fdmanyloop /* Adjusted inner loop decr */ + addib,COND(>) -1, %r31, fdmanyloop /* Adjusted inner loop decr */ fdce %r0(%sr1, %arg0) fdce,m %arg1(%sr1, %arg0) /* Last fdce and addr adjust */ movb,tr %arg3, %r31, fdmanyloop /* Re-init inner loop count */ - ADDIB<=,n -1, %arg2, fdsync /* Outer loop decr */ + addib,COND(<=),n -1, %arg2, fdsync /* Outer loop decr */ fdoneloop: /* Loop if LOOP = 1 */ - ADDIB> -1, %arg2, fdoneloop /* Outer loop count decr */ + addib,COND(>) -1, %arg2, fdoneloop /* Outer loop count decr */ fdce,m %arg1(%sr1, %arg0) /* Fdce for one loop */ fdsync: @@ -342,7 +343,7 @@ ENTRY(copy_user_page_asm) * non-taken backward branch. Note that .+4 is a backwards branch. * The ldd should only get executed if the branch is taken. */ - ADDIB>,n -1, %r1, 1b /* bundle 10 */ + addib,COND(>),n -1, %r1, 1b /* bundle 10 */ ldd 0(%r25), %r19 /* start next loads */ #else @@ -391,7 +392,7 @@ ENTRY(copy_user_page_asm) stw %r21, 56(%r26) stw %r22, 60(%r26) ldo 64(%r26), %r26 - ADDIB>,n -1, %r1, 1b + addib,COND(>),n -1, %r1, 1b ldw 0(%r25), %r19 #endif bv %r0(%r2) @@ -515,7 +516,7 @@ ENTRY(copy_user_page_asm) stw %r21, 56(%r28) stw %r22, 60(%r28) ldo 64(%r28), %r28 - ADDIB> -1, %r1,1b + addib,COND(>) -1, %r1,1b ldo 64(%r29), %r29 bv %r0(%r2) @@ -574,7 +575,7 @@ ENTRY(__clear_user_page_asm) std %r0, 104(%r28) std %r0, 112(%r28) std %r0, 120(%r28) - ADDIB> -1, %r1, 1b + addib,COND(>) -1, %r1, 1b ldo 128(%r28), %r28 #else /* ! CONFIG_64BIT */ @@ -597,7 +598,7 @@ ENTRY(__clear_user_page_asm) stw %r0, 52(%r28) stw %r0, 56(%r28) stw %r0, 60(%r28) - ADDIB> -1, %r1, 1b + addib,COND(>) -1, %r1, 1b ldo 64(%r28), %r28 #endif /* CONFIG_64BIT */ @@ -640,7 +641,7 @@ ENTRY(flush_kernel_dcache_page_asm) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) - CMPB<< %r26, %r25,1b + cmpb,COND(<<) %r26, %r25,1b fdc,m %r23(%r26) sync @@ -683,7 +684,7 @@ ENTRY(flush_user_dcache_page) fdc,m %r23(%sr3, %r26) fdc,m %r23(%sr3, %r26) fdc,m %r23(%sr3, %r26) - CMPB<< %r26, %r25,1b + cmpb,COND(<<) %r26, %r25,1b fdc,m %r23(%sr3, %r26) sync @@ -726,7 +727,7 @@ ENTRY(flush_user_icache_page) fic,m %r23(%sr3, %r26) fic,m %r23(%sr3, %r26) fic,m %r23(%sr3, %r26) - CMPB<< %r26, %r25,1b + cmpb,COND(<<) %r26, %r25,1b fic,m %r23(%sr3, %r26) sync @@ -769,7 +770,7 @@ ENTRY(purge_kernel_dcache_page) pdc,m %r23(%r26) pdc,m %r23(%r26) pdc,m %r23(%r26) - CMPB<< %r26, %r25, 1b + cmpb,COND(<<) %r26, %r25, 1b pdc,m %r23(%r26) sync @@ -833,7 +834,7 @@ ENTRY(flush_alias_page) fdc,m %r23(%r28) fdc,m %r23(%r28) fdc,m %r23(%r28) - CMPB<< %r28, %r29, 1b + cmpb,COND(<<) %r28, %r29, 1b fdc,m %r23(%r28) sync @@ -856,7 +857,7 @@ flush_user_dcache_range_asm: ldo -1(%r23), %r21 ANDCM %r26, %r21, %r26 -1: CMPB<<,n %r26, %r25, 1b +1: cmpb,COND(<<),n %r26, %r25, 1b fdc,m %r23(%sr3, %r26) sync @@ -877,7 +878,7 @@ ENTRY(flush_kernel_dcache_range_asm) ldo -1(%r23), %r21 ANDCM %r26, %r21, %r26 -1: CMPB<<,n %r26, %r25,1b +1: cmpb,COND(<<),n %r26, %r25,1b fdc,m %r23(%r26) sync @@ -899,7 +900,7 @@ ENTRY(flush_user_icache_range_asm) ldo -1(%r23), %r21 ANDCM %r26, %r21, %r26 -1: CMPB<<,n %r26, %r25,1b +1: cmpb,COND(<<),n %r26, %r25,1b fic,m %r23(%sr3, %r26) sync @@ -942,7 +943,7 @@ ENTRY(flush_kernel_icache_page) fic,m %r23(%sr4, %r26) fic,m %r23(%sr4, %r26) fic,m %r23(%sr4, %r26) - CMPB<< %r26, %r25, 1b + cmpb,COND(<<) %r26, %r25, 1b fic,m %r23(%sr4, %r26) sync @@ -963,7 +964,7 @@ ENTRY(flush_kernel_icache_range_asm) ldo -1(%r23), %r21 ANDCM %r26, %r21, %r26 -1: CMPB<<,n %r26, %r25, 1b +1: cmpb,COND(<<),n %r26, %r25, 1b fic,m %r23(%sr4, %r26) sync diff --git a/arch/parisc/kernel/perf_asm.S b/arch/parisc/kernel/perf_asm.S index 43874ca3ed67178505597cbe707630ffc3dfa2ba..d411dfb5b6d147dc02b32911d4db9014811a1350 100644 --- a/arch/parisc/kernel/perf_asm.S +++ b/arch/parisc/kernel/perf_asm.S @@ -20,6 +20,8 @@ */ #include + +#include #include #ifdef CONFIG_64BIT @@ -41,7 +43,7 @@ ; The coprocessor only needs to be enabled when ; starting/stopping the coprocessor with the pmenb/pmdis. ; - .text + __HEAD ENTRY(perf_intrigue_enable_perf_counters) .proc diff --git a/arch/parisc/kernel/real2.S b/arch/parisc/kernel/real2.S index 7a92695d95a6bf814a72803da7d02403953eacd4..47fbdae6efd5c54a4a49ae0ae799118c711250b4 100644 --- a/arch/parisc/kernel/real2.S +++ b/arch/parisc/kernel/real2.S @@ -12,6 +12,7 @@ #include #include +#include .section .bss .export real_stack @@ -39,7 +40,7 @@ save_cr_end: /************************ 32-bit real-mode calls ***********************/ /* This can be called in both narrow and wide kernels */ - .text + __HEAD /* unsigned long real32_call_asm(unsigned int *sp, * unsigned int *arg0p, @@ -113,7 +114,7 @@ ENDPROC(real32_call_asm) # define PUSH_CR(r, where) mfctl r, %r1 ! STREG,ma %r1, REG_SZ(where) # define POP_CR(r, where) LDREG,mb -REG_SZ(where), %r1 ! mtctl %r1, r - .text + __HEAD save_control_regs: load32 PA(save_cr_space), %r28 PUSH_CR(%cr24, %r28) @@ -145,7 +146,7 @@ restore_control_regs: /* rfi_virt2real() and rfi_real2virt() could perhaps be adapted for * more general-purpose use by the several places which need RFIs */ - .text + __HEAD .align 128 rfi_virt2real: /* switch to real mode... */ @@ -180,7 +181,7 @@ rfi_v2r_1: bv 0(%r2) nop - .text + __HEAD .align 128 rfi_real2virt: rsm PSW_SM_I,%r0 @@ -218,7 +219,7 @@ rfi_r2v_1: /************************ 64-bit real-mode calls ***********************/ /* This is only usable in wide kernels right now and will probably stay so */ - .text + __HEAD /* unsigned long real64_call_asm(unsigned long *sp, * unsigned long *arg0p, * unsigned long fn) @@ -276,7 +277,7 @@ ENDPROC(real64_call_asm) #endif - .text + __HEAD /* http://lists.parisc-linux.org/hypermail/parisc-linux/10916.html ** GCC 3.3 and later has a new function in libgcc.a for ** comparing function pointers. diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S index 69b6eebc466ea4860261d6ff9c503bae308a748c..ae509d8cd03f24867401851975f15b2eef611300 100644 --- a/arch/parisc/kernel/syscall.S +++ b/arch/parisc/kernel/syscall.S @@ -17,6 +17,7 @@ #include #include +#include /* We fill the empty parts of the gateway page with * something that will kill the kernel or a @@ -26,7 +27,7 @@ .level LEVEL - .text + __HEAD .import syscall_exit,code .import syscall_exit_rfi,code @@ -636,7 +637,7 @@ END(sys_call_table64) All light-weight-syscall atomic operations will use this set of locks */ - .section .data + .section .data, "aw" .align PAGE_SIZE ENTRY(lws_lock_start) /* lws locks */ diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c index 9dc6dc42f9cfb151e5d827338c9e27431e40c58d..675f1d098f05d2f6ec29ab8c5be3d55005627a03 100644 --- a/arch/parisc/kernel/traps.c +++ b/arch/parisc/kernel/traps.c @@ -275,7 +275,7 @@ KERN_CRIT " || ||\n"); /* Wot's wrong wif bein' racy? */ if (current->thread.flags & PARISC_KERNEL_DEATH) { - printk(KERN_CRIT "%s() recursion detected.\n", __FUNCTION__); + printk(KERN_CRIT "%s() recursion detected.\n", __func__); local_irq_enable(); while (1); } diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c index aebf3c1688719b0b6ce735f258c3eb068a68b845..e6f4b7a4b7e321eaefbd03dc5b2766f55f73d887 100644 --- a/arch/parisc/kernel/unaligned.c +++ b/arch/parisc/kernel/unaligned.c @@ -30,7 +30,7 @@ /* #define DEBUG_UNALIGNED 1 */ #ifdef DEBUG_UNALIGNED -#define DPRINTF(fmt, args...) do { printk(KERN_DEBUG "%s:%d:%s ", __FILE__, __LINE__, __FUNCTION__ ); printk(KERN_DEBUG fmt, ##args ); } while (0) +#define DPRINTF(fmt, args...) do { printk(KERN_DEBUG "%s:%d:%s ", __FILE__, __LINE__, __func__ ); printk(KERN_DEBUG fmt, ##args ); } while (0) #else #define DPRINTF(fmt, args...) #endif @@ -460,7 +460,8 @@ void handle_unaligned(struct pt_regs *regs) goto force_sigbus; } - if (unaligned_count > 5 && jiffies - last_time > 5*HZ) { + if (unaligned_count > 5 && + time_after(jiffies, last_time + 5 * HZ)) { unaligned_count = 0; last_time = jiffies; } diff --git a/arch/parisc/lib/fixup.S b/arch/parisc/lib/fixup.S index d172d4245cdcfc54eabdb3758eb4ad487e8b8cf7..4821ad6d5269ea0f62dcbddc984e9adf59f736ac 100644 --- a/arch/parisc/lib/fixup.S +++ b/arch/parisc/lib/fixup.S @@ -23,6 +23,7 @@ #include #include #include +#include #ifdef CONFIG_SMP .macro get_fault_ip t1 t2 @@ -55,7 +56,7 @@ .level LEVEL - .text + __HEAD .section .fixup, "ax" /* get_user() fixups, store -EFAULT in r8, and 0 in r9 */ diff --git a/arch/parisc/lib/lusercopy.S b/arch/parisc/lib/lusercopy.S index 1bd23ccec17b9a53fb838fdfdf5eb9ab62ccf739..b0d88535084613bb58d61f56698220d6ab5ea595 100644 --- a/arch/parisc/lib/lusercopy.S +++ b/arch/parisc/lib/lusercopy.S @@ -33,11 +33,12 @@ */ - .text - #include #include #include +#include + + __HEAD /* * get_sr gets the appropriate space value into diff --git a/arch/parisc/lib/memcpy.c b/arch/parisc/lib/memcpy.c index d22042d33100b80c34d1c26b17b8fd25fcc350d1..2d68431fc22e98a818dd3ecaca049c93c9196d5e 100644 --- a/arch/parisc/lib/memcpy.c +++ b/arch/parisc/lib/memcpy.c @@ -91,7 +91,7 @@ DECLARE_PER_CPU(struct exception_data, exception_data); #define THRESHOLD 16 #ifdef DEBUG_MEMCPY -#define DPRINTF(fmt, args...) do { printk(KERN_DEBUG "%s:%d:%s ", __FILE__, __LINE__, __FUNCTION__ ); printk(KERN_DEBUG fmt, ##args ); } while (0) +#define DPRINTF(fmt, args...) do { printk(KERN_DEBUG "%s:%d:%s ", __FILE__, __LINE__, __func__ ); printk(KERN_DEBUG fmt, ##args ); } while (0) #else #define DPRINTF(fmt, args...) #endif diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c index 1f012843150fbd83b801c11b8a6a58ddcaa099b5..78fe252b92c3c5e1dfc1eb00807d5de1d32eba6e 100644 --- a/arch/parisc/mm/init.c +++ b/arch/parisc/mm/init.c @@ -555,8 +555,6 @@ void show_mem(void) printk(KERN_INFO "Mem-info:\n"); show_free_areas(); - printk(KERN_INFO "Free swap: %6ldkB\n", - nr_swap_pages<<(PAGE_SHIFT-10)); #ifndef CONFIG_DISCONTIGMEM i = max_mapnr; while (i-- > 0) { @@ -606,7 +604,7 @@ void show_mem(void) int i, j; for (i = 0; i < npmem_ranges; i++) { - zl = node_zonelist(i); + zl = node_zonelist(i, 0); for (j = 0; j < MAX_NR_ZONES; j++) { struct zoneref *z; struct zone *zone; diff --git a/arch/powerpc/boot/4xx.c b/arch/powerpc/boot/4xx.c index 758edf1c58156e1b44e25fa6deb931d86aa274fc..5c878436f3485a9dfbd606120fe66642ed26f74c 100644 --- a/arch/powerpc/boot/4xx.c +++ b/arch/powerpc/boot/4xx.c @@ -21,6 +21,25 @@ #include "reg.h" #include "dcr.h" +static unsigned long chip_11_errata(unsigned long memsize) +{ + unsigned long pvr; + + pvr = mfpvr(); + + switch (pvr & 0xf0000ff0) { + case 0x40000850: + case 0x400008d0: + case 0x200008d0: + memsize -= 4096; + break; + default: + break; + } + + return memsize; +} + /* Read the 4xx SDRAM controller to get size of system memory. */ void ibm4xx_sdram_fixup_memsize(void) { @@ -34,6 +53,7 @@ void ibm4xx_sdram_fixup_memsize(void) memsize += SDRAM_CONFIG_BANK_SIZE(bank_config); } + memsize = chip_11_errata(memsize); dt_fixup_memory(0, memsize); } @@ -199,6 +219,7 @@ void ibm4xx_denali_fixup_memsize(void) bank = 4; /* 4 banks */ memsize = cs * (1 << (col+row)) * bank * dpath; + memsize = chip_11_errata(memsize); dt_fixup_memory(0, memsize); } diff --git a/arch/powerpc/boot/dts/mpc8377_mds.dts b/arch/powerpc/boot/dts/mpc8377_mds.dts index eac8e1b594965dd7e997ac27791faf4dcf06f52e..1e7802cc31ae30207b4b7dd9bc8e546d57218078 100644 --- a/arch/powerpc/boot/dts/mpc8377_mds.dts +++ b/arch/powerpc/boot/dts/mpc8377_mds.dts @@ -268,6 +268,33 @@ interrupt-parent = <&ipic>; }; + dma@82a8 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "fsl,mpc8349-dma"; + reg = <0x82a8 4>; + ranges = <0 0x8100 0x1a8>; + interrupt-parent = <&ipic>; + interrupts = <0x47 8>; + cell-index = <0>; + dma-channel@0 { + compatible = "fsl,mpc8349-dma-channel"; + reg = <0 0x80>; + }; + dma-channel@80 { + compatible = "fsl,mpc8349-dma-channel"; + reg = <0x80 0x80>; + }; + dma-channel@100 { + compatible = "fsl,mpc8349-dma-channel"; + reg = <0x100 0x80>; + }; + dma-channel@180 { + compatible = "fsl,mpc8349-dma-channel"; + reg = <0x180 0x28>; + }; + }; + /* IPIC * interrupts cell = * sense values match linux IORESOURCE_IRQ_* defines: diff --git a/arch/powerpc/boot/dts/mpc8610_hpcd.dts b/arch/powerpc/boot/dts/mpc8610_hpcd.dts index bba234eb14a92a12c9896ecb7936a240d96fb4bb..08a780d89807fcd6d5039641d9925af4a51164a1 100644 --- a/arch/powerpc/boot/dts/mpc8610_hpcd.dts +++ b/arch/powerpc/boot/dts/mpc8610_hpcd.dts @@ -46,9 +46,63 @@ reg = <0x00000000 0x20000000>; // 512M at 0x0 }; - board-control@e8000000 { - compatible = "fsl,fpga-pixis"; - reg = <0xe8000000 32>; // pixis at 0xe8000000 + localbus@e0005000 { + #address-cells = <2>; + #size-cells = <1>; + compatible = "fsl,mpc8610-elbc", "fsl,elbc", "simple-bus"; + reg = <0xe0005000 0x1000>; + interrupts = <19 2>; + interrupt-parent = <&mpic>; + ranges = <0 0 0xf8000000 0x08000000 + 1 0 0xf0000000 0x08000000 + 2 0 0xe8400000 0x00008000 + 4 0 0xe8440000 0x00008000 + 5 0 0xe8480000 0x00008000 + 6 0 0xe84c0000 0x00008000 + 3 0 0xe8000000 0x00000020>; + + flash@0,0 { + compatible = "cfi-flash"; + reg = <0 0 0x8000000>; + bank-width = <2>; + device-width = <1>; + }; + + flash@1,0 { + compatible = "cfi-flash"; + reg = <1 0 0x8000000>; + bank-width = <2>; + device-width = <1>; + }; + + flash@2,0 { + compatible = "fsl,mpc8610-fcm-nand", + "fsl,elbc-fcm-nand"; + reg = <2 0 0x8000>; + }; + + flash@4,0 { + compatible = "fsl,mpc8610-fcm-nand", + "fsl,elbc-fcm-nand"; + reg = <4 0 0x8000>; + }; + + flash@5,0 { + compatible = "fsl,mpc8610-fcm-nand", + "fsl,elbc-fcm-nand"; + reg = <5 0 0x8000>; + }; + + flash@6,0 { + compatible = "fsl,mpc8610-fcm-nand", + "fsl,elbc-fcm-nand"; + reg = <6 0 0x8000>; + }; + + board-control@3,0 { + compatible = "fsl,fpga-pixis"; + reg = <3 0 0x20>; + }; }; soc@e0000000 { diff --git a/arch/powerpc/boot/dts/sbc8548.dts b/arch/powerpc/boot/dts/sbc8548.dts index b86e65d926c16e40acffd304193018075deffa88..22d967178fe9c4e00ab99dae429ddaa96255eadc 100644 --- a/arch/powerpc/boot/dts/sbc8548.dts +++ b/arch/powerpc/boot/dts/sbc8548.dts @@ -52,6 +52,99 @@ reg = <0x00000000 0x10000000>; }; + localbus@e0000000 { + #address-cells = <2>; + #size-cells = <1>; + compatible = "simple-bus"; + reg = <0xe0000000 0x5000>; + interrupt-parent = <&mpic>; + + ranges = <0x0 0x0 0xff800000 0x00800000 /*8MB Flash*/ + 0x3 0x0 0xf0000000 0x04000000 /*64MB SDRAM*/ + 0x4 0x0 0xf4000000 0x04000000 /*64MB SDRAM*/ + 0x5 0x0 0xf8000000 0x00b10000 /* EPLD */ + 0x6 0x0 0xfb800000 0x04000000>; /*64MB Flash*/ + + + flash@0,0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "cfi-flash"; + reg = <0x0 0x0 0x800000>; + bank-width = <1>; + device-width = <1>; + partition@0x0 { + label = "space"; + reg = <0x00000000 0x00100000>; + }; + partition@0x100000 { + label = "bootloader"; + reg = <0x00100000 0x00700000>; + read-only; + }; + }; + + epld@5,0 { + compatible = "wrs,epld-localbus"; + #address-cells = <2>; + #size-cells = <1>; + reg = <0x5 0x0 0x00b10000>; + ranges = < + 0x0 0x0 0x5 0x000000 0x1fff /* LED */ + 0x1 0x0 0x5 0x100000 0x1fff /* Switches */ + 0x3 0x0 0x5 0x300000 0x1fff /* HW Rev. */ + 0xb 0x0 0x5 0xb00000 0x1fff /* EEPROM */ + >; + + led@0,0 { + compatible = "led"; + reg = <0x0 0x0 0x1fff>; + }; + + switches@1,0 { + compatible = "switches"; + reg = <0x1 0x0 0x1fff>; + }; + + hw-rev@3,0 { + compatible = "hw-rev"; + reg = <0x3 0x0 0x1fff>; + }; + + eeprom@b,0 { + compatible = "eeprom"; + reg = <0xb 0 0x1fff>; + }; + + }; + + alt-flash@6,0 { + #address-cells = <1>; + #size-cells = <1>; + reg = <0x6 0x0 0x04000000>; + compatible = "cfi-flash"; + bank-width = <4>; + device-width = <1>; + partition@0x0 { + label = "bootloader"; + reg = <0x00000000 0x00100000>; + read-only; + }; + partition@0x00100000 { + label = "file-system"; + reg = <0x00100000 0x01f00000>; + }; + partition@0x02000000 { + label = "boot-config"; + reg = <0x02000000 0x00100000>; + }; + partition@0x02100000 { + label = "space"; + reg = <0x02100000 0x01f00000>; + }; + }; + }; + soc8548@e0000000 { #address-cells = <1>; #size-cells = <1>; @@ -59,6 +152,7 @@ ranges = <0x00000000 0xe0000000 0x00100000>; reg = <0xe0000000 0x00001000>; // CCSRBAR bus-frequency = <0>; + compatible = "simple-bus"; memory-controller@2000 { compatible = "fsl,8548-memory-controller"; diff --git a/arch/powerpc/boot/dts/sequoia.dts b/arch/powerpc/boot/dts/sequoia.dts index a1ae4d6ec9908c3a86dc1900b39086ec8d08c995..72d67564bdfc6302a3d48185761aa5abeadd67ce 100644 --- a/arch/powerpc/boot/dts/sequoia.dts +++ b/arch/powerpc/boot/dts/sequoia.dts @@ -342,9 +342,14 @@ /* Outbound ranges, one memory and one IO, * later cannot be changed. Chip supports a second * IO range but we don't use it for now + * From the 440EPx user manual: + * PCI 1 Memory 1 8000 0000 1 BFFF FFFF 1GB + * I/O 1 E800 0000 1 E800 FFFF 64KB + * I/O 1 E880 0000 1 EBFF FFFF 56MB */ - ranges = <02000000 0 80000000 1 80000000 0 10000000 - 01000000 0 00000000 1 e8000000 0 00100000>; + ranges = <02000000 0 80000000 1 80000000 0 40000000 + 01000000 0 00000000 1 e8000000 0 00010000 + 01000000 0 00000000 1 e8800000 0 03800000>; /* Inbound 2GB range starting at 0 */ dma-ranges = <42000000 0 0 0 0 0 80000000>; diff --git a/arch/powerpc/configs/mpc8610_hpcd_defconfig b/arch/powerpc/configs/mpc8610_hpcd_defconfig index 9270afe7594d02975a05ef8b28c97155597c99ba..7e5b9ce58d896af32801fc8b73676edde3a5244f 100644 --- a/arch/powerpc/configs/mpc8610_hpcd_defconfig +++ b/arch/powerpc/configs/mpc8610_hpcd_defconfig @@ -358,7 +358,93 @@ CONFIG_FW_LOADER=y # CONFIG_DEBUG_DEVRES is not set # CONFIG_SYS_HYPERVISOR is not set # CONFIG_CONNECTOR is not set -# CONFIG_MTD is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_OF_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +CONFIG_MTD_PHYSMAP_OF=y +# CONFIG_MTD_INTEL_VR_NOR is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_CAFE is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +CONFIG_MTD_NAND_FSL_ELBC=y +# CONFIG_MTD_ONENAND is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set CONFIG_OF_DEVICE=y # CONFIG_PARPORT is not set CONFIG_BLK_DEV=y @@ -567,14 +653,11 @@ CONFIG_MII=y # CONFIG_NET_VENDOR_3COM is not set CONFIG_NET_TULIP=y # CONFIG_DE2104X is not set -CONFIG_TULIP=y -# CONFIG_TULIP_MWI is not set -CONFIG_TULIP_MMIO=y -# CONFIG_TULIP_NAPI is not set +# CONFIG_TULIP is not set # CONFIG_DE4X5 is not set # CONFIG_WINBOND_840 is not set # CONFIG_DM9102 is not set -# CONFIG_ULI526X is not set +CONFIG_ULI526X=y # CONFIG_HP100 is not set # CONFIG_IBM_NEW_EMAC_ZMII is not set # CONFIG_IBM_NEW_EMAC_RGMII is not set diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index d14cebf62bb03e42732c174a67d5f2134dffe13e..2346d271fbfdbc5bb8323a588de5124e3237cabf 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -105,6 +105,9 @@ PHONY += systbl_chk systbl_chk: $(src)/systbl_chk.sh $(obj)/systbl_chk.i $(call cmd,systbl_chk) + +ifeq ($(CONFIG_PPC_MERGE),y) + $(obj)/built-in.o: prom_init_check quiet_cmd_prom_init_check = CALL $< @@ -114,4 +117,7 @@ PHONY += prom_init_check prom_init_check: $(src)/prom_init_check.sh $(obj)/prom_init.o $(call cmd,prom_init_check) +endif + + clean-files := vmlinux.lds diff --git a/arch/powerpc/kernel/btext.c b/arch/powerpc/kernel/btext.c index 9f9377745490d966ff434f728bc1e15581c3dace..d8f0329b13444b73be463ea06c71169a193d180f 100644 --- a/arch/powerpc/kernel/btext.c +++ b/arch/powerpc/kernel/btext.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 36080d4d1922ba1d47621916f84fa528fe615816..e44d5530f0a6d5ea0457d137d1856fac559a7b82 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -1208,6 +1208,18 @@ static struct cpu_spec __initdata cpu_specs[] = { .machine_check = machine_check_4xx, .platform = "ppc405", }, + { /* default match */ + .pvr_mask = 0x00000000, + .pvr_value = 0x00000000, + .cpu_name = "(generic 40x PPC)", + .cpu_features = CPU_FTRS_40X, + .cpu_user_features = PPC_FEATURE_32 | + PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, + .icache_bsize = 32, + .dcache_bsize = 32, + .machine_check = machine_check_4xx, + .platform = "ppc405", + } #endif /* CONFIG_40x */ #ifdef CONFIG_44x @@ -1421,8 +1433,18 @@ static struct cpu_spec __initdata cpu_specs[] = { .machine_check = machine_check_440A, .platform = "ppc440", }, + { /* default match */ + .pvr_mask = 0x00000000, + .pvr_value = 0x00000000, + .cpu_name = "(generic 44x PPC)", + .cpu_features = CPU_FTRS_44X, + .cpu_user_features = COMMON_USER_BOOKE, + .icache_bsize = 32, + .dcache_bsize = 32, + .machine_check = machine_check_4xx, + .platform = "ppc440", + } #endif /* CONFIG_44x */ -#ifdef CONFIG_FSL_BOOKE #ifdef CONFIG_E200 { /* e200z5 */ .pvr_mask = 0xfff00000, @@ -1451,7 +1473,20 @@ static struct cpu_spec __initdata cpu_specs[] = { .machine_check = machine_check_e200, .platform = "ppc5554", }, -#elif defined(CONFIG_E500) + { /* default match */ + .pvr_mask = 0x00000000, + .pvr_value = 0x00000000, + .cpu_name = "(generic E200 PPC)", + .cpu_features = CPU_FTRS_E200, + .cpu_user_features = COMMON_USER_BOOKE | + PPC_FEATURE_HAS_EFP_SINGLE | + PPC_FEATURE_UNIFIED_CACHE, + .dcache_bsize = 32, + .machine_check = machine_check_e200, + .platform = "ppc5554", + } +#endif /* CONFIG_E200 */ +#ifdef CONFIG_E500 { /* e500 */ .pvr_mask = 0xffff0000, .pvr_value = 0x80200000, @@ -1487,20 +1522,20 @@ static struct cpu_spec __initdata cpu_specs[] = { .machine_check = machine_check_e500, .platform = "ppc8548", }, -#endif -#endif -#if !CLASSIC_PPC { /* default match */ .pvr_mask = 0x00000000, .pvr_value = 0x00000000, - .cpu_name = "(generic PPC)", - .cpu_features = CPU_FTRS_GENERIC_32, - .cpu_user_features = PPC_FEATURE_32, + .cpu_name = "(generic E500 PPC)", + .cpu_features = CPU_FTRS_E500, + .cpu_user_features = COMMON_USER_BOOKE | + PPC_FEATURE_HAS_SPE_COMP | + PPC_FEATURE_HAS_EFP_SINGLE_COMP, .icache_bsize = 32, .dcache_bsize = 32, + .machine_check = machine_check_e500, .platform = "powerpc", } -#endif /* !CLASSIC_PPC */ +#endif /* CONFIG_E500 */ #endif /* CONFIG_PPC32 */ }; diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S index b84ec6a2fc94c06a4374647344e0c4ce6c87e01c..c2b9dc4fce5d24a4021972f5337d66828faca918 100644 --- a/arch/powerpc/kernel/head_44x.S +++ b/arch/powerpc/kernel/head_44x.S @@ -653,7 +653,14 @@ finish_tlb_load: rlwimi r10, r11, 0, 26, 26 /* UX = HWEXEC & USER */ rlwimi r12, r10, 0, 26, 31 /* Insert static perms */ - rlwinm r12, r12, 0, 20, 15 /* Clear U0-U3 */ + + /* + * Clear U0-U3 and WL1 IL1I IL1D IL2I IL2D bits which are added + * on newer 440 cores like the 440x6 used on AMCC 460EX/460GT (see + * include/asm-powerpc/pgtable-ppc32.h for details). + */ + rlwinm r12, r12, 0, 20, 10 + tlbwe r12, r13, PPC44x_TLB_ATTRIB /* Write ATTRIB */ /* Done...restore registers and get out of here. diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 024805e1747df86a9c1e58f71b581932b70ddae7..25e84c0e116695e37d416296e34eb6f8cfc28ba6 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -1517,10 +1517,6 @@ _INIT_STATIC(start_here_multiplatform) addi r2,r2,0x4000 add r2,r2,r26 - /* Set initial ptr to current */ - LOAD_REG_IMMEDIATE(r4, init_task) - std r4,PACACURRENT(r13) - /* Do very early kernel initializations, including initial hash table, * stab and slb setup before we turn on relocation. */ diff --git a/arch/powerpc/kernel/init_task.c b/arch/powerpc/kernel/init_task.c index 941043ae040f086233fc2118a8f6d3d589cfc94f..4c85b8d564783b7a695aaad977ddd3c96b2ae197 100644 --- a/arch/powerpc/kernel/init_task.c +++ b/arch/powerpc/kernel/init_task.c @@ -8,7 +8,6 @@ #include static struct fs_struct init_fs = INIT_FS; -static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS(init_signals); static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); struct mm_struct init_mm = INIT_MM(init_mm); diff --git a/arch/powerpc/kernel/isa-bridge.c b/arch/powerpc/kernel/isa-bridge.c index 289af348978dac142638703e630bdaf367001068..4d5731b2429aa605f6776a8674d6c7e4a40d5520 100644 --- a/arch/powerpc/kernel/isa-bridge.c +++ b/arch/powerpc/kernel/isa-bridge.c @@ -108,9 +108,6 @@ static void __devinit pci_process_ISA_OF_ranges(struct device_node *isa_node, if (size > 0x10000) size = 0x10000; - printk(KERN_ERR "no ISA IO ranges or unexpected isa range, " - "mapping 64k\n"); - __ioremap_at(phb_io_base_phys, (void *)ISA_IO_BASE, size, _PAGE_NO_CACHE|_PAGE_GUARDED); return; diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 25e3fd8606ab589ebae8ee51143e39a517d32505..098fd96a394aa4df6947a2cad11146458de2b29f 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -170,6 +170,8 @@ void __init setup_paca(int cpu) void __init early_setup(unsigned long dt_ptr) { + /* -------- printk is _NOT_ safe to use here ! ------- */ + /* Fill in any unititialised pacas */ initialise_pacas(); @@ -179,12 +181,14 @@ void __init early_setup(unsigned long dt_ptr) /* Assume we're on cpu 0 for now. Don't write to the paca yet! */ setup_paca(0); - /* Enable early debugging if any specified (see udbg.h) */ - udbg_early_init(); - /* Initialize lockdep early or else spinlocks will blow */ lockdep_init(); + /* -------- printk is now safe to use ------- */ + + /* Enable early debugging if any specified (see udbg.h) */ + udbg_early_init(); + DBG(" -> early_setup(), dt_ptr: 0x%lx\n", dt_ptr); /* diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index f1d2cdc5331b256e2b3c3133ff3e3196bf520f8e..c71d37dc6a88220d41b14480cbdf2a6ae692dcd8 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -10,6 +10,7 @@ ifeq ($(CONFIG_PPC_MERGE),y) obj-y := string.o alloc.o \ checksum_$(CONFIG_WORD_SIZE).o obj-$(CONFIG_PPC32) += div64.o copy_32.o +obj-$(CONFIG_HAS_IOMEM) += devres.o endif obj-$(CONFIG_PPC64) += copypage_64.o copyuser_64.o \ @@ -23,4 +24,3 @@ obj-$(CONFIG_SMP) += locks.o endif obj-$(CONFIG_PPC_LIB_RHEAP) += rheap.o -obj-$(CONFIG_HAS_IOMEM) += devres.o diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index 2b5a399f6fa644763866440916e73658d14e3ed9..0f2d239d94c440608dadf79671b4b95f6cf4e0e9 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -94,6 +94,9 @@ unsigned long htab_hash_mask; int mmu_linear_psize = MMU_PAGE_4K; int mmu_virtual_psize = MMU_PAGE_4K; int mmu_vmalloc_psize = MMU_PAGE_4K; +#ifdef CONFIG_SPARSEMEM_VMEMMAP +int mmu_vmemmap_psize = MMU_PAGE_4K; +#endif int mmu_io_psize = MMU_PAGE_4K; int mmu_kernel_ssize = MMU_SEGSIZE_256M; int mmu_highuser_ssize = MMU_SEGSIZE_256M; @@ -387,11 +390,32 @@ static void __init htab_init_page_sizes(void) } #endif /* CONFIG_PPC_64K_PAGES */ +#ifdef CONFIG_SPARSEMEM_VMEMMAP + /* We try to use 16M pages for vmemmap if that is supported + * and we have at least 1G of RAM at boot + */ + if (mmu_psize_defs[MMU_PAGE_16M].shift && + lmb_phys_mem_size() >= 0x40000000) + mmu_vmemmap_psize = MMU_PAGE_16M; + else if (mmu_psize_defs[MMU_PAGE_64K].shift) + mmu_vmemmap_psize = MMU_PAGE_64K; + else + mmu_vmemmap_psize = MMU_PAGE_4K; +#endif /* CONFIG_SPARSEMEM_VMEMMAP */ + printk(KERN_DEBUG "Page orders: linear mapping = %d, " - "virtual = %d, io = %d\n", + "virtual = %d, io = %d" +#ifdef CONFIG_SPARSEMEM_VMEMMAP + ", vmemmap = %d" +#endif + "\n", mmu_psize_defs[mmu_linear_psize].shift, mmu_psize_defs[mmu_virtual_psize].shift, - mmu_psize_defs[mmu_io_psize].shift); + mmu_psize_defs[mmu_io_psize].shift +#ifdef CONFIG_SPARSEMEM_VMEMMAP + ,mmu_psize_defs[mmu_vmemmap_psize].shift +#endif + ); #ifdef CONFIG_HUGETLB_PAGE /* Init large page size. Currently, we pick 16M or 1M depending diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c index c5ac532a0161b733757016d8fb28396d9a47193d..6aa65375abf5919ce2b02c0efe309dd8d39c893c 100644 --- a/arch/powerpc/mm/init_64.c +++ b/arch/powerpc/mm/init_64.c @@ -19,6 +19,8 @@ * */ +#undef DEBUG + #include #include #include @@ -208,12 +210,12 @@ int __meminit vmemmap_populated(unsigned long start, int page_size) } int __meminit vmemmap_populate(struct page *start_page, - unsigned long nr_pages, int node) + unsigned long nr_pages, int node) { unsigned long mode_rw; unsigned long start = (unsigned long)start_page; unsigned long end = (unsigned long)(start_page + nr_pages); - unsigned long page_size = 1 << mmu_psize_defs[mmu_linear_psize].shift; + unsigned long page_size = 1 << mmu_psize_defs[mmu_vmemmap_psize].shift; mode_rw = _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | PP_RWXX; @@ -235,11 +237,11 @@ int __meminit vmemmap_populate(struct page *start_page, start, p, __pa(p)); mapped = htab_bolt_mapping(start, start + page_size, - __pa(p), mode_rw, mmu_linear_psize, + __pa(p), mode_rw, mmu_vmemmap_psize, mmu_kernel_ssize); BUG_ON(mapped < 0); } return 0; } -#endif +#endif /* CONFIG_SPARSEMEM_VMEMMAP */ diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c index cf8705e32d607b9692d0213f543ac84e092afe7b..89497fb04280ce6bb63b50af6603c513c942d872 100644 --- a/arch/powerpc/mm/slb.c +++ b/arch/powerpc/mm/slb.c @@ -28,7 +28,7 @@ #include #ifdef DEBUG -#define DBG(fmt...) udbg_printf(fmt) +#define DBG(fmt...) printk(fmt) #else #define DBG pr_debug #endif @@ -263,13 +263,19 @@ void slb_initialize(void) extern unsigned int *slb_miss_kernel_load_linear; extern unsigned int *slb_miss_kernel_load_io; extern unsigned int *slb_compare_rr_to_size; +#ifdef CONFIG_SPARSEMEM_VMEMMAP + extern unsigned int *slb_miss_kernel_load_vmemmap; + unsigned long vmemmap_llp; +#endif /* Prepare our SLB miss handler based on our page size */ linear_llp = mmu_psize_defs[mmu_linear_psize].sllp; io_llp = mmu_psize_defs[mmu_io_psize].sllp; vmalloc_llp = mmu_psize_defs[mmu_vmalloc_psize].sllp; get_paca()->vmalloc_sllp = SLB_VSID_KERNEL | vmalloc_llp; - +#ifdef CONFIG_SPARSEMEM_VMEMMAP + vmemmap_llp = mmu_psize_defs[mmu_vmemmap_psize].sllp; +#endif if (!slb_encoding_inited) { slb_encoding_inited = 1; patch_slb_encoding(slb_miss_kernel_load_linear, @@ -281,6 +287,12 @@ void slb_initialize(void) DBG("SLB: linear LLP = %04lx\n", linear_llp); DBG("SLB: io LLP = %04lx\n", io_llp); + +#ifdef CONFIG_SPARSEMEM_VMEMMAP + patch_slb_encoding(slb_miss_kernel_load_vmemmap, + SLB_VSID_KERNEL | vmemmap_llp); + DBG("SLB: vmemmap LLP = %04lx\n", vmemmap_llp); +#endif } get_paca()->stab_rr = SLB_NUM_BOLTED; diff --git a/arch/powerpc/mm/slb_low.S b/arch/powerpc/mm/slb_low.S index 657f6b37e9df58892fe4ece4a2a02eef51fe7d44..bc44dc4b5c67f4dfe1efb0247b60b4b7493a3945 100644 --- a/arch/powerpc/mm/slb_low.S +++ b/arch/powerpc/mm/slb_low.S @@ -47,8 +47,7 @@ _GLOBAL(slb_allocate_realmode) * it to VSID 0, which is reserved as a bad VSID - one which * will never have any pages in it. */ - /* Check if hitting the linear mapping of the vmalloc/ioremap - * kernel space + /* Check if hitting the linear mapping or some other kernel space */ bne cr7,1f @@ -62,7 +61,18 @@ BEGIN_FTR_SECTION END_FTR_SECTION_IFCLR(CPU_FTR_1T_SEGMENT) b slb_finish_load_1T -1: /* vmalloc/ioremap mapping encoding bits, the "li" instructions below +1: +#ifdef CONFIG_SPARSEMEM_VMEMMAP + /* Check virtual memmap region. To be patches at kernel boot */ + cmpldi cr0,r9,0xf + bne 1f +_GLOBAL(slb_miss_kernel_load_vmemmap) + li r11,0 + b 6f +1: +#endif /* CONFIG_SPARSEMEM_VMEMMAP */ + + /* vmalloc/ioremap mapping encoding bits, the "li" instructions below * will be patched by the kernel at boot */ BEGIN_FTR_SECTION diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c index 25f8bc75e838400de36fbb2f8345513e69afa232..43a459f63e31230fa54341aed5df7cd3e6ac2463 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -56,6 +57,95 @@ #define DBG(fmt...) #endif +#define MV88E1111_SCR 0x10 +#define MV88E1111_SCR_125CLK 0x0010 +static int mpc8568_fixup_125_clock(struct phy_device *phydev) +{ + int scr; + int err; + + /* Workaround for the 125 CLK Toggle */ + scr = phy_read(phydev, MV88E1111_SCR); + + if (scr < 0) + return scr; + + err = phy_write(phydev, MV88E1111_SCR, scr & ~(MV88E1111_SCR_125CLK)); + + if (err) + return err; + + err = phy_write(phydev, MII_BMCR, BMCR_RESET); + + if (err) + return err; + + scr = phy_read(phydev, MV88E1111_SCR); + + if (scr < 0) + return err; + + err = phy_write(phydev, MV88E1111_SCR, scr | 0x0008); + + return err; +} + +static int mpc8568_mds_phy_fixups(struct phy_device *phydev) +{ + int temp; + int err; + + /* Errata */ + err = phy_write(phydev,29, 0x0006); + + if (err) + return err; + + temp = phy_read(phydev, 30); + + if (temp < 0) + return temp; + + temp = (temp & (~0x8000)) | 0x4000; + err = phy_write(phydev,30, temp); + + if (err) + return err; + + err = phy_write(phydev,29, 0x000a); + + if (err) + return err; + + temp = phy_read(phydev, 30); + + if (temp < 0) + return temp; + + temp = phy_read(phydev, 30); + + if (temp < 0) + return temp; + + temp &= ~0x0020; + + err = phy_write(phydev,30,temp); + + if (err) + return err; + + /* Disable automatic MDI/MDIX selection */ + temp = phy_read(phydev, 16); + + if (temp < 0) + return temp; + + temp &= ~0x0060; + err = phy_write(phydev,16,temp); + + return err; +} + /* ************************************************************************ * * Setup the architecture @@ -64,7 +154,7 @@ static void __init mpc85xx_mds_setup_arch(void) { struct device_node *np; - static u8 *bcsr_regs = NULL; + static u8 __iomem *bcsr_regs = NULL; if (ppc_md.progress) ppc_md.progress("mpc85xx_mds_setup_arch()", 0); @@ -138,6 +228,35 @@ static void __init mpc85xx_mds_setup_arch(void) #endif /* CONFIG_QUICC_ENGINE */ } + +static int __init board_fixups(void) +{ + char phy_id[BUS_ID_SIZE]; + char *compstrs[2] = {"fsl,gianfar-mdio", "fsl,ucc-mdio"}; + struct device_node *mdio; + struct resource res; + int i; + + for (i = 0; i < ARRAY_SIZE(compstrs); i++) { + mdio = of_find_compatible_node(NULL, NULL, compstrs[i]); + + of_address_to_resource(mdio, 0, &res); + snprintf(phy_id, BUS_ID_SIZE, "%x:%02x", res.start, 1); + + phy_register_fixup_for_id(phy_id, mpc8568_fixup_125_clock); + phy_register_fixup_for_id(phy_id, mpc8568_mds_phy_fixups); + + /* Register a workaround for errata */ + snprintf(phy_id, BUS_ID_SIZE, "%x:%02x", res.start, 7); + phy_register_fixup_for_id(phy_id, mpc8568_mds_phy_fixups); + + of_node_put(mdio); + } + + return 0; +} +machine_arch_initcall(mpc85xx_mds, board_fixups); + static struct of_device_id mpc85xx_ids[] = { { .type = "soc", }, { .compatible = "soc", }, diff --git a/arch/powerpc/platforms/85xx/sbc8548.c b/arch/powerpc/platforms/85xx/sbc8548.c index 488facb99fe83533fae4505b30b6dfc7ae6b3991..b9246ea0928a6c699703bd4993f71da311418e89 100644 --- a/arch/powerpc/platforms/85xx/sbc8548.c +++ b/arch/powerpc/platforms/85xx/sbc8548.c @@ -49,6 +49,8 @@ #include #include +static int sbc_rev; + static void __init sbc8548_pic_init(void) { struct mpic *mpic; @@ -79,6 +81,30 @@ static void __init sbc8548_pic_init(void) mpic_init(mpic); } +/* Extract the HW Rev from the EPLD on the board */ +static int __init sbc8548_hw_rev(void) +{ + struct device_node *np; + struct resource res; + unsigned int *rev; + int board_rev = 0; + + np = of_find_compatible_node(NULL, NULL, "hw-rev"); + if (np == NULL) { + printk("No HW-REV found in DTB.\n"); + return -ENODEV; + } + + of_address_to_resource(np, 0, &res); + of_node_put(np); + + rev = ioremap(res.start,sizeof(unsigned int)); + board_rev = (*rev) >> 28; + iounmap(rev); + + return board_rev; +} + /* * Setup the architecture */ @@ -104,6 +130,7 @@ static void __init sbc8548_setup_arch(void) } } #endif + sbc_rev = sbc8548_hw_rev(); } static void sbc8548_show_cpuinfo(struct seq_file *m) @@ -115,7 +142,7 @@ static void sbc8548_show_cpuinfo(struct seq_file *m) svid = mfspr(SPRN_SVR); seq_printf(m, "Vendor\t\t: Wind River\n"); - seq_printf(m, "Machine\t\t: SBC8548\n"); + seq_printf(m, "Machine\t\t: SBC8548 v%d\n", sbc_rev); seq_printf(m, "PVR\t\t: 0x%x\n", pvid); seq_printf(m, "SVR\t\t: 0x%x\n", svid); @@ -130,6 +157,7 @@ static void sbc8548_show_cpuinfo(struct seq_file *m) static struct of_device_id __initdata of_bus_ids[] = { { .name = "soc", }, { .type = "soc", }, + { .compatible = "simple-bus", }, {}, }; diff --git a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c index 5e1e8cf14e75785675f4072afe033777daab241c..dea13208bf64d618f787ad748115814995dcad4a 100644 --- a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c +++ b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c @@ -43,6 +43,7 @@ static unsigned char *pixis_bdcfg0, *pixis_arch; static struct of_device_id __initdata mpc8610_ids[] = { { .compatible = "fsl,mpc8610-immr", }, + { .compatible = "simple-bus", }, {} }; @@ -216,11 +217,21 @@ void mpc8610hpcd_set_gamma_table(int monitor_port, char *gamma_table_base) } } +#define PX_BRDCFG0_DVISEL (1 << 3) +#define PX_BRDCFG0_DLINK (1 << 4) +#define PX_BRDCFG0_DIU_MASK (PX_BRDCFG0_DVISEL | PX_BRDCFG0_DLINK) + void mpc8610hpcd_set_monitor_port(int monitor_port) { - static const u8 bdcfg[] = {0xBD, 0xB5, 0xA5}; + static const u8 bdcfg[] = { + PX_BRDCFG0_DVISEL | PX_BRDCFG0_DLINK, + PX_BRDCFG0_DLINK, + 0, + }; + if (monitor_port < 3) - *pixis_bdcfg0 = bdcfg[monitor_port]; + clrsetbits_8(pixis_bdcfg0, PX_BRDCFG0_DIU_MASK, + bdcfg[monitor_port]); } void mpc8610hpcd_set_pixel_clock(unsigned int pixclock) diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c index 04f74f9f9ab67dcae27a706a7c3de449bab22ac6..5bf7df14602288b1d4daafb79e1116ac92066864 100644 --- a/arch/powerpc/platforms/cell/interrupt.c +++ b/arch/powerpc/platforms/cell/interrupt.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -231,6 +232,54 @@ static int iic_host_match(struct irq_host *h, struct device_node *node) "IBM,CBEA-Internal-Interrupt-Controller"); } +extern int noirqdebug; + +static void handle_iic_irq(unsigned int irq, struct irq_desc *desc) +{ + const unsigned int cpu = smp_processor_id(); + + spin_lock(&desc->lock); + + desc->status &= ~(IRQ_REPLAY | IRQ_WAITING); + + /* + * If we're currently running this IRQ, or its disabled, + * we shouldn't process the IRQ. Mark it pending, handle + * the necessary masking and go out + */ + if (unlikely((desc->status & (IRQ_INPROGRESS | IRQ_DISABLED)) || + !desc->action)) { + desc->status |= IRQ_PENDING; + goto out_eoi; + } + + kstat_cpu(cpu).irqs[irq]++; + + /* Mark the IRQ currently in progress.*/ + desc->status |= IRQ_INPROGRESS; + + do { + struct irqaction *action = desc->action; + irqreturn_t action_ret; + + if (unlikely(!action)) + goto out_eoi; + + desc->status &= ~IRQ_PENDING; + spin_unlock(&desc->lock); + action_ret = handle_IRQ_event(irq, action); + if (!noirqdebug) + note_interrupt(irq, desc, action_ret); + spin_lock(&desc->lock); + + } while ((desc->status & (IRQ_PENDING | IRQ_DISABLED)) == IRQ_PENDING); + + desc->status &= ~IRQ_INPROGRESS; +out_eoi: + desc->chip->eoi(irq); + spin_unlock(&desc->lock); +} + static int iic_host_map(struct irq_host *h, unsigned int virq, irq_hw_number_t hw) { @@ -240,10 +289,10 @@ static int iic_host_map(struct irq_host *h, unsigned int virq, break; case IIC_IRQ_TYPE_IOEXC: set_irq_chip_and_handler(virq, &iic_ioexc_chip, - handle_fasteoi_irq); + handle_iic_irq); break; default: - set_irq_chip_and_handler(virq, &iic_chip, handle_fasteoi_irq); + set_irq_chip_and_handler(virq, &iic_chip, handle_iic_irq); } return 0; } diff --git a/arch/powerpc/platforms/cell/io-workarounds.c b/arch/powerpc/platforms/cell/io-workarounds.c index 3b84e8be314c4f5a09217f11d89426d86c93b19e..b5f84e8f089990756daa13ca1101a9ccc4db74d6 100644 --- a/arch/powerpc/platforms/cell/io-workarounds.c +++ b/arch/powerpc/platforms/cell/io-workarounds.c @@ -118,7 +118,7 @@ static void iowa_##name at \ #undef DEF_PCI_AC_RET #undef DEF_PCI_AC_NORET -static struct ppc_pci_io __initdata iowa_pci_io = { +static const struct ppc_pci_io __devinitconst iowa_pci_io = { #define DEF_PCI_AC_RET(name, ret, at, al, space, aa) .name = iowa_##name, #define DEF_PCI_AC_NORET(name, at, al, space, aa) .name = iowa_##name, @@ -146,7 +146,7 @@ static void __iomem *iowa_ioremap(unsigned long addr, unsigned long size, } /* Regist new bus to support workaround */ -void __init iowa_register_bus(struct pci_controller *phb, +void __devinit iowa_register_bus(struct pci_controller *phb, struct ppc_pci_io *ops, int (*initfunc)(struct iowa_bus *, void *), void *data) { @@ -173,7 +173,7 @@ void __init iowa_register_bus(struct pci_controller *phb, } /* enable IO workaround */ -void __init io_workaround_init(void) +void __devinit io_workaround_init(void) { static int io_workaround_inited; diff --git a/arch/powerpc/platforms/cell/io-workarounds.h b/arch/powerpc/platforms/cell/io-workarounds.h index 79d8ed3d510f41889f41a5a566479dd4257248ba..6efc7782ebf2832062907a378fb5335b8f9922cb 100644 --- a/arch/powerpc/platforms/cell/io-workarounds.h +++ b/arch/powerpc/platforms/cell/io-workarounds.h @@ -31,9 +31,9 @@ struct iowa_bus { void *private; }; -void __init io_workaround_init(void); -void __init iowa_register_bus(struct pci_controller *, struct ppc_pci_io *, - int (*)(struct iowa_bus *, void *), void *); +void __devinit io_workaround_init(void); +void __devinit iowa_register_bus(struct pci_controller *, struct ppc_pci_io *, + int (*)(struct iowa_bus *, void *), void *); struct iowa_bus *iowa_mem_find_bus(const PCI_IO_ADDR); struct iowa_bus *iowa_pio_find_bus(unsigned long); diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index 6bab44b7716b2d525bff0720c0c6a0f436a55acb..70c660121ec4d0d2da4a36071d851a1acd3e7870 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c @@ -141,6 +141,10 @@ static void spu_restart_dma(struct spu *spu) if (!test_bit(SPU_CONTEXT_SWITCH_PENDING, &spu->flags)) out_be64(&priv2->mfc_control_RW, MFC_CNTL_RESTART_DMA_COMMAND); + else { + set_bit(SPU_CONTEXT_FAULT_PENDING, &spu->flags); + mb(); + } } static inline void spu_load_slb(struct spu *spu, int slbe, struct spu_slb *slb) @@ -226,11 +230,13 @@ static int __spu_trap_data_map(struct spu *spu, unsigned long ea, u64 dsisr) return 0; } - spu->class_0_pending = 0; - spu->dar = ea; - spu->dsisr = dsisr; + spu->class_1_dar = ea; + spu->class_1_dsisr = dsisr; + + spu->stop_callback(spu, 1); - spu->stop_callback(spu); + spu->class_1_dar = 0; + spu->class_1_dsisr = 0; return 0; } @@ -318,11 +324,15 @@ spu_irq_class_0(int irq, void *data) stat = spu_int_stat_get(spu, 0) & mask; spu->class_0_pending |= stat; - spu->dsisr = spu_mfc_dsisr_get(spu); - spu->dar = spu_mfc_dar_get(spu); + spu->class_0_dsisr = spu_mfc_dsisr_get(spu); + spu->class_0_dar = spu_mfc_dar_get(spu); spin_unlock(&spu->register_lock); - spu->stop_callback(spu); + spu->stop_callback(spu, 0); + + spu->class_0_pending = 0; + spu->class_0_dsisr = 0; + spu->class_0_dar = 0; spu_int_stat_clear(spu, 0, stat); @@ -363,6 +373,9 @@ spu_irq_class_1(int irq, void *data) if (stat & CLASS1_LS_COMPARE_SUSPEND_ON_PUT_INTR) ; + spu->class_1_dsisr = 0; + spu->class_1_dar = 0; + return stat ? IRQ_HANDLED : IRQ_NONE; } @@ -396,10 +409,10 @@ spu_irq_class_2(int irq, void *data) spu->ibox_callback(spu); if (stat & CLASS2_SPU_STOP_INTR) - spu->stop_callback(spu); + spu->stop_callback(spu, 2); if (stat & CLASS2_SPU_HALT_INTR) - spu->stop_callback(spu); + spu->stop_callback(spu, 2); if (stat & CLASS2_SPU_DMA_TAG_GROUP_COMPLETE_INTR) spu->mfc_callback(spu); diff --git a/arch/powerpc/platforms/cell/spu_priv1_mmio.c b/arch/powerpc/platforms/cell/spu_priv1_mmio.c index 67fa7247b80a4e0dac21d6702c2fcc0c1d6b1867..906a0a2a9fe18fc4273be7916f18df118c824dc1 100644 --- a/arch/powerpc/platforms/cell/spu_priv1_mmio.c +++ b/arch/powerpc/platforms/cell/spu_priv1_mmio.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -75,8 +76,19 @@ static u64 int_stat_get(struct spu *spu, int class) static void cpu_affinity_set(struct spu *spu, int cpu) { - u64 target = iic_get_target_id(cpu); - u64 route = target << 48 | target << 32 | target << 16; + u64 target; + u64 route; + + if (nr_cpus_node(spu->node)) { + cpumask_t spumask = node_to_cpumask(spu->node); + cpumask_t cpumask = node_to_cpumask(cpu_to_node(cpu)); + + if (!cpus_intersects(spumask, cpumask)) + return; + } + + target = iic_get_target_id(cpu); + route = target << 48 | target << 32 | target << 16; out_be64(&spu->priv1->int_route_RW, route); } diff --git a/arch/powerpc/platforms/cell/spufs/fault.c b/arch/powerpc/platforms/cell/spufs/fault.c index e46d300e21a5e18cf3b612b214a11af5f9562805..f093a581ac7410792a9126b2b0bbc87f665e9fdc 100644 --- a/arch/powerpc/platforms/cell/spufs/fault.c +++ b/arch/powerpc/platforms/cell/spufs/fault.c @@ -83,13 +83,18 @@ int spufs_handle_class0(struct spu_context *ctx) return 0; if (stat & CLASS0_DMA_ALIGNMENT_INTR) - spufs_handle_event(ctx, ctx->csa.dar, SPE_EVENT_DMA_ALIGNMENT); + spufs_handle_event(ctx, ctx->csa.class_0_dar, + SPE_EVENT_DMA_ALIGNMENT); if (stat & CLASS0_INVALID_DMA_COMMAND_INTR) - spufs_handle_event(ctx, ctx->csa.dar, SPE_EVENT_INVALID_DMA); + spufs_handle_event(ctx, ctx->csa.class_0_dar, + SPE_EVENT_INVALID_DMA); if (stat & CLASS0_SPU_ERROR_INTR) - spufs_handle_event(ctx, ctx->csa.dar, SPE_EVENT_SPE_ERROR); + spufs_handle_event(ctx, ctx->csa.class_0_dar, + SPE_EVENT_SPE_ERROR); + + ctx->csa.class_0_pending = 0; return -EIO; } @@ -119,8 +124,8 @@ int spufs_handle_class1(struct spu_context *ctx) * in time, we can still expect to get the same fault * the immediately after the context restore. */ - ea = ctx->csa.dar; - dsisr = ctx->csa.dsisr; + ea = ctx->csa.class_1_dar; + dsisr = ctx->csa.class_1_dsisr; if (!(dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED))) return 0; @@ -158,7 +163,7 @@ int spufs_handle_class1(struct spu_context *ctx) * time slicing will not preempt the context while the page fault * handler is running. Context switch code removes mappings. */ - ctx->csa.dar = ctx->csa.dsisr = 0; + ctx->csa.class_1_dar = ctx->csa.class_1_dsisr = 0; /* * If we handled the fault successfully and are in runnable diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 80911a37340063a84d0ffaf045802858988eac17..c81341ff75b548be96daf09ba55eac4e2cda539c 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -32,6 +32,7 @@ #include #include +#include #include #include #include diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index 0c32a05ab068a1487485d8871ce26a847d50a784..f407b24718554f474a153dc9a66e93d88518739f 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -223,7 +224,7 @@ static int spufs_dir_close(struct inode *inode, struct file *file) parent = dir->d_parent->d_inode; ctx = SPUFS_I(dir->d_inode)->i_ctx; - mutex_lock(&parent->i_mutex); + mutex_lock_nested(&parent->i_mutex, I_MUTEX_PARENT); ret = spufs_rmdir(parent, dir); mutex_unlock(&parent->i_mutex); WARN_ON(ret); @@ -618,12 +619,15 @@ long spufs_create(struct nameidata *nd, unsigned int flags, mode_t mode, mode &= ~current->fs->umask; if (flags & SPU_CREATE_GANG) - return spufs_create_gang(nd->path.dentry->d_inode, + ret = spufs_create_gang(nd->path.dentry->d_inode, dentry, nd->path.mnt, mode); else - return spufs_create_context(nd->path.dentry->d_inode, + ret = spufs_create_context(nd->path.dentry->d_inode, dentry, nd->path.mnt, flags, mode, filp); + if (ret >= 0) + fsnotify_mkdir(nd->path.dentry->d_inode, dentry); + return ret; out_dput: dput(dentry); diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c index a9c35b7b719fda3bd3850dc1dfdaa74d2e5acc6b..b7493b86581228d0edf8b0c0b691582e706bac58 100644 --- a/arch/powerpc/platforms/cell/spufs/run.c +++ b/arch/powerpc/platforms/cell/spufs/run.c @@ -11,7 +11,7 @@ #include "spufs.h" /* interrupt-level stop callback function. */ -void spufs_stop_callback(struct spu *spu) +void spufs_stop_callback(struct spu *spu, int irq) { struct spu_context *ctx = spu->ctx; @@ -24,9 +24,19 @@ void spufs_stop_callback(struct spu *spu) */ if (ctx) { /* Copy exception arguments into module specific structure */ - ctx->csa.class_0_pending = spu->class_0_pending; - ctx->csa.dsisr = spu->dsisr; - ctx->csa.dar = spu->dar; + switch(irq) { + case 0 : + ctx->csa.class_0_pending = spu->class_0_pending; + ctx->csa.class_0_dsisr = spu->class_0_dsisr; + ctx->csa.class_0_dar = spu->class_0_dar; + break; + case 1 : + ctx->csa.class_1_dsisr = spu->class_1_dsisr; + ctx->csa.class_1_dar = spu->class_1_dar; + break; + case 2 : + break; + } /* ensure that the exception status has hit memory before a * thread waiting on the context's stop queue is woken */ @@ -34,11 +44,6 @@ void spufs_stop_callback(struct spu *spu) wake_up_all(&ctx->stop_wq); } - - /* Clear callback arguments from spu structure */ - spu->class_0_pending = 0; - spu->dsisr = 0; - spu->dar = 0; } int spu_stopped(struct spu_context *ctx, u32 *stat) @@ -56,7 +61,11 @@ int spu_stopped(struct spu_context *ctx, u32 *stat) if (!(*stat & SPU_STATUS_RUNNING) && (*stat & stopped)) return 1; - dsisr = ctx->csa.dsisr; + dsisr = ctx->csa.class_0_dsisr; + if (dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED)) + return 1; + + dsisr = ctx->csa.class_1_dsisr; if (dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED)) return 1; @@ -294,7 +303,7 @@ static int spu_process_callback(struct spu_context *ctx) u32 ls_pointer, npc; void __iomem *ls; long spu_ret; - int ret, ret2; + int ret; /* get syscall block from local store */ npc = ctx->ops->npc_read(ctx) & ~3; @@ -316,11 +325,9 @@ static int spu_process_callback(struct spu_context *ctx) if (spu_ret <= -ERESTARTSYS) { ret = spu_handle_restartsys(ctx, &spu_ret, &npc); } - ret2 = spu_acquire(ctx); + mutex_lock(&ctx->state_mutex); if (ret == -ERESTARTSYS) return ret; - if (ret2) - return -EINTR; } /* need to re-get the ls, as it may have changed when we released the @@ -343,13 +350,14 @@ long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *event) if (mutex_lock_interruptible(&ctx->run_mutex)) return -ERESTARTSYS; - spu_enable_spu(ctx); ctx->event_return = 0; ret = spu_acquire(ctx); if (ret) goto out_unlock; + spu_enable_spu(ctx); + spu_update_sched_info(ctx); ret = spu_run_init(ctx, npc); diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c index 7298e7db2c8365cf83f8519350f917a01a35c8c3..745dd51ec37f7fdacab76bcc773a4a6fa421716a 100644 --- a/arch/powerpc/platforms/cell/spufs/sched.c +++ b/arch/powerpc/platforms/cell/spufs/sched.c @@ -140,6 +140,9 @@ void __spu_update_sched_info(struct spu_context *ctx) * if it is timesliced or preempted. */ ctx->cpus_allowed = current->cpus_allowed; + + /* Save the current cpu id for spu interrupt routing. */ + ctx->last_ran = raw_smp_processor_id(); } void spu_update_sched_info(struct spu_context *ctx) @@ -243,7 +246,6 @@ static void spu_bind_context(struct spu *spu, struct spu_context *ctx) spu_switch_log_notify(spu, ctx, SWITCH_LOG_START, 0); spu_restore(&ctx->csa, spu); spu->timestamp = jiffies; - spu_cpu_affinity_set(spu, raw_smp_processor_id()); spu_switch_notify(spu, ctx); ctx->state = SPU_STATE_RUNNABLE; @@ -657,7 +659,8 @@ static struct spu *find_victim(struct spu_context *ctx) victim->stats.invol_ctx_switch++; spu->stats.invol_ctx_switch++; - spu_add_to_rq(victim); + if (test_bit(SPU_SCHED_SPU_RUN, &victim->sched_flags)) + spu_add_to_rq(victim); mutex_unlock(&victim->state_mutex); diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h index 7312745b7540d4586fd72c7e4b57e9b5a9abd641..454c277c1457deaf4034b084cf95e438241c295c 100644 --- a/arch/powerpc/platforms/cell/spufs/spufs.h +++ b/arch/powerpc/platforms/cell/spufs/spufs.h @@ -121,6 +121,7 @@ struct spu_context { cpumask_t cpus_allowed; int policy; int prio; + int last_ran; /* statistics */ struct { @@ -331,7 +332,7 @@ size_t spu_ibox_read(struct spu_context *ctx, u32 *data); /* irq callback funcs. */ void spufs_ibox_callback(struct spu *spu); void spufs_wbox_callback(struct spu *spu); -void spufs_stop_callback(struct spu *spu); +void spufs_stop_callback(struct spu *spu, int irq); void spufs_mfc_callback(struct spu *spu); void spufs_dma_callback(struct spu *spu, int type); diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c index d2a1249d36dd2a7bc018727e09c3b7c57b88cf1c..3df9a36eb2f58efe6bcda41f7d27cf5861ac4e5b 100644 --- a/arch/powerpc/platforms/cell/spufs/switch.c +++ b/arch/powerpc/platforms/cell/spufs/switch.c @@ -132,6 +132,14 @@ static inline void disable_interrupts(struct spu_state *csa, struct spu *spu) spu_int_mask_set(spu, 2, 0ul); eieio(); spin_unlock_irq(&spu->register_lock); + + /* + * This flag needs to be set before calling synchronize_irq so + * that the update will be visible to the relevant handlers + * via a simple load. + */ + set_bit(SPU_CONTEXT_SWITCH_PENDING, &spu->flags); + clear_bit(SPU_CONTEXT_FAULT_PENDING, &spu->flags); synchronize_irq(spu->irqs[0]); synchronize_irq(spu->irqs[1]); synchronize_irq(spu->irqs[2]); @@ -166,9 +174,8 @@ static inline void set_switch_pending(struct spu_state *csa, struct spu *spu) /* Save, Step 7: * Restore, Step 5: * Set a software context switch pending flag. + * Done above in Step 3 - disable_interrupts(). */ - set_bit(SPU_CONTEXT_SWITCH_PENDING, &spu->flags); - mb(); } static inline void save_mfc_cntl(struct spu_state *csa, struct spu *spu) @@ -186,20 +193,21 @@ static inline void save_mfc_cntl(struct spu_state *csa, struct spu *spu) MFC_CNTL_SUSPEND_COMPLETE); /* fall through */ case MFC_CNTL_SUSPEND_COMPLETE: - if (csa) { + if (csa) csa->priv2.mfc_control_RW = - MFC_CNTL_SUSPEND_MASK | + in_be64(&priv2->mfc_control_RW) | MFC_CNTL_SUSPEND_DMA_QUEUE; - } break; case MFC_CNTL_NORMAL_DMA_QUEUE_OPERATION: out_be64(&priv2->mfc_control_RW, MFC_CNTL_SUSPEND_DMA_QUEUE); POLL_WHILE_FALSE((in_be64(&priv2->mfc_control_RW) & MFC_CNTL_SUSPEND_DMA_STATUS_MASK) == MFC_CNTL_SUSPEND_COMPLETE); - if (csa) { - csa->priv2.mfc_control_RW = 0; - } + if (csa) + csa->priv2.mfc_control_RW = + in_be64(&priv2->mfc_control_RW) & + ~MFC_CNTL_SUSPEND_DMA_QUEUE & + ~MFC_CNTL_SUSPEND_MASK; break; } } @@ -249,16 +257,21 @@ static inline void save_spu_status(struct spu_state *csa, struct spu *spu) } } -static inline void save_mfc_decr(struct spu_state *csa, struct spu *spu) +static inline void save_mfc_stopped_status(struct spu_state *csa, + struct spu *spu) { struct spu_priv2 __iomem *priv2 = spu->priv2; + const u64 mask = MFC_CNTL_DECREMENTER_RUNNING | + MFC_CNTL_DMA_QUEUES_EMPTY; /* Save, Step 12: * Read MFC_CNTL[Ds]. Update saved copy of * CSA.MFC_CNTL[Ds]. + * + * update: do the same with MFC_CNTL[Q]. */ - csa->priv2.mfc_control_RW |= - in_be64(&priv2->mfc_control_RW) & MFC_CNTL_DECREMENTER_RUNNING; + csa->priv2.mfc_control_RW &= ~mask; + csa->priv2.mfc_control_RW |= in_be64(&priv2->mfc_control_RW) & mask; } static inline void halt_mfc_decr(struct spu_state *csa, struct spu *spu) @@ -462,7 +475,9 @@ static inline void purge_mfc_queue(struct spu_state *csa, struct spu *spu) * Restore, Step 14. * Write MFC_CNTL[Pc]=1 (purge queue). */ - out_be64(&priv2->mfc_control_RW, MFC_CNTL_PURGE_DMA_REQUEST); + out_be64(&priv2->mfc_control_RW, + MFC_CNTL_PURGE_DMA_REQUEST | + MFC_CNTL_SUSPEND_MASK); eieio(); } @@ -725,10 +740,14 @@ static inline void set_switch_active(struct spu_state *csa, struct spu *spu) /* Save, Step 48: * Restore, Step 23. * Change the software context switch pending flag - * to context switch active. + * to context switch active. This implementation does + * not uses a switch active flag. * - * This implementation does not uses a switch active flag. + * Now that we have saved the mfc in the csa, we can add in the + * restart command if an exception occurred. */ + if (test_bit(SPU_CONTEXT_FAULT_PENDING, &spu->flags)) + csa->priv2.mfc_control_RW |= MFC_CNTL_RESTART_DMA_COMMAND; clear_bit(SPU_CONTEXT_SWITCH_PENDING, &spu->flags); mb(); } @@ -1690,6 +1709,13 @@ static inline void restore_mfc_sr1(struct spu_state *csa, struct spu *spu) eieio(); } +static inline void set_int_route(struct spu_state *csa, struct spu *spu) +{ + struct spu_context *ctx = spu->ctx; + + spu_cpu_affinity_set(spu, ctx->last_ran); +} + static inline void restore_other_spu_access(struct spu_state *csa, struct spu *spu) { @@ -1721,15 +1747,15 @@ static inline void restore_mfc_cntl(struct spu_state *csa, struct spu *spu) */ out_be64(&priv2->mfc_control_RW, csa->priv2.mfc_control_RW); eieio(); + /* - * FIXME: this is to restart a DMA that we were processing - * before the save. better remember the fault information - * in the csa instead. + * The queue is put back into the same state that was evident prior to + * the context switch. The suspend flag is added to the saved state in + * the csa, if the operational state was suspending or suspended. In + * this case, the code that suspended the mfc is responsible for + * continuing it. Note that SPE faults do not change the operational + * state of the spu. */ - if ((csa->priv2.mfc_control_RW & MFC_CNTL_SUSPEND_DMA_QUEUE_MASK)) { - out_be64(&priv2->mfc_control_RW, MFC_CNTL_RESTART_DMA_COMMAND); - eieio(); - } } static inline void enable_user_access(struct spu_state *csa, struct spu *spu) @@ -1788,7 +1814,7 @@ static int quiece_spu(struct spu_state *prev, struct spu *spu) save_spu_runcntl(prev, spu); /* Step 9. */ save_mfc_sr1(prev, spu); /* Step 10. */ save_spu_status(prev, spu); /* Step 11. */ - save_mfc_decr(prev, spu); /* Step 12. */ + save_mfc_stopped_status(prev, spu); /* Step 12. */ halt_mfc_decr(prev, spu); /* Step 13. */ save_timebase(prev, spu); /* Step 14. */ remove_other_spu_access(prev, spu); /* Step 15. */ @@ -2000,6 +2026,7 @@ static void restore_csa(struct spu_state *next, struct spu *spu) check_ppuint_mb_stat(next, spu); /* Step 67. */ spu_invalidate_slbs(spu); /* Modified Step 68. */ restore_mfc_sr1(next, spu); /* Step 69. */ + set_int_route(next, spu); /* NEW */ restore_other_spu_access(next, spu); /* Step 70. */ restore_spu_runcntl(next, spu); /* Step 71. */ restore_mfc_cntl(next, spu); /* Step 72. */ diff --git a/arch/powerpc/platforms/chrp/pegasos_eth.c b/arch/powerpc/platforms/chrp/pegasos_eth.c index 5bcc58d9a4dd39ad451785b36ad00d1ecb8e3e70..130ff72d99dd4366bfe5062d3842e894f04b9883 100644 --- a/arch/powerpc/platforms/chrp/pegasos_eth.c +++ b/arch/powerpc/platforms/chrp/pegasos_eth.c @@ -58,7 +58,9 @@ static struct resource mv643xx_eth0_resources[] = { static struct mv643xx_eth_platform_data eth0_pd = { + .shared = &mv643xx_eth_shared_device, .port_number = 0, + .tx_sram_addr = PEGASOS2_SRAM_BASE_ETH0, .tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE, .tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16, @@ -88,7 +90,9 @@ static struct resource mv643xx_eth1_resources[] = { }; static struct mv643xx_eth_platform_data eth1_pd = { + .shared = &mv643xx_eth_shared_device, .port_number = 1, + .tx_sram_addr = PEGASOS2_SRAM_BASE_ETH1, .tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE, .tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16, diff --git a/arch/powerpc/platforms/pasemi/misc.c b/arch/powerpc/platforms/pasemi/misc.c index ded7d152d00c2540a00dd2a43780982884435461..e0ab299763c1d665b24a0c95c12691f08163855f 100644 --- a/arch/powerpc/platforms/pasemi/misc.c +++ b/arch/powerpc/platforms/pasemi/misc.c @@ -24,12 +24,11 @@ */ struct i2c_driver_device { char *of_device; - char *i2c_driver; char *i2c_type; }; static struct i2c_driver_device i2c_devices[] __initdata = { - {"dallas,ds1338", "rtc-ds1307", "ds1338"}, + {"dallas,ds1338", "ds1338"}, }; static int __init find_i2c_driver(struct device_node *node, @@ -40,9 +39,7 @@ static int __init find_i2c_driver(struct device_node *node, for (i = 0; i < ARRAY_SIZE(i2c_devices); i++) { if (!of_device_is_compatible(node, i2c_devices[i].of_device)) continue; - if (strlcpy(info->driver_name, i2c_devices[i].i2c_driver, - KOBJ_NAME_LEN) >= KOBJ_NAME_LEN || - strlcpy(info->type, i2c_devices[i].i2c_type, + if (strlcpy(info->type, i2c_devices[i].i2c_type, I2C_NAME_SIZE) >= I2C_NAME_SIZE) return -ENOMEM; return 0; diff --git a/arch/powerpc/sysdev/mv64x60_dev.c b/arch/powerpc/sysdev/mv64x60_dev.c index 41af1223e2a0f058036d7c4a11af9cf8d5a21937..a132e0de8ca5a056ac1f7803c7fe5925a037cf31 100644 --- a/arch/powerpc/sysdev/mv64x60_dev.c +++ b/arch/powerpc/sysdev/mv64x60_dev.c @@ -239,6 +239,8 @@ static int __init mv64x60_eth_device_setup(struct device_node *np, int id, memset(&pdata, 0, sizeof(pdata)); + pdata.shared = shared_pdev; + prop = of_get_property(np, "reg", NULL); if (!prop) return -ENODEV; diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c index 1814adbd22363c13f79f8e2744f41cf9f14e1f5d..b4a54c52e8805cac1fb32af31d85d0168ff41bda 100644 --- a/arch/powerpc/sysdev/ppc4xx_pci.c +++ b/arch/powerpc/sysdev/ppc4xx_pci.c @@ -1387,28 +1387,59 @@ static void __init ppc4xx_configure_pciex_PIMs(struct ppc4xx_pciex_port *port, resource_size_t size = res->end - res->start + 1; u64 sa; - /* Calculate window size */ - sa = (0xffffffffffffffffull << ilog2(size));; - if (res->flags & IORESOURCE_PREFETCH) - sa |= 0x8; + if (port->endpoint) { + resource_size_t ep_addr = 0; + resource_size_t ep_size = 32 << 20; + + /* Currently we map a fixed 64MByte window to PLB address + * 0 (SDRAM). This should probably be configurable via a dts + * property. + */ + + /* Calculate window size */ + sa = (0xffffffffffffffffull << ilog2(ep_size));; + + /* Setup BAR0 */ + out_le32(mbase + PECFG_BAR0HMPA, RES_TO_U32_HIGH(sa)); + out_le32(mbase + PECFG_BAR0LMPA, RES_TO_U32_LOW(sa) | + PCI_BASE_ADDRESS_MEM_TYPE_64); - out_le32(mbase + PECFG_BAR0HMPA, RES_TO_U32_HIGH(sa)); - out_le32(mbase + PECFG_BAR0LMPA, RES_TO_U32_LOW(sa)); + /* Disable BAR1 & BAR2 */ + out_le32(mbase + PECFG_BAR1MPA, 0); + out_le32(mbase + PECFG_BAR2HMPA, 0); + out_le32(mbase + PECFG_BAR2LMPA, 0); - /* The setup of the split looks weird to me ... let's see if it works */ - out_le32(mbase + PECFG_PIM0LAL, 0x00000000); - out_le32(mbase + PECFG_PIM0LAH, 0x00000000); - out_le32(mbase + PECFG_PIM1LAL, 0x00000000); - out_le32(mbase + PECFG_PIM1LAH, 0x00000000); - out_le32(mbase + PECFG_PIM01SAH, 0xffff0000); - out_le32(mbase + PECFG_PIM01SAL, 0x00000000); + out_le32(mbase + PECFG_PIM01SAH, RES_TO_U32_HIGH(sa)); + out_le32(mbase + PECFG_PIM01SAL, RES_TO_U32_LOW(sa)); + + out_le32(mbase + PCI_BASE_ADDRESS_0, RES_TO_U32_LOW(ep_addr)); + out_le32(mbase + PCI_BASE_ADDRESS_1, RES_TO_U32_HIGH(ep_addr)); + } else { + /* Calculate window size */ + sa = (0xffffffffffffffffull << ilog2(size));; + if (res->flags & IORESOURCE_PREFETCH) + sa |= 0x8; + + out_le32(mbase + PECFG_BAR0HMPA, RES_TO_U32_HIGH(sa)); + out_le32(mbase + PECFG_BAR0LMPA, RES_TO_U32_LOW(sa)); + + /* The setup of the split looks weird to me ... let's see + * if it works + */ + out_le32(mbase + PECFG_PIM0LAL, 0x00000000); + out_le32(mbase + PECFG_PIM0LAH, 0x00000000); + out_le32(mbase + PECFG_PIM1LAL, 0x00000000); + out_le32(mbase + PECFG_PIM1LAH, 0x00000000); + out_le32(mbase + PECFG_PIM01SAH, 0xffff0000); + out_le32(mbase + PECFG_PIM01SAL, 0x00000000); + + out_le32(mbase + PCI_BASE_ADDRESS_0, RES_TO_U32_LOW(res->start)); + out_le32(mbase + PCI_BASE_ADDRESS_1, RES_TO_U32_HIGH(res->start)); + } /* Enable inbound mapping */ out_le32(mbase + PECFG_PIMEN, 0x1); - out_le32(mbase + PCI_BASE_ADDRESS_0, RES_TO_U32_LOW(res->start)); - out_le32(mbase + PCI_BASE_ADDRESS_1, RES_TO_U32_HIGH(res->start)); - /* Enable I/O, Mem, and Busmaster cycles */ out_le16(mbase + PCI_COMMAND, in_le16(mbase + PCI_COMMAND) | @@ -1422,13 +1453,8 @@ static void __init ppc4xx_pciex_port_setup_hose(struct ppc4xx_pciex_port *port) const int *bus_range; int primary = 0, busses; void __iomem *mbase = NULL, *cfg_data = NULL; - - /* XXX FIXME: Handle endpoint mode properly */ - if (port->endpoint) { - printk(KERN_WARNING "PCIE%d: Port in endpoint mode !\n", - port->index); - return; - } + const u32 *pval; + u32 val; /* Check if primary bridge */ if (of_get_property(port->node, "primary", NULL)) @@ -1462,21 +1488,30 @@ static void __init ppc4xx_pciex_port_setup_hose(struct ppc4xx_pciex_port *port) hose->last_busno = hose->first_busno + busses; } - /* We map the external config space in cfg_data and the host config - * space in cfg_addr. External space is 1M per bus, internal space - * is 4K + if (!port->endpoint) { + /* Only map the external config space in cfg_data for + * PCIe root-complexes. External space is 1M per bus + */ + cfg_data = ioremap(port->cfg_space.start + + (hose->first_busno + 1) * 0x100000, + busses * 0x100000); + if (cfg_data == NULL) { + printk(KERN_ERR "%s: Can't map external config space !", + port->node->full_name); + goto fail; + } + hose->cfg_data = cfg_data; + } + + /* Always map the host config space in cfg_addr. + * Internal space is 4K */ - cfg_data = ioremap(port->cfg_space.start + - (hose->first_busno + 1) * 0x100000, - busses * 0x100000); mbase = ioremap(port->cfg_space.start + 0x10000000, 0x1000); - if (cfg_data == NULL || mbase == NULL) { - printk(KERN_ERR "%s: Can't map config space !", + if (mbase == NULL) { + printk(KERN_ERR "%s: Can't map internal config space !", port->node->full_name); goto fail; } - - hose->cfg_data = cfg_data; hose->cfg_addr = mbase; pr_debug("PCIE %s, bus %d..%d\n", port->node->full_name, @@ -1489,12 +1524,14 @@ static void __init ppc4xx_pciex_port_setup_hose(struct ppc4xx_pciex_port *port) port->hose = hose; mbase = (void __iomem *)hose->cfg_addr; - /* - * Set bus numbers on our root port - */ - out_8(mbase + PCI_PRIMARY_BUS, hose->first_busno); - out_8(mbase + PCI_SECONDARY_BUS, hose->first_busno + 1); - out_8(mbase + PCI_SUBORDINATE_BUS, hose->last_busno); + if (!port->endpoint) { + /* + * Set bus numbers on our root port + */ + out_8(mbase + PCI_PRIMARY_BUS, hose->first_busno); + out_8(mbase + PCI_SECONDARY_BUS, hose->first_busno + 1); + out_8(mbase + PCI_SUBORDINATE_BUS, hose->last_busno); + } /* * OMRs are already reset, also disable PIMs @@ -1515,17 +1552,49 @@ static void __init ppc4xx_pciex_port_setup_hose(struct ppc4xx_pciex_port *port) ppc4xx_configure_pciex_PIMs(port, hose, mbase, &dma_window); /* The root complex doesn't show up if we don't set some vendor - * and device IDs into it. Those are the same bogus one that the - * initial code in arch/ppc add. We might want to change that. + * and device IDs into it. The defaults below are the same bogus + * one that the initial code in arch/ppc had. This can be + * overwritten by setting the "vendor-id/device-id" properties + * in the pciex node. */ - out_le16(mbase + 0x200, 0xaaa0 + port->index); - out_le16(mbase + 0x202, 0xbed0 + port->index); - /* Set Class Code to PCI-PCI bridge and Revision Id to 1 */ - out_le32(mbase + 0x208, 0x06040001); + /* Get the (optional) vendor-/device-id from the device-tree */ + pval = of_get_property(port->node, "vendor-id", NULL); + if (pval) { + val = *pval; + } else { + if (!port->endpoint) + val = 0xaaa0 + port->index; + else + val = 0xeee0 + port->index; + } + out_le16(mbase + 0x200, val); + + pval = of_get_property(port->node, "device-id", NULL); + if (pval) { + val = *pval; + } else { + if (!port->endpoint) + val = 0xbed0 + port->index; + else + val = 0xfed0 + port->index; + } + out_le16(mbase + 0x202, val); + + if (!port->endpoint) { + /* Set Class Code to PCI-PCI bridge and Revision Id to 1 */ + out_le32(mbase + 0x208, 0x06040001); + + printk(KERN_INFO "PCIE%d: successfully set as root-complex\n", + port->index); + } else { + /* Set Class Code to Processor/PPC */ + out_le32(mbase + 0x208, 0x0b200001); + + printk(KERN_INFO "PCIE%d: successfully set as endpoint\n", + port->index); + } - printk(KERN_INFO "PCIE%d: successfully set as root-complex\n", - port->index); return; fail: if (hose) @@ -1542,6 +1611,7 @@ static void __init ppc4xx_probe_pciex_bridge(struct device_node *np) const u32 *pval; int portno; unsigned int dcrs; + const char *val; /* First, proceed to core initialization as we assume there's * only one PCIe core in the system @@ -1573,8 +1643,20 @@ static void __init ppc4xx_probe_pciex_bridge(struct device_node *np) } port->sdr_base = *pval; - /* XXX Currently, we only support root complex mode */ - port->endpoint = 0; + /* Check if device_type property is set to "pci" or "pci-endpoint". + * Resulting from this setup this PCIe port will be configured + * as root-complex or as endpoint. + */ + val = of_get_property(port->node, "device_type", NULL); + if (!strcmp(val, "pci-endpoint")) { + port->endpoint = 1; + } else if (!strcmp(val, "pci")) { + port->endpoint = 0; + } else { + printk(KERN_ERR "PCIE: missing or incorrect device_type for %s\n", + np->full_name); + return; + } /* Fetch config space registers address */ if (of_address_to_resource(np, 0, &port->cfg_space)) { diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 52c74780f403c420c47bbcf13640173b6992852e..1702de9395eeee96b02d686e20550dbc98b8d63d 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -2842,9 +2842,11 @@ static void dump_spu_fields(struct spu *spu) DUMP_FIELD(spu, "0x%lx", ls_size); DUMP_FIELD(spu, "0x%x", node); DUMP_FIELD(spu, "0x%lx", flags); - DUMP_FIELD(spu, "0x%lx", dar); - DUMP_FIELD(spu, "0x%lx", dsisr); DUMP_FIELD(spu, "%d", class_0_pending); + DUMP_FIELD(spu, "0x%lx", class_0_dar); + DUMP_FIELD(spu, "0x%lx", class_0_dsisr); + DUMP_FIELD(spu, "0x%lx", class_1_dar); + DUMP_FIELD(spu, "0x%lx", class_1_dsisr); DUMP_FIELD(spu, "0x%lx", irqs[0]); DUMP_FIELD(spu, "0x%lx", irqs[1]); DUMP_FIELD(spu, "0x%lx", irqs[2]); diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile index 8df7f0e4c3a62ee245ca120355c3545d944d793f..2352d139b262bd378434987782bf1c5b0592404c 100644 --- a/arch/ppc/Makefile +++ b/arch/ppc/Makefile @@ -43,7 +43,7 @@ KBUILD_AFLAGS += $(cpu-as-y) KBUILD_CFLAGS += $(cpu-as-y) # Default to the common case. -KBUILD_DEFCONFIG := common_defconfig +KBUILD_DEFCONFIG := ebony_defconfig head-y := arch/ppc/kernel/head.o head-$(CONFIG_8xx) := arch/ppc/kernel/head_8xx.o diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c index 16ac11ca7ba0feb0b022fc8093a21bcf6cae4f61..602c268fc8a2875ae55f5c51ddbbf59f510d4838 100644 --- a/arch/ppc/kernel/ppc_ksyms.c +++ b/arch/ppc/kernel/ppc_ksyms.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c index bfddfdee0b6592867d3801b8c3500c55e76f3d33..51e8094f52d6e9f46f5ff71a806de653db578a4a 100644 --- a/arch/ppc/kernel/setup.c +++ b/arch/ppc/kernel/setup.c @@ -36,6 +36,7 @@ #include #include #include +#include #define USES_PPC_SYS (defined(CONFIG_MPC10X_BRIDGE) || defined(CONFIG_8260) || \ defined(CONFIG_PPC_MPC52xx)) diff --git a/arch/ppc/platforms/residual.c b/arch/ppc/platforms/residual.c index 18495e754e3086be415af6e69f86f927fd4ce978..d687b0f8763b20750b1f2de574836c87db968376 100644 --- a/arch/ppc/platforms/residual.c +++ b/arch/ppc/platforms/residual.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include diff --git a/arch/ppc/syslib/mv64x60.c b/arch/ppc/syslib/mv64x60.c index 90fe904d36141623c5f81f922647b4ac96af171a..418f3053de529274fb996fc61c731a8ee2efa1a2 100644 --- a/arch/ppc/syslib/mv64x60.c +++ b/arch/ppc/syslib/mv64x60.c @@ -341,6 +341,7 @@ static struct resource mv64x60_eth0_resources[] = { }; static struct mv643xx_eth_platform_data eth0_pd = { + .shared = &mv64x60_eth_shared_device; .port_number = 0, }; @@ -366,6 +367,7 @@ static struct resource mv64x60_eth1_resources[] = { }; static struct mv643xx_eth_platform_data eth1_pd = { + .shared = &mv64x60_eth_shared_device; .port_number = 1, }; @@ -391,6 +393,7 @@ static struct resource mv64x60_eth2_resources[] = { }; static struct mv643xx_eth_platform_data eth2_pd = { + .shared = &mv64x60_eth_shared_device; .port_number = 2, }; diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 29a7940f284f62fa1f9e27508bc7d55f9b50aca4..1d035082e78eb15fc73f8f3b7b939af19eaa23ba 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -430,6 +430,13 @@ config CMM_IUCV Select this option to enable the special message interface to the cooperative memory management. +config PAGE_STATES + bool "Unused page notification" + help + This enables the notification of unused pages to the + hypervisor. The ESSA instruction is used to do the states + changes between a page that has content and the unused state. + config VIRT_TIMER bool "Virtual CPU timer support" help diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index 743d54f0b8dbb01e93c17f51be274bece0005f48..d003a6e16afb807df2ecbbcc6066de49f0784c33 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -121,7 +121,7 @@ sys32_ptrace_wrapper: lgfr %r3,%r3 # long llgtr %r4,%r4 # long llgfr %r5,%r5 # long - jg sys_ptrace # branch to system call + jg compat_sys_ptrace # branch to system call .globl sys32_alarm_wrapper sys32_alarm_wrapper: diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c index dff0568e67ec8869fa427b7769b0ca329b561650..c93d1296cc0a7eeff66feaa20e9666bb5e31b6fa 100644 --- a/arch/s390/kernel/debug.c +++ b/arch/s390/kernel/debug.c @@ -71,7 +71,7 @@ static ssize_t debug_input(struct file *file, const char __user *user_buf, size_t user_len, loff_t * offset); static int debug_open(struct inode *inode, struct file *file); static int debug_close(struct inode *inode, struct file *file); -static debug_info_t* debug_info_create(char *name, int pages_per_area, +static debug_info_t *debug_info_create(const char *name, int pages_per_area, int nr_areas, int buf_size, mode_t mode); static void debug_info_get(debug_info_t *); static void debug_info_put(debug_info_t *); @@ -234,8 +234,8 @@ fail_malloc_areas: */ static debug_info_t* -debug_info_alloc(char *name, int pages_per_area, int nr_areas, int buf_size, - int level, int mode) +debug_info_alloc(const char *name, int pages_per_area, int nr_areas, + int buf_size, int level, int mode) { debug_info_t* rc; @@ -326,8 +326,8 @@ debug_info_free(debug_info_t* db_info){ */ static debug_info_t* -debug_info_create(char *name, int pages_per_area, int nr_areas, int buf_size, - mode_t mode) +debug_info_create(const char *name, int pages_per_area, int nr_areas, + int buf_size, mode_t mode) { debug_info_t* rc; @@ -684,9 +684,9 @@ debug_close(struct inode *inode, struct file *file) * - Returns handle for debug area */ -debug_info_t *debug_register_mode(char *name, int pages_per_area, int nr_areas, - int buf_size, mode_t mode, uid_t uid, - gid_t gid) +debug_info_t *debug_register_mode(const char *name, int pages_per_area, + int nr_areas, int buf_size, mode_t mode, + uid_t uid, gid_t gid) { debug_info_t *rc = NULL; @@ -722,8 +722,8 @@ EXPORT_SYMBOL(debug_register_mode); * - returns handle for debug area */ -debug_info_t *debug_register(char *name, int pages_per_area, int nr_areas, - int buf_size) +debug_info_t *debug_register(const char *name, int pages_per_area, + int nr_areas, int buf_size) { return debug_register_mode(name, pages_per_area, nr_areas, buf_size, S_IRUSR | S_IWUSR, 0, 0); diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index bdbb3bcd78a5d7088ed4cfd39f7fb444e2f15814..708cf9cf9a355e175d5b1cf4fbdc2b96732e7084 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -279,8 +279,6 @@ sysc_do_restart: st %r2,SP_R2(%r15) # store return value (change R2 on stack) sysc_return: - tm SP_PSW+1(%r15),0x01 # returning to user ? - bno BASED(sysc_restore) tm __TI_flags+3(%r9),_TIF_WORK_SVC bnz BASED(sysc_work) # there is work to do (signals etc.) sysc_restore: @@ -312,6 +310,8 @@ sysc_work_loop: # One of the work bits is on. Find out which one. # sysc_work: + tm SP_PSW+1(%r15),0x01 # returning to user ? + bno BASED(sysc_restore) tm __TI_flags+3(%r9),_TIF_MCCK_PENDING bo BASED(sysc_mcck_pending) tm __TI_flags+3(%r9),_TIF_NEED_RESCHED @@ -602,12 +602,6 @@ io_no_vtime: la %r2,SP_PTREGS(%r15) # address of register-save area basr %r14,%r1 # branch to standard irq handler io_return: - tm SP_PSW+1(%r15),0x01 # returning to user ? -#ifdef CONFIG_PREEMPT - bno BASED(io_preempt) # no -> check for preemptive scheduling -#else - bno BASED(io_restore) # no-> skip resched & signal -#endif tm __TI_flags+3(%r9),_TIF_WORK_INT bnz BASED(io_work) # there is work to do (signals etc.) io_restore: @@ -629,10 +623,18 @@ io_restore_trace_psw: .long 0, io_restore_trace + 0x80000000 #endif -#ifdef CONFIG_PREEMPT -io_preempt: +# +# switch to kernel stack, then check the TIF bits +# +io_work: + tm SP_PSW+1(%r15),0x01 # returning to user ? +#ifndef CONFIG_PREEMPT + bno BASED(io_restore) # no-> skip resched & signal +#else + bnz BASED(io_work_user) # no -> check for preemptive scheduling + # check for preemptive scheduling icm %r0,15,__TI_precount(%r9) - bnz BASED(io_restore) + bnz BASED(io_restore) # preemption disabled l %r1,SP_R15(%r15) s %r1,BASED(.Lc_spsize) mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) @@ -646,10 +648,7 @@ io_resume_loop: br %r1 # call schedule #endif -# -# switch to kernel stack, then check the TIF bits -# -io_work: +io_work_user: l %r1,__LC_KERNEL_STACK s %r1,BASED(.Lc_spsize) mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index 5a4a7bcd2bbad8e92e95eb529fb11559977c0dd9..fee10177dbfcf67a175c7d82f1839886ef509ff4 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S @@ -271,8 +271,6 @@ sysc_noemu: stg %r2,SP_R2(%r15) # store return value (change R2 on stack) sysc_return: - tm SP_PSW+1(%r15),0x01 # returning to user ? - jno sysc_restore tm __TI_flags+7(%r9),_TIF_WORK_SVC jnz sysc_work # there is work to do (signals etc.) sysc_restore: @@ -304,6 +302,8 @@ sysc_work_loop: # One of the work bits is on. Find out which one. # sysc_work: + tm SP_PSW+1(%r15),0x01 # returning to user ? + jno sysc_restore tm __TI_flags+7(%r9),_TIF_MCCK_PENDING jo sysc_mcck_pending tm __TI_flags+7(%r9),_TIF_NEED_RESCHED @@ -585,12 +585,6 @@ io_no_vtime: la %r2,SP_PTREGS(%r15) # address of register-save area brasl %r14,do_IRQ # call standard irq handler io_return: - tm SP_PSW+1(%r15),0x01 # returning to user ? -#ifdef CONFIG_PREEMPT - jno io_preempt # no -> check for preemptive scheduling -#else - jno io_restore # no-> skip resched & signal -#endif tm __TI_flags+7(%r9),_TIF_WORK_INT jnz io_work # there is work to do (signals etc.) io_restore: @@ -612,10 +606,41 @@ io_restore_trace_psw: .quad 0, io_restore_trace #endif -#ifdef CONFIG_PREEMPT -io_preempt: +# +# There is work todo, we need to check if we return to userspace, then +# check, if we are in SIE, if yes leave it +# +io_work: + tm SP_PSW+1(%r15),0x01 # returning to user ? +#ifndef CONFIG_PREEMPT +#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) + jnz io_work_user # yes -> no need to check for SIE + la %r1, BASED(sie_opcode) # we return to kernel here + lg %r2, SP_PSW+8(%r15) + clc 0(2,%r1), 0(%r2) # is current instruction = SIE? + jne io_restore # no-> return to kernel + lg %r1, SP_PSW+8(%r15) # yes-> add 4 bytes to leave SIE + aghi %r1, 4 + stg %r1, SP_PSW+8(%r15) + j io_restore # return to kernel +#else + jno io_restore # no-> skip resched & signal +#endif +#else + jnz io_work_user # yes -> do resched & signal +#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) + la %r1, BASED(sie_opcode) + lg %r2, SP_PSW+8(%r15) + clc 0(2,%r1), 0(%r2) # is current instruction = SIE? + jne 0f # no -> leave PSW alone + lg %r1, SP_PSW+8(%r15) # yes-> add 4 bytes to leave SIE + aghi %r1, 4 + stg %r1, SP_PSW+8(%r15) +0: +#endif + # check for preemptive scheduling icm %r0,15,__TI_precount(%r9) - jnz io_restore + jnz io_restore # preemption is disabled # switch to kernel stack lg %r1,SP_R15(%r15) aghi %r1,-SP_SIZE @@ -629,10 +654,7 @@ io_resume_loop: jg preempt_schedule_irq #endif -# -# switch to kernel stack, then check TIF bits -# -io_work: +io_work_user: lg %r1,__LC_KERNEL_STACK aghi %r1,-SP_SIZE mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) @@ -653,6 +675,11 @@ io_work_loop: j io_restore io_work_done: +#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) +sie_opcode: + .long 0xb2140000 +#endif + # # _TIF_MCCK_PENDING is set, call handler # diff --git a/arch/s390/kernel/init_task.c b/arch/s390/kernel/init_task.c index d494161b05b40125668709c893d3407432dbb971..7ad003969251f159cb7f5d6ab0cfaac62c9eb113 100644 --- a/arch/s390/kernel/init_task.c +++ b/arch/s390/kernel/init_task.c @@ -17,7 +17,6 @@ #include static struct fs_struct init_fs = INIT_FS; -static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS(init_signals); static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); struct mm_struct init_mm = INIT_MM(init_mm); diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c index c59a86dca5849617ac74428647fe3ddb7834937e..e7c5bfb7c755acf812f563a6c4d2986843fcbd04 100644 --- a/arch/s390/kernel/irq.c +++ b/arch/s390/kernel/irq.c @@ -25,6 +25,7 @@ int show_interrupts(struct seq_file *p, void *v) static const char *intrclass_names[] = { "EXT", "I/O", }; int i = *(loff_t *) v, j; + get_online_cpus(); if (i == 0) { seq_puts(p, " "); for_each_online_cpu(j) @@ -43,7 +44,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_putc(p, '\n'); } - + put_online_cpus(); return 0; } diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index 7f4270163744b1ea5af37b6a68ca69e2cef89437..35827b9bd4d1827f102f79f3e999bbb69c52f5ab 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c @@ -292,8 +292,7 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data) return 0; } -static int -do_ptrace_normal(struct task_struct *child, long request, long addr, long data) +long arch_ptrace(struct task_struct *child, long request, long addr, long data) { ptrace_area parea; int copied, ret; @@ -529,35 +528,19 @@ poke_user_emu31(struct task_struct *child, addr_t addr, addr_t data) return 0; } -static int -do_ptrace_emu31(struct task_struct *child, long request, long addr, long data) +long compat_arch_ptrace(struct task_struct *child, compat_long_t request, + compat_ulong_t caddr, compat_ulong_t cdata) { - unsigned int tmp; /* 4 bytes !! */ + unsigned long addr = caddr; + unsigned long data = cdata; ptrace_area_emu31 parea; int copied, ret; switch (request) { - case PTRACE_PEEKTEXT: - case PTRACE_PEEKDATA: - /* read word at location addr. */ - copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0); - if (copied != sizeof(tmp)) - return -EIO; - return put_user(tmp, (unsigned int __force __user *) data); - case PTRACE_PEEKUSR: /* read the word at location addr in the USER area. */ return peek_user_emu31(child, addr, data); - case PTRACE_POKETEXT: - case PTRACE_POKEDATA: - /* write the word at location addr. */ - tmp = data; - copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 1); - if (copied != sizeof(tmp)) - return -EIO; - return 0; - case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ return poke_user_emu31(child, addr, data); @@ -587,82 +570,11 @@ do_ptrace_emu31(struct task_struct *child, long request, long addr, long data) copied += sizeof(unsigned int); } return 0; - case PTRACE_GETEVENTMSG: - return put_user((__u32) child->ptrace_message, - (unsigned int __force __user *) data); - case PTRACE_GETSIGINFO: - if (child->last_siginfo == NULL) - return -EINVAL; - return copy_siginfo_to_user32((compat_siginfo_t - __force __user *) data, - child->last_siginfo); - case PTRACE_SETSIGINFO: - if (child->last_siginfo == NULL) - return -EINVAL; - return copy_siginfo_from_user32(child->last_siginfo, - (compat_siginfo_t - __force __user *) data); } - return ptrace_request(child, request, addr, data); + return compat_ptrace_request(child, request, addr, data); } #endif -long arch_ptrace(struct task_struct *child, long request, long addr, long data) -{ - switch (request) { - case PTRACE_SYSCALL: - /* continue and stop at next (return from) syscall */ - case PTRACE_CONT: - /* restart after signal. */ - if (!valid_signal(data)) - return -EIO; - if (request == PTRACE_SYSCALL) - set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); - else - clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); - child->exit_code = data; - /* make sure the single step bit is not set. */ - user_disable_single_step(child); - wake_up_process(child); - return 0; - - case PTRACE_KILL: - /* - * make the child exit. Best I can do is send it a sigkill. - * perhaps it should be put in the status that it wants to - * exit. - */ - if (child->exit_state == EXIT_ZOMBIE) /* already dead */ - return 0; - child->exit_code = SIGKILL; - /* make sure the single step bit is not set. */ - user_disable_single_step(child); - wake_up_process(child); - return 0; - - case PTRACE_SINGLESTEP: - /* set the trap flag. */ - if (!valid_signal(data)) - return -EIO; - clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); - child->exit_code = data; - user_enable_single_step(child); - /* give it a chance to run. */ - wake_up_process(child); - return 0; - - /* Do requests that differ for 31/64 bit */ - default: -#ifdef CONFIG_COMPAT - if (test_thread_flag(TIF_31BIT)) - return do_ptrace_emu31(child, request, addr, data); -#endif - return do_ptrace_normal(child, request, addr, data); - } - /* Not reached. */ - return -EIO; -} - asmlinkage void syscall_trace(struct pt_regs *regs, int entryexit) { diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 0aeb290060d9cb379532568880dc4d408b0ac01c..1f4228948dc4396ad19c5bc1f771d13f3b19286d 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -139,7 +139,6 @@ static void __smp_call_function_map(void (*func) (void *info), void *info, if (wait) data.finished = CPU_MASK_NONE; - spin_lock(&call_lock); call_data = &data; for_each_cpu_mask(cpu, map) @@ -151,7 +150,6 @@ static void __smp_call_function_map(void (*func) (void *info), void *info, if (wait) while (!cpus_equal(map, data.finished)) cpu_relax(); - spin_unlock(&call_lock); out: if (local) { local_irq_disable(); @@ -177,11 +175,11 @@ int smp_call_function(void (*func) (void *info), void *info, int nonatomic, { cpumask_t map; - preempt_disable(); + spin_lock(&call_lock); map = cpu_online_map; cpu_clear(smp_processor_id(), map); __smp_call_function_map(func, info, nonatomic, wait, map); - preempt_enable(); + spin_unlock(&call_lock); return 0; } EXPORT_SYMBOL(smp_call_function); @@ -202,10 +200,10 @@ EXPORT_SYMBOL(smp_call_function); int smp_call_function_single(int cpu, void (*func) (void *info), void *info, int nonatomic, int wait) { - preempt_disable(); + spin_lock(&call_lock); __smp_call_function_map(func, info, nonatomic, wait, cpumask_of_cpu(cpu)); - preempt_enable(); + spin_unlock(&call_lock); return 0; } EXPORT_SYMBOL(smp_call_function_single); @@ -228,10 +226,10 @@ EXPORT_SYMBOL(smp_call_function_single); int smp_call_function_mask(cpumask_t mask, void (*func)(void *), void *info, int wait) { - preempt_disable(); + spin_lock(&call_lock); cpu_clear(smp_processor_id(), mask); __smp_call_function_map(func, info, 0, wait, mask); - preempt_enable(); + spin_unlock(&call_lock); return 0; } EXPORT_SYMBOL(smp_call_function_mask); @@ -592,7 +590,9 @@ int __cpuinit start_secondary(void *cpuvoid) pfault_init(); /* Mark this cpu as online */ + spin_lock(&call_lock); cpu_set(smp_processor_id(), cpu_online_map); + spin_unlock(&call_lock); /* Switch on interrupts */ local_irq_enable(); /* Print info about this processor */ diff --git a/arch/s390/kvm/Kconfig b/arch/s390/kvm/Kconfig index 1761b74d639be88e3fbc870cda7a4942c7b50ac9..e051cad1f1e09d9f880b91f0d23b7738e10a5a57 100644 --- a/arch/s390/kvm/Kconfig +++ b/arch/s390/kvm/Kconfig @@ -22,7 +22,6 @@ config KVM select PREEMPT_NOTIFIERS select ANON_INODES select S390_SWITCH_AMODE - select PREEMPT ---help--- Support hosting paravirtualized guest machines using the SIE virtualization capability on the mainframe. This should work diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c index 349581a2610344f23c1af6873dc57d6c23761b47..47a0b642174c1ef807ca5d16774f9d10c6584197 100644 --- a/arch/s390/kvm/intercept.c +++ b/arch/s390/kvm/intercept.c @@ -105,6 +105,9 @@ static intercept_handler_t instruction_handlers[256] = { static int handle_noop(struct kvm_vcpu *vcpu) { switch (vcpu->arch.sie_block->icptcode) { + case 0x0: + vcpu->stat.exit_null++; + break; case 0x10: vcpu->stat.exit_external_request++; break; diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 98d1e73e01f11f31cdac4d693f54c1bfddedc871..0ac36a649eba9a2823189d3bb31dcb68b0ec6055 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -31,6 +31,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { { "userspace_handled", VCPU_STAT(exit_userspace) }, + { "exit_null", VCPU_STAT(exit_null) }, { "exit_validity", VCPU_STAT(exit_validity) }, { "exit_stop_request", VCPU_STAT(exit_stop_request) }, { "exit_external_request", VCPU_STAT(exit_external_request) }, @@ -221,10 +222,6 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) vcpu->arch.guest_fpregs.fpc &= FPC_VALID_MASK; restore_fp_regs(&vcpu->arch.guest_fpregs); restore_access_regs(vcpu->arch.guest_acrs); - - if (signal_pending(current)) - atomic_set_mask(CPUSTAT_STOP_INT, - &vcpu->arch.sie_block->cpuflags); } void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) diff --git a/arch/s390/mm/Makefile b/arch/s390/mm/Makefile index fb988a48a754ff541d161ba341a108e10a2a15e1..2a745813454410cb35ff525e837efc9f29c0dd95 100644 --- a/arch/s390/mm/Makefile +++ b/arch/s390/mm/Makefile @@ -5,3 +5,4 @@ obj-y := init.o fault.o extmem.o mmap.o vmem.o pgtable.o obj-$(CONFIG_CMM) += cmm.o obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o +obj-$(CONFIG_PAGE_STATES) += page-states.o diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index fa31de6ae97aef1577b99d0f9afb04cf257334ce..29f3a63806b976ee8847dd3efd84292697ba53db 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c @@ -126,6 +126,9 @@ void __init mem_init(void) /* clear the zero-page */ memset(empty_zero_page, 0, PAGE_SIZE); + /* Setup guest page hinting */ + cmma_init(); + /* this will put all low memory onto the freelists */ totalram_pages += free_all_bootmem(); diff --git a/arch/s390/mm/page-states.c b/arch/s390/mm/page-states.c new file mode 100644 index 0000000000000000000000000000000000000000..fc0ad73ffd902ec243bbb06de79eff7428132d95 --- /dev/null +++ b/arch/s390/mm/page-states.c @@ -0,0 +1,79 @@ +/* + * arch/s390/mm/page-states.c + * + * Copyright IBM Corp. 2008 + * + * Guest page hinting for unused pages. + * + * Author(s): Martin Schwidefsky + */ + +#include +#include +#include +#include +#include + +#define ESSA_SET_STABLE 1 +#define ESSA_SET_UNUSED 2 + +static int cmma_flag; + +static int __init cmma(char *str) +{ + char *parm; + parm = strstrip(str); + if (strcmp(parm, "yes") == 0 || strcmp(parm, "on") == 0) { + cmma_flag = 1; + return 1; + } + cmma_flag = 0; + if (strcmp(parm, "no") == 0 || strcmp(parm, "off") == 0) + return 1; + return 0; +} + +__setup("cmma=", cmma); + +void __init cmma_init(void) +{ + register unsigned long tmp asm("0") = 0; + register int rc asm("1") = -EOPNOTSUPP; + + if (!cmma_flag) + return; + asm volatile( + " .insn rrf,0xb9ab0000,%1,%1,0,0\n" + "0: la %0,0\n" + "1:\n" + EX_TABLE(0b,1b) + : "+&d" (rc), "+&d" (tmp)); + if (rc) + cmma_flag = 0; +} + +void arch_free_page(struct page *page, int order) +{ + int i, rc; + + if (!cmma_flag) + return; + for (i = 0; i < (1 << order); i++) + asm volatile(".insn rrf,0xb9ab0000,%0,%1,%2,0" + : "=&d" (rc) + : "a" ((page_to_pfn(page) + i) << PAGE_SHIFT), + "i" (ESSA_SET_UNUSED)); +} + +void arch_alloc_page(struct page *page, int order) +{ + int i, rc; + + if (!cmma_flag) + return; + for (i = 0; i < (1 << order); i++) + asm volatile(".insn rrf,0xb9ab0000,%0,%1,%2,0" + : "=&d" (rc) + : "a" ((page_to_pfn(page) + i) << PAGE_SHIFT), + "i" (ESSA_SET_STABLE)); +} diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c index beccacf907f3481190b10496cad77a1bb4d1d23f..ea2804808f39a98c368637b75a060431fd750d54 100644 --- a/arch/s390/mm/vmem.c +++ b/arch/s390/mm/vmem.c @@ -27,19 +27,12 @@ struct memory_segment { static LIST_HEAD(mem_segs); -static void __ref *vmem_alloc_pages(unsigned int order) -{ - if (slab_is_available()) - return (void *)__get_free_pages(GFP_KERNEL, order); - return alloc_bootmem_pages((1 << order) * PAGE_SIZE); -} - -static inline pud_t *vmem_pud_alloc(void) +static pud_t *vmem_pud_alloc(void) { pud_t *pud = NULL; #ifdef CONFIG_64BIT - pud = vmem_alloc_pages(2); + pud = vmemmap_alloc_block(PAGE_SIZE * 4, 0); if (!pud) return NULL; clear_table((unsigned long *) pud, _REGION3_ENTRY_EMPTY, PAGE_SIZE * 4); @@ -47,12 +40,12 @@ static inline pud_t *vmem_pud_alloc(void) return pud; } -static inline pmd_t *vmem_pmd_alloc(void) +static pmd_t *vmem_pmd_alloc(void) { pmd_t *pmd = NULL; #ifdef CONFIG_64BIT - pmd = vmem_alloc_pages(2); + pmd = vmemmap_alloc_block(PAGE_SIZE * 4, 0); if (!pmd) return NULL; clear_table((unsigned long *) pmd, _SEGMENT_ENTRY_EMPTY, PAGE_SIZE * 4); @@ -60,7 +53,7 @@ static inline pmd_t *vmem_pmd_alloc(void) return pmd; } -static pte_t __init_refok *vmem_pte_alloc(void) +static pte_t __ref *vmem_pte_alloc(void) { pte_t *pte; @@ -214,7 +207,7 @@ int __meminit vmemmap_populate(struct page *start, unsigned long nr, int node) if (pte_none(*pt_dir)) { unsigned long new_page; - new_page =__pa(vmem_alloc_pages(0)); + new_page =__pa(vmemmap_alloc_block(PAGE_SIZE, 0)); if (!new_page) goto out; pte = pfn_pte(new_page >> PAGE_SHIFT, PAGE_KERNEL); diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 6a679c3e15e817d14adcee8d6771c9e3c89e5b30..8a68160079a90cb5c77411f410960d59899abd5a 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -448,14 +448,6 @@ config SH_DREAMCAST Select Dreamcast if configuring for a SEGA Dreamcast. More information at -config SH_MPC1211 - bool "Interface MPC1211" - depends on CPU_SUBTYPE_SH7751 && BROKEN - help - CTP/PCI-SH02 is a CPU module computer that is produced - by Interface Corporation. - More information at - config SH_SH03 bool "Interface CTP/PCI-SH03" depends on CPU_SUBTYPE_SH7751 @@ -657,8 +649,7 @@ source "arch/sh/drivers/Kconfig" endmenu config ISA_DMA_API - def_bool y - depends on SH_MPC1211 + bool menu "Kernel features" @@ -666,7 +657,7 @@ source kernel/Kconfig.hz config KEXEC bool "kexec system call (EXPERIMENTAL)" - depends on EXPERIMENTAL + depends on SUPERH32 && EXPERIMENTAL help kexec is a system call that implements the ability to shutdown your current kernel, and to start another kernel. It is like a reboot @@ -683,7 +674,7 @@ config KEXEC config CRASH_DUMP bool "kernel crash dumps (EXPERIMENTAL)" - depends on EXPERIMENTAL + depends on SUPERH32 && EXPERIMENTAL help Generate crash dump after being started by kexec. This should be normally only set in special crash dump kernels @@ -763,7 +754,7 @@ menu "Boot options" config ZERO_PAGE_OFFSET hex "Zero page offset" - default "0x00004000" if SH_MPC1211 || SH_SH03 + default "0x00004000" if SH_SH03 default "0x00010000" if PAGE_SIZE_64KB default "0x00002000" if PAGE_SIZE_8KB default "0x00001000" diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug index d9d28f9dd0db5fbd990a1262d07898017e73cc04..0d2ef1e9a6fdd45cf483f61b33ccc96d2e71ce04 100644 --- a/arch/sh/Kconfig.debug +++ b/arch/sh/Kconfig.debug @@ -7,6 +7,7 @@ source "lib/Kconfig.debug" config SH_STANDARD_BIOS bool "Use LinuxSH standard BIOS" + depends on SUPERH32 help Say Y here if your target has the gdb-sh-stub package from www.m17n.org (or any conforming standard LinuxSH BIOS) diff --git a/arch/sh/Makefile b/arch/sh/Makefile index bb06f83e6239c648e138a1d820f0d3e6dab7fa51..8050b03d51fca42823063b2c31cf12984572728b 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -110,7 +110,6 @@ machdir-$(CONFIG_SH_7343_SOLUTION_ENGINE) += se/7343 machdir-$(CONFIG_SH_7721_SOLUTION_ENGINE) += se/7721 machdir-$(CONFIG_SH_HP6XX) += hp6xx machdir-$(CONFIG_SH_DREAMCAST) += dreamcast -machdir-$(CONFIG_SH_MPC1211) += mpc1211 machdir-$(CONFIG_SH_SH03) += sh03 machdir-$(CONFIG_SH_SECUREEDGE5410) += snapgear machdir-$(CONFIG_SH_RTS7751R2D) += renesas/rts7751r2d diff --git a/arch/sh/boards/mpc1211/Makefile b/arch/sh/boards/mpc1211/Makefile deleted file mode 100644 index 8cd31b5d200b026372f852a76ffb4d93ac0203c7..0000000000000000000000000000000000000000 --- a/arch/sh/boards/mpc1211/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# -# Makefile for the Interface (CTP/PCI/MPC-SH02) specific parts of the kernel -# - -obj-y := setup.o rtc.o - -obj-$(CONFIG_PCI) += pci.o - diff --git a/arch/sh/boards/mpc1211/pci.c b/arch/sh/boards/mpc1211/pci.c deleted file mode 100644 index 23849f70f13396b48fe8d1de52d81bbcb69a6b84..0000000000000000000000000000000000000000 --- a/arch/sh/boards/mpc1211/pci.c +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Low-Level PCI Support for the MPC-1211(CTP/PCI/MPC-SH02) - * - * (c) 2002-2003 Saito.K & Jeanne - * - * Dustin McIntire (dustin@sensoria.com) - * Derived from arch/i386/kernel/pci-*.c which bore the message: - * (c) 1999--2000 Martin Mares - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -static struct resource mpcpci_io_resource = { - "MPCPCI IO", - 0x00000000, - 0xffffffff, - IORESOURCE_IO -}; - -static struct resource mpcpci_mem_resource = { - "MPCPCI mem", - 0x00000000, - 0xffffffff, - IORESOURCE_MEM -}; - -static struct pci_ops pci_direct_conf1; -struct pci_channel board_pci_channels[] = { - {&pci_direct_conf1, &mpcpci_io_resource, &mpcpci_mem_resource, 0, 256}, - {NULL, NULL, NULL, 0, 0}, -}; - -/* - * Direct access to PCI hardware... - */ - - -#define CONFIG_CMD(bus, devfn, where) (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3)) - -/* - * Functions for accessing PCI configuration space with type 1 accesses - */ -static int pci_conf1_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) -{ - u32 word; - unsigned long flags; - - /* - * PCIPDR may only be accessed as 32 bit words, - * so we must do byte alignment by hand - */ - local_irq_save(flags); - writel(CONFIG_CMD(bus,devfn,where), PCIPAR); - word = readl(PCIPDR); - local_irq_restore(flags); - - switch (size) { - case 1: - switch (where & 0x3) { - case 3: - *value = (u8)(word >> 24); - break; - case 2: - *value = (u8)(word >> 16); - break; - case 1: - *value = (u8)(word >> 8); - break; - default: - *value = (u8)word; - break; - } - break; - case 2: - switch (where & 0x3) { - case 3: - *value = (u16)(word >> 24); - local_irq_save(flags); - writel(CONFIG_CMD(bus,devfn,(where+1)), PCIPAR); - word = readl(PCIPDR); - local_irq_restore(flags); - *value |= ((word & 0xff) << 8); - break; - case 2: - *value = (u16)(word >> 16); - break; - case 1: - *value = (u16)(word >> 8); - break; - default: - *value = (u16)word; - break; - } - break; - case 4: - *value = word; - break; - } - PCIDBG(4,"pci_conf1_read@0x%08x=0x%x\n", CONFIG_CMD(bus,devfn,where),*value); - return PCIBIOS_SUCCESSFUL; -} - -/* - * Since MPC-1211 only does 32bit access we'll have to do a read,mask,write operation. - * We'll allow an odd byte offset, though it should be illegal. - */ -static int pci_conf1_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value) -{ - u32 word,mask = 0; - unsigned long flags; - u32 shift = (where & 3) * 8; - - if(size == 1) { - mask = ((1 << 8) - 1) << shift; // create the byte mask - } else if(size == 2){ - if(shift == 24) - return PCIBIOS_BAD_REGISTER_NUMBER; - mask = ((1 << 16) - 1) << shift; // create the word mask - } - local_irq_save(flags); - writel(CONFIG_CMD(bus,devfn,where), PCIPAR); - if(size == 4){ - writel(value, PCIPDR); - local_irq_restore(flags); - PCIDBG(4,"pci_conf1_write@0x%08x=0x%x\n", CONFIG_CMD(bus,devfn,where),value); - return PCIBIOS_SUCCESSFUL; - } - word = readl(PCIPDR); - word &= ~mask; - word |= ((value << shift) & mask); - writel(word, PCIPDR); - local_irq_restore(flags); - PCIDBG(4,"pci_conf1_write@0x%08x=0x%x\n", CONFIG_CMD(bus,devfn,where),word); - return PCIBIOS_SUCCESSFUL; -} - -#undef CONFIG_CMD - -static struct pci_ops pci_direct_conf1 = { - .read = pci_conf1_read, - .write = pci_conf1_write, -}; - -static void __devinit quirk_ali_ide_ports(struct pci_dev *dev) -{ - dev->resource[0].start = 0x1f0; - dev->resource[0].end = 0x1f7; - dev->resource[0].flags = IORESOURCE_IO; - dev->resource[1].start = 0x3f6; - dev->resource[1].end = 0x3f6; - dev->resource[1].flags = IORESOURCE_IO; - dev->resource[2].start = 0x170; - dev->resource[2].end = 0x177; - dev->resource[2].flags = IORESOURCE_IO; - dev->resource[3].start = 0x376; - dev->resource[3].end = 0x376; - dev->resource[3].flags = IORESOURCE_IO; - dev->resource[4].start = 0xf000; - dev->resource[4].end = 0xf00f; - dev->resource[4].flags = IORESOURCE_IO; -} -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5229, quirk_ali_ide_ports); - -char * __devinit pcibios_setup(char *str) -{ - return str; -} - -/* - * Called after each bus is probed, but before its children - * are examined. - */ - -void __devinit pcibios_fixup_bus(struct pci_bus *b) -{ - pci_read_bridge_bases(b); -} - -/* - * IRQ functions - */ -static inline u8 bridge_swizzle(u8 pin, u8 slot) -{ - return (((pin-1) + slot) % 4) + 1; -} - -static inline u8 bridge_swizzle_pci_1(u8 pin, u8 slot) -{ - return (((pin-1) - slot) & 3) + 1; -} - -static u8 __init mpc1211_swizzle(struct pci_dev *dev, u8 *pinp) -{ - unsigned long flags; - u8 pin = *pinp; - u32 word; - - for ( ; dev->bus->self; dev = dev->bus->self) { - if (!pin) - continue; - - if (dev->bus->number == 1) { - local_irq_save(flags); - writel(0x80000000 | 0x2c, PCIPAR); - word = readl(PCIPDR); - local_irq_restore(flags); - word >>= 16; - - if (word == 0x0001) - pin = bridge_swizzle_pci_1(pin, PCI_SLOT(dev->devfn)); - else - pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn)); - } else - pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn)); - } - - *pinp = pin; - - return PCI_SLOT(dev->devfn); -} - -static int __init map_mpc1211_irq(struct pci_dev *dev, u8 slot, u8 pin) -{ - int irq = -1; - - /* now lookup the actual IRQ on a platform specific basis (pci-'platform'.c) */ - if (dev->bus->number == 0) { - switch (slot) { - case 13: irq = 9; break; /* USB */ - case 22: irq = 10; break; /* LAN */ - default: irq = 0; break; - } - } else { - switch (pin) { - case 0: irq = 0; break; - case 1: irq = 7; break; - case 2: irq = 9; break; - case 3: irq = 10; break; - case 4: irq = 11; break; - } - } - - if( irq < 0 ) { - PCIDBG(3, "PCI: Error mapping IRQ on device %s\n", pci_name(dev)); - return irq; - } - - PCIDBG(2, "Setting IRQ for slot %s to %d\n", pci_name(dev), irq); - - return irq; -} - -void __init pcibios_fixup_irqs(void) -{ - pci_fixup_irqs(mpc1211_swizzle, map_mpc1211_irq); -} - -void pcibios_align_resource(void *data, struct resource *res, - resource_size_t size, resource_size_t align) -{ - resource_size_t start = res->start; - - if (res->flags & IORESOURCE_IO) { - if (start >= 0x10000UL) { - if ((start & 0xffffUL) < 0x4000UL) { - start = (start & 0xffff0000UL) + 0x4000UL; - } else if ((start & 0xffffUL) >= 0xf000UL) { - start = (start & 0xffff0000UL) + 0x10000UL; - } - res->start = start; - } else { - if (start & 0x300) { - start = (start + 0x3ff) & ~0x3ff; - res->start = start; - } - } - } -} - diff --git a/arch/sh/boards/mpc1211/rtc.c b/arch/sh/boards/mpc1211/rtc.c deleted file mode 100644 index 03b123a4bba42d54bd2757dc514da30fe1f7a998..0000000000000000000000000000000000000000 --- a/arch/sh/boards/mpc1211/rtc.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * linux/arch/sh/kernel/rtc-mpc1211.c -- MPC-1211 on-chip RTC support - * - * Copyright (C) 2002 Saito.K & Jeanne - * - */ - -#include -#include -#include -#include -#include -#include - -unsigned long get_cmos_time(void) -{ - unsigned int year, mon, day, hour, min, sec; - - spin_lock(&rtc_lock); - - do { - sec = CMOS_READ(RTC_SECONDS); - min = CMOS_READ(RTC_MINUTES); - hour = CMOS_READ(RTC_HOURS); - day = CMOS_READ(RTC_DAY_OF_MONTH); - mon = CMOS_READ(RTC_MONTH); - year = CMOS_READ(RTC_YEAR); - } while (sec != CMOS_READ(RTC_SECONDS)); - - if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - BCD_TO_BIN(sec); - BCD_TO_BIN(min); - BCD_TO_BIN(hour); - BCD_TO_BIN(day); - BCD_TO_BIN(mon); - BCD_TO_BIN(year); - } - - spin_unlock(&rtc_lock); - - year += 1900; - if (year < 1970) - year += 100; - - return mktime(year, mon, day, hour, min, sec); -} - -void mpc1211_rtc_gettimeofday(struct timeval *tv) -{ - - tv->tv_sec = get_cmos_time(); - tv->tv_usec = 0; -} - -/* arc/i386/kernel/time.c */ -/* - * In order to set the CMOS clock precisely, set_rtc_mmss has to be - * called 500 ms after the second nowtime has started, because when - * nowtime is written into the registers of the CMOS clock, it will - * jump to the next second precisely 500 ms later. Check the Motorola - * MC146818A or Dallas DS12887 data sheet for details. - * - * BUG: This routine does not handle hour overflow properly; it just - * sets the minutes. Usually you'll only notice that after reboot! - */ -static int set_rtc_mmss(unsigned long nowtime) -{ - int retval = 0; - int real_seconds, real_minutes, cmos_minutes; - unsigned char save_control, save_freq_select; - - /* gets recalled with irq locally disabled */ - spin_lock(&rtc_lock); - save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */ - CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL); - - save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */ - CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); - - cmos_minutes = CMOS_READ(RTC_MINUTES); - if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) - BCD_TO_BIN(cmos_minutes); - - /* - * since we're only adjusting minutes and seconds, - * don't interfere with hour overflow. This avoids - * messing with unknown time zones but requires your - * RTC not to be off by more than 15 minutes - */ - real_seconds = nowtime % 60; - real_minutes = nowtime / 60; - if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1) - real_minutes += 30; /* correct for half hour time zone */ - real_minutes %= 60; - - if (abs(real_minutes - cmos_minutes) < 30) { - if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - BIN_TO_BCD(real_seconds); - BIN_TO_BCD(real_minutes); - } - CMOS_WRITE(real_seconds,RTC_SECONDS); - CMOS_WRITE(real_minutes,RTC_MINUTES); - } else { - printk(KERN_WARNING - "set_rtc_mmss: can't update from %d to %d\n", - cmos_minutes, real_minutes); - retval = -1; - } - - /* The following flags have to be released exactly in this order, - * otherwise the DS12887 (popular MC146818A clone with integrated - * battery and quartz) will not reset the oscillator and will not - * update precisely 500 ms later. You won't find this mentioned in - * the Dallas Semiconductor data sheets, but who believes data - * sheets anyway ... -- Markus Kuhn - */ - CMOS_WRITE(save_control, RTC_CONTROL); - CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); - spin_unlock(&rtc_lock); - - return retval; -} - -int mpc1211_rtc_settimeofday(const struct timeval *tv) -{ - unsigned long nowtime = tv->tv_sec; - - return set_rtc_mmss(nowtime); -} - -void mpc1211_time_init(void) -{ - rtc_sh_get_time = mpc1211_rtc_gettimeofday; - rtc_sh_set_time = mpc1211_rtc_settimeofday; -} - diff --git a/arch/sh/boards/mpc1211/setup.c b/arch/sh/boards/mpc1211/setup.c deleted file mode 100644 index fede36361dc78065c7999014ac3e61be16bf1b95..0000000000000000000000000000000000000000 --- a/arch/sh/boards/mpc1211/setup.c +++ /dev/null @@ -1,347 +0,0 @@ -/* - * linux/arch/sh/boards/mpc1211/setup.c - * - * Copyright (C) 2002 Saito.K & Jeanne, Fujii.Y - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* ALI15X3 SMBus address offsets */ -#define SMBHSTSTS (0 + 0x3100) -#define SMBHSTCNT (1 + 0x3100) -#define SMBHSTSTART (2 + 0x3100) -#define SMBHSTCMD (7 + 0x3100) -#define SMBHSTADD (3 + 0x3100) -#define SMBHSTDAT0 (4 + 0x3100) -#define SMBHSTDAT1 (5 + 0x3100) -#define SMBBLKDAT (6 + 0x3100) - -/* Other settings */ -#define MAX_TIMEOUT 500 /* times 1/100 sec */ - -/* ALI15X3 command constants */ -#define ALI15X3_ABORT 0x04 -#define ALI15X3_T_OUT 0x08 -#define ALI15X3_QUICK 0x00 -#define ALI15X3_BYTE 0x10 -#define ALI15X3_BYTE_DATA 0x20 -#define ALI15X3_WORD_DATA 0x30 -#define ALI15X3_BLOCK_DATA 0x40 -#define ALI15X3_BLOCK_CLR 0x80 - -/* ALI15X3 status register bits */ -#define ALI15X3_STS_IDLE 0x04 -#define ALI15X3_STS_BUSY 0x08 -#define ALI15X3_STS_DONE 0x10 -#define ALI15X3_STS_DEV 0x20 /* device error */ -#define ALI15X3_STS_COLL 0x40 /* collision or no response */ -#define ALI15X3_STS_TERM 0x80 /* terminated by abort */ -#define ALI15X3_STS_ERR 0xE0 /* all the bad error bits */ - -static void __init pci_write_config(unsigned long busNo, - unsigned long devNo, - unsigned long fncNo, - unsigned long cnfAdd, - unsigned long cnfData) -{ - ctrl_outl((0x80000000 - + ((busNo & 0xff) << 16) - + ((devNo & 0x1f) << 11) - + ((fncNo & 0x07) << 8) - + (cnfAdd & 0xfc)), PCIPAR); - - ctrl_outl(cnfData, PCIPDR); -} - -/* - Initialize IRQ setting -*/ - -static unsigned char m_irq_mask = 0xfb; -static unsigned char s_irq_mask = 0xff; - -static void disable_mpc1211_irq(unsigned int irq) -{ - if( irq < 8) { - m_irq_mask |= (1 << irq); - outb(m_irq_mask,I8259_M_MR); - } else { - s_irq_mask |= (1 << (irq - 8)); - outb(s_irq_mask,I8259_S_MR); - } - -} - -static void enable_mpc1211_irq(unsigned int irq) -{ - if( irq < 8) { - m_irq_mask &= ~(1 << irq); - outb(m_irq_mask,I8259_M_MR); - } else { - s_irq_mask &= ~(1 << (irq - 8)); - outb(s_irq_mask,I8259_S_MR); - } -} - -static inline int mpc1211_irq_real(unsigned int irq) -{ - int value; - int irqmask; - - if ( irq < 8) { - irqmask = 1<= MAX_TIMEOUT){ - return -1; - } - - outb(((address & 0x7f) << 1), SMBHSTADD); - outb(0xc0, SMBHSTCNT); - outb(command & 0xff, SMBHSTCMD); - outb(no & 0x1f, SMBHSTDAT0); - - for(i = 1; i <= no; i++) { - outb(*p++, SMBBLKDAT); - } - outb(0xff, SMBHSTSTART); - - temp = inb(SMBHSTSTS); - for (timeout = 0; (timeout < MAX_TIMEOUT) && !(temp & (ALI15X3_STS_ERR | ALI15X3_STS_DONE)); timeout++) { - delay1000(); - temp = inb(SMBHSTSTS); - } - if (timeout >= MAX_TIMEOUT) { - return -2; - } - if ( temp & ALI15X3_STS_ERR ){ - return -3; - } - return 0; -} - -static struct resource heartbeat_resources[] = { - [0] = { - .start = 0xa2000000, - .end = 0xa2000000, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device heartbeat_device = { - .name = "heartbeat", - .id = -1, - .num_resources = ARRAY_SIZE(heartbeat_resources), - .resource = heartbeat_resources, -}; - -static struct platform_device *mpc1211_devices[] __initdata = { - &heartbeat_device, -}; - -static int __init mpc1211_devices_setup(void) -{ - return platform_add_devices(mpc1211_devices, - ARRAY_SIZE(mpc1211_devices)); -} -__initcall(mpc1211_devices_setup); - -/* arch/sh/boards/mpc1211/rtc.c */ -void mpc1211_time_init(void); - -static void __init mpc1211_setup(char **cmdline_p) -{ - unsigned char spd_buf[128]; - - __set_io_port_base(PA_PCI_IO); - - pci_write_config(0,0,0,0x54, 0xb0b00000); - - do { - outb(ALI15X3_ABORT, SMBHSTCNT); - spd_buf[0] = 0x0c; - spd_buf[1] = 0x43; - spd_buf[2] = 0x7f; - spd_buf[3] = 0x03; - spd_buf[4] = 0x00; - spd_buf[5] = 0x03; - spd_buf[6] = 0x00; - } while (put_smb_blk(spd_buf, 0x69, 0, 7) < 0); - - board_time_init = mpc1211_time_init; - - return 0; -} - -/* - * The Machine Vector - */ -static struct sh_machine_vector mv_mpc1211 __initmv = { - .mv_name = "Interface MPC-1211(CTP/PCI/MPC-SH02)", - .mv_setup = mpc1211_setup, - .mv_nr_irqs = 48, - .mv_irq_demux = mpc1211_irq_demux, - .mv_init_irq = init_mpc1211_IRQ, -}; diff --git a/arch/sh/boards/renesas/migor/setup.c b/arch/sh/boards/renesas/migor/setup.c index e7c150d4970297629be13c17fefa543f5cfe9ac5..01af44245b57761c5f4f5004d3b438a93e7fcc07 100644 --- a/arch/sh/boards/renesas/migor/setup.c +++ b/arch/sh/boards/renesas/migor/setup.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -27,6 +28,11 @@ * 0x18000000 8GB 8 NAND Flash (K9K8G08U0A) */ +static struct smc91x_platdata smc91x_info = { + .flags = SMC91X_USE_16BIT, + .irq_flags = IRQF_TRIGGER_HIGH, +}; + static struct resource smc91x_eth_resources[] = { [0] = { .name = "SMC91C111" , @@ -36,7 +42,7 @@ static struct resource smc91x_eth_resources[] = { }, [1] = { .start = 32, /* IRQ0 */ - .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH, + .flags = IORESOURCE_IRQ, }, }; @@ -44,6 +50,9 @@ static struct platform_device smc91x_eth_device = { .name = "smc91x", .num_resources = ARRAY_SIZE(smc91x_eth_resources), .resource = smc91x_eth_resources, + .dev = { + .platform_data = &smc91x_info, + }, }; static struct sh_keysc_info sh_keysc_info = { diff --git a/arch/sh/boards/renesas/r7780rp/irq-r7780mp.c b/arch/sh/boards/renesas/r7780rp/irq-r7780mp.c index 68f0ad1b637dd3335243e7e101761fe34cd08688..ae1cfcb297008f76f8cb003872cf2ba87c6a8aa0 100644 --- a/arch/sh/boards/renesas/r7780rp/irq-r7780mp.c +++ b/arch/sh/boards/renesas/r7780rp/irq-r7780mp.c @@ -62,7 +62,7 @@ static unsigned char irl2irq[HL_NR_IRL] __initdata = { static DECLARE_INTC_DESC(intc_desc, "r7780mp", vectors, NULL, mask_registers, NULL, NULL); -unsigned char * __init highlander_init_irq_r7780mp(void) +unsigned char * __init highlander_plat_irq_setup(void) { if ((ctrl_inw(0xa4000700) & 0xf000) == 0x2000) { printk(KERN_INFO "Using r7780mp interrupt controller.\n"); diff --git a/arch/sh/boards/renesas/r7780rp/irq-r7780rp.c b/arch/sh/boards/renesas/r7780rp/irq-r7780rp.c index bd34048ed0e1f95c6b042a77d7a17486d13663e0..9d3921fe27c0b4506322ad5a3a0837c652a63c02 100644 --- a/arch/sh/boards/renesas/r7780rp/irq-r7780rp.c +++ b/arch/sh/boards/renesas/r7780rp/irq-r7780rp.c @@ -55,7 +55,7 @@ static unsigned char irl2irq[HL_NR_IRL] __initdata = { static DECLARE_INTC_DESC(intc_desc, "r7780rp", vectors, NULL, mask_registers, NULL, NULL); -unsigned char * __init highlander_init_irq_r7780rp(void) +unsigned char * __init highlander_plat_irq_setup(void) { if (ctrl_inw(0xa5000600)) { printk(KERN_INFO "Using r7780rp interrupt controller.\n"); diff --git a/arch/sh/boards/renesas/r7780rp/irq-r7785rp.c b/arch/sh/boards/renesas/r7780rp/irq-r7785rp.c index bf7ec107fbc63b4515e871a7858e6dfb7086e176..896c045aa39d63ab66ebc4eceed0b38f00911b59 100644 --- a/arch/sh/boards/renesas/r7780rp/irq-r7785rp.c +++ b/arch/sh/boards/renesas/r7780rp/irq-r7785rp.c @@ -64,7 +64,7 @@ static unsigned char irl2irq[HL_NR_IRL] __initdata = { static DECLARE_INTC_DESC(intc_desc, "r7785rp", vectors, NULL, mask_registers, NULL, NULL); -unsigned char * __init highlander_init_irq_r7785rp(void) +unsigned char * __init highlander_plat_irq_setup(void) { if ((ctrl_inw(0xa4000158) & 0xf000) != 0x1000) return NULL; diff --git a/arch/sh/boards/renesas/r7780rp/setup.c b/arch/sh/boards/renesas/r7780rp/setup.c index ac0a96522e45e3f9387ae578149fe9ec05e34578..bc79afb6fc4c04c7c13335b9ae03e4938ec51939 100644 --- a/arch/sh/boards/renesas/r7780rp/setup.c +++ b/arch/sh/boards/renesas/r7780rp/setup.c @@ -316,7 +316,7 @@ static void __init highlander_setup(char **cmdline_p) static unsigned char irl2irq[HL_NR_IRL]; -int highlander_irq_demux(int irq) +static int highlander_irq_demux(int irq) { if (irq >= HL_NR_IRL || !irl2irq[irq]) return irq; @@ -324,27 +324,9 @@ int highlander_irq_demux(int irq) return irl2irq[irq]; } -void __init highlander_init_irq(void) +static void __init highlander_init_irq(void) { - unsigned char *ucp = NULL; - - do { -#ifdef CONFIG_SH_R7780MP - ucp = highlander_init_irq_r7780mp(); - if (ucp) - break; -#endif -#ifdef CONFIG_SH_R7785RP - ucp = highlander_init_irq_r7785rp(); - if (ucp) - break; -#endif -#ifdef CONFIG_SH_R7780RP - ucp = highlander_init_irq_r7780rp(); - if (ucp) - break; -#endif - } while (0); + unsigned char *ucp = highlander_plat_irq_setup(); if (ucp) { plat_irq_setup_pins(IRQ_MODE_IRL3210); diff --git a/arch/sh/boards/renesas/rts7751r2d/setup.c b/arch/sh/boards/renesas/rts7751r2d/setup.c index f21ee49ef3a5c842c540c8e4a0780b113d666c2a..452d0d6459a40ee0da3a1f1050d8525ac66367ee 100644 --- a/arch/sh/boards/renesas/rts7751r2d/setup.c +++ b/arch/sh/boards/renesas/rts7751r2d/setup.c @@ -109,7 +109,6 @@ static struct platform_device heartbeat_device = { .resource = heartbeat_resources, }; -#ifdef CONFIG_MFD_SM501 static struct plat_serial8250_port uart_platform_data[] = { { .membase = (void __iomem *)0xb3e30000, @@ -208,13 +207,9 @@ static struct platform_device sm501_device = { .resource = sm501_resources, }; -#endif /* CONFIG_MFD_SM501 */ - static struct platform_device *rts7751r2d_devices[] __initdata = { -#ifdef CONFIG_MFD_SM501 &uart_device, &sm501_device, -#endif &heartbeat_device, &spi_sh_sci_device, }; @@ -234,7 +229,9 @@ static int __init rts7751r2d_devices_setup(void) { if (register_trapped_io(&cf_trapped_io) == 0) platform_device_register(&cf_ide_device); + spi_register_board_info(spi_bus, ARRAY_SIZE(spi_bus)); + return platform_add_devices(rts7751r2d_devices, ARRAY_SIZE(rts7751r2d_devices)); } diff --git a/arch/sh/boards/se/7206/setup.c b/arch/sh/boards/se/7206/setup.c index 5b3ee089d91de3acc943cc3ef142dac056072b60..4fe84cc0840679fa3ad0ca83aa09fc7975def7b0 100644 --- a/arch/sh/boards/se/7206/setup.c +++ b/arch/sh/boards/se/7206/setup.c @@ -3,12 +3,13 @@ * linux/arch/sh/boards/se/7206/setup.c * * Copyright (C) 2006 Yoshinori Sato - * Copyright (C) 2007 Paul Mundt + * Copyright (C) 2007 - 2008 Paul Mundt * * Hitachi 7206 SolutionEngine Support. */ #include #include +#include #include #include #include @@ -16,8 +17,9 @@ static struct resource smc91x_resources[] = { [0] = { - .start = 0x300, - .end = 0x300 + 0x020 - 1, + .name = "smc91x-regs", + .start = PA_SMSC + 0x300, + .end = PA_SMSC + 0x300 + 0x020 - 1, .flags = IORESOURCE_MEM, }, [1] = { @@ -27,9 +29,18 @@ static struct resource smc91x_resources[] = { }, }; +static struct smc91x_platdata smc91x_info = { + .flags = SMC91X_USE_16BIT, +}; + static struct platform_device smc91x_device = { .name = "smc91x", .id = -1, + .dev = { + .dma_mask = NULL, + .coherent_dma_mask = 0xffffffff, + .platform_data = &smc91x_info, + }, .num_resources = ARRAY_SIZE(smc91x_resources), .resource = smc91x_resources, }; diff --git a/arch/sh/boards/se/7722/setup.c b/arch/sh/boards/se/7722/setup.c index 33f6ee71f8483f9c58dd736ed93c9237d54f2e33..ede3957fc14afa676eb8f609c06f97d651cc6949 100644 --- a/arch/sh/boards/se/7722/setup.c +++ b/arch/sh/boards/se/7722/setup.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -44,6 +45,10 @@ static struct platform_device heartbeat_device = { }; /* SMC91x */ +static struct smc91x_platdata smc91x_info = { + .flags = SMC91X_USE_16BIT, +}; + static struct resource smc91x_eth_resources[] = { [0] = { .name = "smc91x-regs" , @@ -64,6 +69,7 @@ static struct platform_device smc91x_eth_device = { .dev = { .dma_mask = NULL, /* don't use dma */ .coherent_dma_mask = 0xffffffff, + .platform_data = &smc91x_info, }, .num_resources = ARRAY_SIZE(smc91x_eth_resources), .resource = smc91x_eth_resources, diff --git a/arch/sh/boot/compressed/Makefile_32 b/arch/sh/boot/compressed/Makefile_32 index 6ac8d4a4ed1d87986b8a3debb9caa6ce2df31237..c0d25fb1aa608bb4829294d0907bde736a02f82c 100644 --- a/arch/sh/boot/compressed/Makefile_32 +++ b/arch/sh/boot/compressed/Makefile_32 @@ -6,7 +6,6 @@ targets := vmlinux vmlinux.bin vmlinux.bin.gz \ head_32.o misc_32.o piggy.o -EXTRA_AFLAGS := -traditional OBJECTS = $(obj)/head_32.o $(obj)/misc_32.o diff --git a/arch/sh/boot/compressed/Makefile_64 b/arch/sh/boot/compressed/Makefile_64 index 4334f2b86d8f2e109750e34a29014cc4feae680c..912f3e205a0d38678c532cff4a884f80fd541d77 100644 --- a/arch/sh/boot/compressed/Makefile_64 +++ b/arch/sh/boot/compressed/Makefile_64 @@ -13,7 +13,6 @@ targets := vmlinux vmlinux.bin vmlinux.bin.gz \ head_64.o misc_64.o cache.o piggy.o -EXTRA_AFLAGS := -traditional OBJECTS := $(obj)/vmlinux_64.lds $(obj)/head_64.o $(obj)/misc_64.o \ $(obj)/cache.o diff --git a/arch/sh/kernel/cpu/irq/intc-sh5.c b/arch/sh/kernel/cpu/irq/intc-sh5.c index d6e0e2bdaad5b62858a1e045537eea75389bd5df..de45c6a3e33be98285b04aaa39e927535375f8ee 100644 --- a/arch/sh/kernel/cpu/irq/intc-sh5.c +++ b/arch/sh/kernel/cpu/irq/intc-sh5.c @@ -184,9 +184,8 @@ int intc_irq_describe(char* p, int irq) void __init plat_irq_setup(void) { - unsigned long long __dummy0, __dummy1=~0x00000000100000f0; + unsigned long long __dummy0, __dummy1=~0x00000000100000f0; unsigned long reg; - unsigned long data; int i; intc_virt = onchip_remap(INTC_BASE, 1024, "INTC"); @@ -196,11 +195,8 @@ void __init plat_irq_setup(void) /* Set default: per-line enable/disable, priority driven ack/eoi */ - for (i = 0; i < NR_INTC_IRQS; i++) { - if (platform_int_priority[i] != NO_PRIORITY) { - irq_desc[i].chip = &intc_irq_type; - } - } + for (i = 0; i < NR_INTC_IRQS; i++) + irq_desc[i].chip = &intc_irq_type; /* Disable all interrupts and set all priorities to 0 to avoid trouble */ @@ -211,35 +207,42 @@ void __init plat_irq_setup(void) ctrl_outl( NO_PRIORITY, reg); - /* Set IRLM */ - /* If all the priorities are set to 'no priority', then - * assume we are using encoded mode. - */ - irlm = platform_int_priority[IRQ_IRL0] + platform_int_priority[IRQ_IRL1] + \ - platform_int_priority[IRQ_IRL2] + platform_int_priority[IRQ_IRL3]; - - if (irlm == NO_PRIORITY) { - /* IRLM = 0 */ - reg = INTC_ICR_CLEAR; - i = IRQ_INTA; - printk("Trying to use encoded IRL0-3. IRLs unsupported.\n"); - } else { - /* IRLM = 1 */ - reg = INTC_ICR_SET; - i = IRQ_IRL0; - } - ctrl_outl(INTC_ICR_IRLM, reg); - - /* Set interrupt priorities according to platform description */ - for (data = 0, reg = INTC_INTPRI_0; i < NR_INTC_IRQS; i++) { - data |= platform_int_priority[i] << ((i % INTC_INTPRI_PPREG) * 4); - if ((i % INTC_INTPRI_PPREG) == (INTC_INTPRI_PPREG - 1)) { - /* Upon the 7th, set Priority Register */ - ctrl_outl(data, reg); - data = 0; - reg += 8; +#ifdef CONFIG_SH_CAYMAN + { + unsigned long data; + + /* Set IRLM */ + /* If all the priorities are set to 'no priority', then + * assume we are using encoded mode. + */ + irlm = platform_int_priority[IRQ_IRL0] + + platform_int_priority[IRQ_IRL1] + + platform_int_priority[IRQ_IRL2] + + platform_int_priority[IRQ_IRL3]; + if (irlm == NO_PRIORITY) { + /* IRLM = 0 */ + reg = INTC_ICR_CLEAR; + i = IRQ_INTA; + printk("Trying to use encoded IRL0-3. IRLs unsupported.\n"); + } else { + /* IRLM = 1 */ + reg = INTC_ICR_SET; + i = IRQ_IRL0; } - } + ctrl_outl(INTC_ICR_IRLM, reg); + + /* Set interrupt priorities according to platform description */ + for (data = 0, reg = INTC_INTPRI_0; i < NR_INTC_IRQS; i++) { + data |= platform_int_priority[i] << + ((i % INTC_INTPRI_PPREG) * 4); + if ((i % INTC_INTPRI_PPREG) == (INTC_INTPRI_PPREG - 1)) { + /* Upon the 7th, set Priority Register */ + ctrl_outl(data, reg); + data = 0; + reg += 8; + } + } +#endif /* * And now let interrupts come in. diff --git a/arch/sh/kernel/cpu/irq/intc.c b/arch/sh/kernel/cpu/irq/intc.c index 84806b2027f85525fee1b8569cc898dd1f94ca59..da5dae787888fe104fb78000290b4a0427d6b862 100644 --- a/arch/sh/kernel/cpu/irq/intc.c +++ b/arch/sh/kernel/cpu/irq/intc.c @@ -1,7 +1,7 @@ /* * Shared interrupt handling code for IPR and INTC2 types of IRQs. * - * Copyright (C) 2007 Magnus Damm + * Copyright (C) 2007, 2008 Magnus Damm * * Based on intc2.c and ipr.c * @@ -62,6 +62,9 @@ struct intc_desc_int { #endif static unsigned int intc_prio_level[NR_IRQS]; /* for now */ +#ifdef CONFIG_CPU_SH3 +static unsigned long ack_handle[NR_IRQS]; +#endif static inline struct intc_desc_int *get_intc_desc(unsigned int irq) { @@ -98,17 +101,26 @@ static void write_32(unsigned long addr, unsigned long h, unsigned long data) static void modify_8(unsigned long addr, unsigned long h, unsigned long data) { + unsigned long flags; + local_irq_save(flags); ctrl_outb(set_field(ctrl_inb(addr), data, h), addr); + local_irq_restore(flags); } static void modify_16(unsigned long addr, unsigned long h, unsigned long data) { + unsigned long flags; + local_irq_save(flags); ctrl_outw(set_field(ctrl_inw(addr), data, h), addr); + local_irq_restore(flags); } static void modify_32(unsigned long addr, unsigned long h, unsigned long data) { + unsigned long flags; + local_irq_save(flags); ctrl_outl(set_field(ctrl_inl(addr), data, h), addr); + local_irq_restore(flags); } enum { REG_FN_ERR = 0, REG_FN_WRITE_BASE = 1, REG_FN_MODIFY_BASE = 5 }; @@ -219,6 +231,25 @@ static void intc_disable(unsigned int irq) } } +#ifdef CONFIG_CPU_SH3 +static void intc_mask_ack(unsigned int irq) +{ + struct intc_desc_int *d = get_intc_desc(irq); + unsigned long handle = ack_handle[irq]; + unsigned long addr; + + intc_disable(irq); + + /* read register and write zero only to the assocaited bit */ + + if (handle) { + addr = INTC_REG(d, _INTC_ADDR_D(handle), 0); + ctrl_inb(addr); + ctrl_outb(0x3f ^ set_field(0, 1, handle), addr); + } +} +#endif + static struct intc_handle_int *intc_find_irq(struct intc_handle_int *hp, unsigned int nr_hp, unsigned int irq) @@ -280,7 +311,12 @@ static unsigned char intc_irq_sense_table[IRQ_TYPE_SENSE_MASK + 1] = { [IRQ_TYPE_EDGE_FALLING] = VALID(0), [IRQ_TYPE_EDGE_RISING] = VALID(1), [IRQ_TYPE_LEVEL_LOW] = VALID(2), + /* SH7706, SH7707 and SH7709 do not support high level triggered */ +#if !defined(CONFIG_CPU_SUBTYPE_SH7706) && \ + !defined(CONFIG_CPU_SUBTYPE_SH7707) && \ + !defined(CONFIG_CPU_SUBTYPE_SH7709) [IRQ_TYPE_LEVEL_HIGH] = VALID(3), +#endif }; static int intc_set_sense(unsigned int irq, unsigned int type) @@ -430,6 +466,40 @@ static unsigned int __init intc_prio_data(struct intc_desc *desc, return 0; } +#ifdef CONFIG_CPU_SH3 +static unsigned int __init intc_ack_data(struct intc_desc *desc, + struct intc_desc_int *d, + intc_enum enum_id) +{ + struct intc_mask_reg *mr = desc->ack_regs; + unsigned int i, j, fn, mode; + unsigned long reg_e, reg_d; + + for (i = 0; mr && enum_id && i < desc->nr_ack_regs; i++) { + mr = desc->ack_regs + i; + + for (j = 0; j < ARRAY_SIZE(mr->enum_ids); j++) { + if (mr->enum_ids[j] != enum_id) + continue; + + fn = REG_FN_MODIFY_BASE; + mode = MODE_ENABLE_REG; + reg_e = mr->set_reg; + reg_d = mr->set_reg; + + fn += (mr->reg_width >> 3) - 1; + return _INTC_MK(fn, mode, + intc_get_reg(d, reg_e), + intc_get_reg(d, reg_d), + 1, + (mr->reg_width - 1) - j); + } + } + + return 0; +} +#endif + static unsigned int __init intc_sense_data(struct intc_desc *desc, struct intc_desc_int *d, intc_enum enum_id) @@ -530,6 +600,11 @@ static void __init intc_register_irq(struct intc_desc *desc, /* irq should be disabled by default */ d->chip.mask(irq); + +#ifdef CONFIG_CPU_SH3 + if (desc->ack_regs) + ack_handle[irq] = intc_ack_data(desc, d, enum_id); +#endif } static unsigned int __init save_reg(struct intc_desc_int *d, @@ -560,6 +635,9 @@ void __init register_intc_controller(struct intc_desc *desc) d->nr_reg += desc->prio_regs ? desc->nr_prio_regs * 2 : 0; d->nr_reg += desc->sense_regs ? desc->nr_sense_regs : 0; +#ifdef CONFIG_CPU_SH3 + d->nr_reg += desc->ack_regs ? desc->nr_ack_regs : 0; +#endif d->reg = alloc_bootmem(d->nr_reg * sizeof(*d->reg)); #ifdef CONFIG_SMP d->smp = alloc_bootmem(d->nr_reg * sizeof(*d->smp)); @@ -592,14 +670,23 @@ void __init register_intc_controller(struct intc_desc *desc) } } - BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */ - d->chip.name = desc->name; d->chip.mask = intc_disable; d->chip.unmask = intc_enable; d->chip.mask_ack = intc_disable; d->chip.set_type = intc_set_sense; +#ifdef CONFIG_CPU_SH3 + if (desc->ack_regs) { + for (i = 0; i < desc->nr_ack_regs; i++) + k += save_reg(d, k, desc->ack_regs[i].set_reg, 0); + + d->chip.mask_ack = intc_mask_ack; + } +#endif + + BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */ + for (i = 0; i < desc->nr_vectors; i++) { struct intc_vect *vect = desc->vectors + i; diff --git a/arch/sh/kernel/cpu/sh2a/fpu.c b/arch/sh/kernel/cpu/sh2a/fpu.c index 5627c0b3ffa82e2c9496fec63eeeb2861eade897..6df2fb98eb30edb905c248290c0d64d754ed33cb 100644 --- a/arch/sh/kernel/cpu/sh2a/fpu.c +++ b/arch/sh/kernel/cpu/sh2a/fpu.c @@ -300,7 +300,7 @@ static int denormal_addf(int hx, int hy) iy = hy & 0x7fffffff; if (iy < 0x00800000) { ix = denormal_subf1(ix, iy); - if (ix < 0) { + if ((int) ix < 0) { ix = -ix; sign ^= 0x80000000; } @@ -385,7 +385,7 @@ static long long denormal_addd(long long hx, long long hy) iy = hy & 0x7fffffffffffffffLL; if (iy < 0x0010000000000000LL) { ix = denormal_subd1(ix, iy); - if (ix < 0) { + if ((int) ix < 0) { ix = -ix; sign ^= 0x8000000000000000LL; } diff --git a/arch/sh/kernel/cpu/sh3/Makefile b/arch/sh/kernel/cpu/sh3/Makefile index 3ae4d9111f19e7cecc33463da2d5a93767713faf..511de55af8321c0d982d827d7987a6c85c45c0c6 100644 --- a/arch/sh/kernel/cpu/sh3/Makefile +++ b/arch/sh/kernel/cpu/sh3/Makefile @@ -2,7 +2,7 @@ # Makefile for the Linux/SuperH SH-3 backends. # -obj-y := ex.o probe.o entry.o +obj-y := ex.o probe.o entry.o setup-sh3.o # CPU subtype setup obj-$(CONFIG_CPU_SUBTYPE_SH7705) += setup-sh7705.o diff --git a/arch/sh/kernel/cpu/sh3/setup-sh3.c b/arch/sh/kernel/cpu/sh3/setup-sh3.c new file mode 100644 index 0000000000000000000000000000000000000000..c988468578550c3e885588594280c1e32915c7d4 --- /dev/null +++ b/arch/sh/kernel/cpu/sh3/setup-sh3.c @@ -0,0 +1,71 @@ +/* + * Shared SH3 Setup code + * + * Copyright (C) 2008 Magnus Damm + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include +#include +#include + +/* All SH3 devices are equipped with IRQ0->5 (except sh7708) */ + +enum { + UNUSED = 0, + + /* interrupt sources */ + IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, +}; + +static struct intc_vect vectors_irq0123[] __initdata = { + INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620), + INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660), +}; + +static struct intc_vect vectors_irq45[] __initdata = { + INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0), +}; + +static struct intc_prio_reg prio_registers[] __initdata = { + { 0xa4000016, 0, 16, 4, /* IPRC */ { IRQ3, IRQ2, IRQ1, IRQ0 } }, + { 0xa4000018, 0, 16, 4, /* IPRD */ { 0, 0, IRQ5, IRQ4 } }, +}; + +static struct intc_mask_reg ack_registers[] __initdata = { + { 0xa4000004, 0, 8, /* IRR0 */ + { 0, 0, IRQ5, IRQ4, IRQ3, IRQ2, IRQ1, IRQ0 } }, +}; + +static struct intc_sense_reg sense_registers[] __initdata = { + { 0xa4000010, 16, 2, { 0, 0, IRQ5, IRQ4, IRQ3, IRQ2, IRQ1, IRQ0 } }, +}; + +static DECLARE_INTC_DESC_ACK(intc_desc_irq0123, "sh3-irq0123", + vectors_irq0123, NULL, NULL, + prio_registers, sense_registers, ack_registers); + +static DECLARE_INTC_DESC_ACK(intc_desc_irq45, "sh3-irq45", + vectors_irq45, NULL, NULL, + prio_registers, sense_registers, ack_registers); + +#define INTC_ICR1 0xa4000010UL +#define INTC_ICR1_IRQLVL (1<<14) + +void __init plat_irq_setup_pins(int mode) +{ + if (mode == IRQ_MODE_IRQ) { + ctrl_outw(ctrl_inw(INTC_ICR1) & ~INTC_ICR1_IRQLVL, INTC_ICR1); + register_intc_controller(&intc_desc_irq0123); + return; + } + BUG(); +} + +void __init plat_irq_setup_sh3(void) +{ + register_intc_controller(&intc_desc_irq45); +} diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c index f581534cb732c08163b274dc452745e957d924d5..6468ae86b9443fd53bf0310fc3e97092f641786e 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c @@ -37,7 +37,7 @@ enum { }; static struct intc_vect vectors[] __initdata = { - INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0), + /* IRQ0->5 are handled in setup-sh3.c */ INTC_VECT(PINT07, 0x700), INTC_VECT(PINT815, 0x720), INTC_VECT(DMAC_DEI0, 0x800), INTC_VECT(DMAC_DEI1, 0x820), INTC_VECT(DMAC_DEI2, 0x840), INTC_VECT(DMAC_DEI3, 0x860), @@ -48,7 +48,7 @@ static struct intc_vect vectors[] __initdata = { INTC_VECT(ADC_ADI, 0x980), INTC_VECT(USB_USI0, 0xa20), INTC_VECT(USB_USI1, 0xa40), INTC_VECT(TPU0, 0xc00), INTC_VECT(TPU1, 0xc20), - INTC_VECT(TPU3, 0xc80), INTC_VECT(TPU1, 0xca0), + INTC_VECT(TPU2, 0xc80), INTC_VECT(TPU3, 0xca0), INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420), INTC_VECT(TMU2_TUNI, 0x440), INTC_VECT(TMU2_TICPI, 0x460), INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0), @@ -81,14 +81,6 @@ static struct intc_prio_reg prio_registers[] __initdata = { static DECLARE_INTC_DESC(intc_desc, "sh7705", vectors, groups, NULL, prio_registers, NULL); -static struct intc_vect vectors_irq[] __initdata = { - INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620), - INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660), -}; - -static DECLARE_INTC_DESC(intc_desc_irq, "sh7705-irq", vectors_irq, NULL, - NULL, prio_registers, NULL); - static struct plat_sci_port sci_platform_data[] = { { .mapbase = 0xa4410000, @@ -159,16 +151,8 @@ static int __init sh7705_devices_setup(void) } __initcall(sh7705_devices_setup); -void __init plat_irq_setup_pins(int mode) -{ - if (mode == IRQ_MODE_IRQ) { - register_intc_controller(&intc_desc_irq); - return; - } - BUG(); -} - void __init plat_irq_setup(void) { register_intc_controller(&intc_desc); + plat_irq_setup_sh3(); } diff --git a/arch/sh/kernel/cpu/sh3/setup-sh770x.c b/arch/sh/kernel/cpu/sh3/setup-sh770x.c index d3733b13ea5298194020ee43114ce3bafe8420c4..93c55e2ed952484fead5128b91509a851c28a887 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh770x.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh770x.c @@ -52,7 +52,7 @@ static struct intc_vect vectors[] __initdata = { #if defined(CONFIG_CPU_SUBTYPE_SH7706) || \ defined(CONFIG_CPU_SUBTYPE_SH7707) || \ defined(CONFIG_CPU_SUBTYPE_SH7709) - INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0), + /* IRQ0->5 are handled in setup-sh3.c */ INTC_VECT(DMAC_DEI0, 0x800), INTC_VECT(DMAC_DEI1, 0x820), INTC_VECT(DMAC_DEI2, 0x840), INTC_VECT(DMAC_DEI3, 0x860), INTC_VECT(ADC_ADI, 0x980), @@ -104,18 +104,6 @@ static struct intc_prio_reg prio_registers[] __initdata = { static DECLARE_INTC_DESC(intc_desc, "sh770x", vectors, groups, NULL, prio_registers, NULL); -#if defined(CONFIG_CPU_SUBTYPE_SH7706) || \ - defined(CONFIG_CPU_SUBTYPE_SH7707) || \ - defined(CONFIG_CPU_SUBTYPE_SH7709) -static struct intc_vect vectors_irq[] __initdata = { - INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620), - INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660), -}; - -static DECLARE_INTC_DESC(intc_desc_irq, "sh770x-irq", vectors_irq, NULL, - NULL, prio_registers, NULL); -#endif - static struct resource rtc_resources[] = { [0] = { .start = 0xfffffec0, @@ -194,24 +182,12 @@ static int __init sh770x_devices_setup(void) } __initcall(sh770x_devices_setup); -#define INTC_ICR1 0xa4000010UL -#define INTC_ICR1_IRQLVL (1<<14) - -void __init plat_irq_setup_pins(int mode) +void __init plat_irq_setup(void) { - if (mode == IRQ_MODE_IRQ) { + register_intc_controller(&intc_desc); #if defined(CONFIG_CPU_SUBTYPE_SH7706) || \ defined(CONFIG_CPU_SUBTYPE_SH7707) || \ defined(CONFIG_CPU_SUBTYPE_SH7709) - ctrl_outw(ctrl_inw(INTC_ICR1) & ~INTC_ICR1_IRQLVL, INTC_ICR1); - register_intc_controller(&intc_desc_irq); - return; + plat_irq_setup_sh3(); #endif - } - BUG(); -} - -void __init plat_irq_setup(void) -{ - register_intc_controller(&intc_desc); } diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c index 7406c9ad92597c758cab7cecdf3102e48e72f078..77eee481de474fc23d2c2d7b387ff29758d8ba59 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c @@ -38,7 +38,7 @@ enum { }; static struct intc_vect vectors[] __initdata = { - INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0), + /* IRQ0->5 are handled in setup-sh3.c */ INTC_VECT(DMAC_DEI0, 0x800), INTC_VECT(DMAC_DEI1, 0x820), INTC_VECT(DMAC_DEI2, 0x840), INTC_VECT(DMAC_DEI3, 0x860), INTC_VECT(SCIF0_ERI, 0x880), INTC_VECT(SCIF0_RXI, 0x8a0), @@ -79,10 +79,7 @@ static struct intc_prio_reg prio_registers[] __initdata = { { 0xa4000016, 0, 16, 4, /* IPRC */ { IRQ3, IRQ2, IRQ1, IRQ0 } }, { 0xa4000018, 0, 16, 4, /* IPRD */ { 0, 0, IRQ5, IRQ4 } }, { 0xa400001a, 0, 16, 4, /* IPRE */ { DMAC1, SCIF0, SCIF1 } }, - { 0xa4080000, 0, 16, 4, /* IPRF */ { 0, DMAC2 } }, -#ifdef CONFIG_CPU_SUBTYPE_SH7710 - { 0xa4080000, 0, 16, 4, /* IPRF */ { IPSEC } }, -#endif + { 0xa4080000, 0, 16, 4, /* IPRF */ { IPSEC, DMAC2 } }, { 0xa4080002, 0, 16, 4, /* IPRG */ { EDMAC0, EDMAC1, EDMAC2 } }, { 0xa4080004, 0, 16, 4, /* IPRH */ { 0, 0, 0, SIOF0 } }, { 0xa4080006, 0, 16, 4, /* IPRI */ { 0, 0, SIOF1 } }, @@ -91,14 +88,6 @@ static struct intc_prio_reg prio_registers[] __initdata = { static DECLARE_INTC_DESC(intc_desc, "sh7710", vectors, groups, NULL, prio_registers, NULL); -static struct intc_vect vectors_irq[] __initdata = { - INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620), - INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660), -}; - -static DECLARE_INTC_DESC(intc_desc_irq, "sh7710-irq", vectors_irq, NULL, - NULL, prio_registers, NULL); - static struct resource rtc_resources[] = { [0] = { .start = 0xa413fec0, @@ -170,16 +159,8 @@ static int __init sh7710_devices_setup(void) } __initcall(sh7710_devices_setup); -void __init plat_irq_setup_pins(int mode) -{ - if (mode == IRQ_MODE_IRQ) { - register_intc_controller(&intc_desc_irq); - return; - } - BUG(); -} - void __init plat_irq_setup(void) { register_intc_controller(&intc_desc); + plat_irq_setup_sh3(); } diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7720.c b/arch/sh/kernel/cpu/sh3/setup-sh7720.c index 8028082527c55a82d835fc32f800a4262dc1bf06..f807a21b066c629e8e4ea636aa3021ffeddccae1 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7720.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7720.c @@ -19,10 +19,6 @@ #include #include -#define INTC_ICR1 0xA4140010UL -#define INTC_ICR_IRLM 0x4000 -#define INTC_ICR_IRQ (~INTC_ICR_IRLM) - static struct resource rtc_resources[] = { [0] = { .start = 0xa413fec0, @@ -170,6 +166,7 @@ enum { }; static struct intc_vect vectors[] __initdata = { + /* IRQ0->5 are handled in setup-sh3.c */ INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420), INTC_VECT(TMU2, 0x440), INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0), INTC_VECT(RTC_CUI, 0x4c0), @@ -214,11 +211,7 @@ static struct intc_prio_reg prio_registers[] __initdata = { { 0xA414FEE4UL, 0, 16, 4, /* IPRB */ { WDT, REF_RCMI, SIM, 0 } }, { 0xA4140016UL, 0, 16, 4, /* IPRC */ { IRQ3, IRQ2, IRQ1, IRQ0 } }, { 0xA4140018UL, 0, 16, 4, /* IPRD */ { USBF_SPD, TMU_SUNI, IRQ5, IRQ4 } }, -#if defined(CONFIG_CPU_SUBTYPE_SH7720) { 0xA414001AUL, 0, 16, 4, /* IPRE */ { DMAC1, 0, LCDC, SSL } }, -#else - { 0xA414001AUL, 0, 16, 4, /* IPRE */ { DMAC1, 0, LCDC, 0 } }, -#endif { 0xA4080000UL, 0, 16, 4, /* IPRF */ { ADC, DMAC2, USBFI, CMT } }, { 0xA4080002UL, 0, 16, 4, /* IPRG */ { SCIF0, SCIF1, 0, 0 } }, { 0xA4080004UL, 0, 16, 4, /* IPRH */ { PINT07, PINT815, TPU, IIC } }, @@ -229,32 +222,8 @@ static struct intc_prio_reg prio_registers[] __initdata = { static DECLARE_INTC_DESC(intc_desc, "sh7720", vectors, groups, NULL, prio_registers, NULL); -static struct intc_sense_reg sense_registers[] __initdata = { - { INTC_ICR1, 16, 2, { 0, 0, IRQ5, IRQ4, IRQ3, IRQ2, IRQ1, IRQ0 } }, -}; - -static struct intc_vect vectors_irq[] __initdata = { - INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620), - INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660), - INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0), -}; - -static DECLARE_INTC_DESC(intc_irq_desc, "sh7720-irq", vectors_irq, - NULL, NULL, prio_registers, sense_registers); - -void __init plat_irq_setup_pins(int mode) -{ - switch (mode) { - case IRQ_MODE_IRQ: - ctrl_outw(ctrl_inw(INTC_ICR1) & INTC_ICR_IRQ, INTC_ICR1); - register_intc_controller(&intc_irq_desc); - break; - default: - BUG(); - } -} - void __init plat_irq_setup(void) { register_intc_controller(&intc_desc); + plat_irq_setup_sh3(); } diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c index 805535aa505e42dbaddefb5f0ab2681f39a91922..27fa81bef6a07f4a4b1cfceb525dba54ed706fb1 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c @@ -26,7 +26,7 @@ static int pfc_divisors[] = { 1, 1, 1, 1, 1, 1, 1, 18, static void master_clk_init(struct clk *clk) { - clk->rate *= 36; + clk->rate *= pfc_divisors[ctrl_inl(FRQMR1) & 0x000f]; } static struct clk_ops sh7785_master_clk_ops = { diff --git a/arch/sh/kernel/cpu/sh5/entry.S b/arch/sh/kernel/cpu/sh5/entry.S index ba8750176d9172113c49ec538de4a83066b57ad5..05372ed6c5686c0dd346853eefb131d9848bbf6a 100644 --- a/arch/sh/kernel/cpu/sh5/entry.S +++ b/arch/sh/kernel/cpu/sh5/entry.S @@ -143,12 +143,22 @@ resvec_save_area: trap_jtable: .long do_exception_error /* 0x000 */ .long do_exception_error /* 0x020 */ +#ifdef CONFIG_MMU .long tlb_miss_load /* 0x040 */ .long tlb_miss_store /* 0x060 */ +#else + .long do_exception_error + .long do_exception_error +#endif ! ARTIFICIAL pseudo-EXPEVT setting .long do_debug_interrupt /* 0x080 */ +#ifdef CONFIG_MMU .long tlb_miss_load /* 0x0A0 */ .long tlb_miss_store /* 0x0C0 */ +#else + .long do_exception_error + .long do_exception_error +#endif .long do_address_error_load /* 0x0E0 */ .long do_address_error_store /* 0x100 */ #ifdef CONFIG_SH_FPU @@ -185,10 +195,18 @@ trap_jtable: .endr .long do_IRQ /* 0xA00 */ .long do_IRQ /* 0xA20 */ +#ifdef CONFIG_MMU .long itlb_miss_or_IRQ /* 0xA40 */ +#else + .long do_IRQ +#endif .long do_IRQ /* 0xA60 */ .long do_IRQ /* 0xA80 */ +#ifdef CONFIG_MMU .long itlb_miss_or_IRQ /* 0xAA0 */ +#else + .long do_IRQ +#endif .long do_exception_error /* 0xAC0 */ .long do_address_error_exec /* 0xAE0 */ .rept 8 @@ -274,6 +292,7 @@ not_a_tlb_miss: * Instead of '.space 1024-TEXT_SIZE' place the RESVEC * block making sure the final alignment is correct. */ +#ifdef CONFIG_MMU tlb_miss: synco /* TAKum03020 (but probably a good idea anyway.) */ putcon SP, KCR1 @@ -377,6 +396,9 @@ fixup_to_invoke_general_handler: getcon KCR1, SP pta handle_exception, tr0 blink tr0, ZERO +#else /* CONFIG_MMU */ + .balign 256 +#endif /* NB TAKE GREAT CARE HERE TO ENSURE THAT THE INTERRUPT CODE DOES END UP AT VBR+0x600 */ @@ -1103,6 +1125,7 @@ restore_all: * fpu_error_or_IRQ? is a helper to deflect to the right cause. * */ +#ifdef CONFIG_MMU tlb_miss_load: or SP, ZERO, r2 or ZERO, ZERO, r3 /* Read */ @@ -1132,6 +1155,7 @@ call_do_page_fault: movi do_page_fault, r6 ptabs r6, tr0 blink tr0, ZERO +#endif /* CONFIG_MMU */ fpu_error_or_IRQA: pta its_IRQ, tr0 @@ -1481,6 +1505,7 @@ poke_real_address_q: ptabs LINK, tr0 blink tr0, r63 +#ifdef CONFIG_MMU /* * --- User Access Handling Section */ @@ -1604,6 +1629,7 @@ ___clear_user_exit: ptabs LINK, tr0 blink tr0, ZERO +#endif /* CONFIG_MMU */ /* * int __strncpy_from_user(unsigned long __dest, unsigned long __src, @@ -2014,9 +2040,11 @@ sa_default_restorer: .global asm_uaccess_start /* Just a marker */ asm_uaccess_start: +#ifdef CONFIG_MMU .long ___copy_user1, ___copy_user_exit .long ___copy_user2, ___copy_user_exit .long ___clear_user1, ___clear_user_exit +#endif .long ___strncpy_from_user1, ___strncpy_from_user_exit .long ___strnlen_user1, ___strnlen_user_exit .long ___get_user_asm_b1, ___get_user_asm_b_exit diff --git a/arch/sh/kernel/cpu/sh5/probe.c b/arch/sh/kernel/cpu/sh5/probe.c index 31f8cb0f6374ac71d517fb04c058a99b3a7f0642..92ad844b5c1220a349944f474d881767715aab1a 100644 --- a/arch/sh/kernel/cpu/sh5/probe.c +++ b/arch/sh/kernel/cpu/sh5/probe.c @@ -15,6 +15,7 @@ #include #include #include +#include int __init detect_cpu_and_cache_system(void) { @@ -67,5 +68,8 @@ int __init detect_cpu_and_cache_system(void) set_bit(SH_CACHE_MODE_WB, &(boot_cpu_data.dcache.flags)); #endif + /* Setup some I/D TLB defaults */ + sh64_tlb_init(); + return 0; } diff --git a/arch/sh/kernel/early_printk.c b/arch/sh/kernel/early_printk.c index 957f256115434fa866ba16cd2f2bccc80664c23c..6b7d166694e28fecc3f949b66cb94ae8c2e53950 100644 --- a/arch/sh/kernel/early_printk.c +++ b/arch/sh/kernel/early_printk.c @@ -141,7 +141,9 @@ static void scif_sercon_init(char *s) */ static void scif_sercon_init(char *s) { + struct uart_port *port = &scif_port; unsigned baud = DEFAULT_BAUD; + unsigned int status; char *e; if (*s == ',') @@ -160,19 +162,25 @@ static void scif_sercon_init(char *s) baud = DEFAULT_BAUD; } - ctrl_outw(0, scif_port.mapbase + 8); - ctrl_outw(0, scif_port.mapbase); + do { + status = sci_in(port, SCxSR); + } while (!(status & SCxSR_TEND(port))); + + sci_out(port, SCSCR, 0); /* TE=0, RE=0 */ + sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST); + sci_out(port, SCSMR, 0); /* Set baud rate */ - ctrl_outb((CONFIG_SH_PCLK_FREQ + 16 * baud) / - (32 * baud) - 1, scif_port.mapbase + 4); - - ctrl_outw(12, scif_port.mapbase + 24); - ctrl_outw(8, scif_port.mapbase + 24); - ctrl_outw(0, scif_port.mapbase + 32); - ctrl_outw(0x60, scif_port.mapbase + 16); - ctrl_outw(0, scif_port.mapbase + 36); - ctrl_outw(0x30, scif_port.mapbase + 8); + sci_out(port, SCBRR, (CONFIG_SH_PCLK_FREQ + 16 * baud) / + (32 * baud) - 1); + udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */ + + sci_out(port, SCSPTR, 0); + sci_out(port, SCxSR, 0x60); + sci_out(port, SCLSR, 0); + + sci_out(port, SCFCR, 0); + sci_out(port, SCSCR, 0x30); /* TE=1, RE=1 */ } #endif /* defined(CONFIG_CPU_SUBTYPE_SH7720) */ #endif /* !defined(CONFIG_SH_STANDARD_BIOS) */ diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S index 926b2e7b11c13a602fcce925c07439e1cdb09229..718bd2356b34bf109a9608d0b6b7d20549dc310a 100644 --- a/arch/sh/kernel/entry-common.S +++ b/arch/sh/kernel/entry-common.S @@ -1,9 +1,6 @@ -/* $Id: entry.S,v 1.37 2004/06/11 13:02:46 doyu Exp $ - * - * linux/arch/sh/entry.S - * +/* * Copyright (C) 1999, 2000, 2002 Niibe Yutaka - * Copyright (C) 2003 Paul Mundt + * Copyright (C) 2003 - 2008 Paul Mundt * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -262,6 +259,7 @@ __restore_all: .align 2 syscall_badsys: ! Bad syscall number + get_current_thread_info r8, r0 mov #-ENOSYS, r0 bra resume_userspace mov.l r0, @(OFF_R0,r15) ! Return value @@ -281,7 +279,9 @@ debug_trap: mov.l 1f, r8 add r0, r8 mov.l @r8, r8 - jmp @r8 + jsr @r8 + nop + bra __restore_all nop .align 2 diff --git a/arch/sh/kernel/head_32.S b/arch/sh/kernel/head_32.S index d67d7ed09f2242283fb5cf666149a5c7cb8d0e4b..ae0a382a82ebbf0f18d54767413c3d31ff87685a 100644 --- a/arch/sh/kernel/head_32.S +++ b/arch/sh/kernel/head_32.S @@ -30,8 +30,8 @@ ENTRY(empty_zero_page) .long 0 /* RAMDISK_FLAGS */ .long 0x0200 /* ORIG_ROOT_DEV */ .long 1 /* LOADER_TYPE */ - .long 0x00360000 /* INITRD_START */ - .long 0x000a0000 /* INITRD_SIZE */ + .long 0x00000000 /* INITRD_START */ + .long 0x00000000 /* INITRD_SIZE */ #ifdef CONFIG_32BIT .long 0x53453f00 + 32 /* "SE?" = 32 bit */ #else diff --git a/arch/sh/kernel/init_task.c b/arch/sh/kernel/init_task.c index f9bcc606127ed647fee003e7e9854bef4b5f7417..b151a25cb14de25f455e7ec26eebe124a23b2207 100644 --- a/arch/sh/kernel/init_task.c +++ b/arch/sh/kernel/init_task.c @@ -8,7 +8,6 @@ #include static struct fs_struct init_fs = INIT_FS; -static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS(init_signals); static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); struct pt_regs fake_swapper_regs; diff --git a/arch/sh/kernel/kgdb_stub.c b/arch/sh/kernel/kgdb_stub.c index d453c3a1c79f485377a870456cef74488d601e27..bf8ac4c716402c2b37178a8df448d318dd60af1c 100644 --- a/arch/sh/kernel/kgdb_stub.c +++ b/arch/sh/kernel/kgdb_stub.c @@ -274,8 +274,7 @@ static char *mem_to_hex(const char *mem, char *buf, const int count) } for (i = 0; i < count; i++) { ch = *mem++; - *buf++ = highhex(ch); - *buf++ = lowhex(ch); + buf = pack_hex_byte(buf, ch); } *buf = 0; return (buf); @@ -330,14 +329,6 @@ static char *ebin_to_mem(const char *buf, char *mem, int count) return mem; } -/* Pack a hex byte */ -static char *pack_hex_byte(char *pkt, int byte) -{ - *pkt++ = hexchars[(byte >> 4) & 0xf]; - *pkt++ = hexchars[(byte & 0xf)]; - return pkt; -} - /* Scan for the start char '$', read the packet and check the checksum */ static void get_packet(char *buffer, int buflen) { @@ -435,8 +426,8 @@ static void put_packet(char *buffer) /* '#' Separator, put high and low components of checksum */ put_debug_char('#'); - put_debug_char(highhex(checksum)); - put_debug_char(lowhex(checksum)); + put_debug_char(hex_asc_hi(checksum)); + put_debug_char(hex_asc_lo(checksum)); } while ((get_debug_char()) != '+'); /* While no ack */ } @@ -658,8 +649,8 @@ static void undo_single_step(void) static void send_signal_msg(const int signum) { out_buffer[0] = 'S'; - out_buffer[1] = highhex(signum); - out_buffer[2] = lowhex(signum); + out_buffer[1] = hex_asc_hi(signum); + out_buffer[2] = hex_asc_lo(signum); out_buffer[3] = 0; put_packet(out_buffer); } diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 284f66f1ebbeb812be6623c7111d820ccaa4ad01..bca2bbc575dbe034e7c0ded352c437997ee8308d 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -53,6 +53,7 @@ EXPORT_SYMBOL(cpu_data); * sh_mv= on the command line, prior to .machvec.init teardown. */ struct sh_machine_vector sh_mv = { .mv_name = "generic", }; +EXPORT_SYMBOL(sh_mv); #ifdef CONFIG_VT struct screen_info screen_info; @@ -76,11 +77,18 @@ static struct resource data_resource = { .flags = IORESOURCE_BUSY | IORESOURCE_MEM, }; +static struct resource bss_resource = { + .name = "Kernel bss", + .flags = IORESOURCE_BUSY | IORESOURCE_MEM, +}; + unsigned long memory_start; EXPORT_SYMBOL(memory_start); unsigned long memory_end = 0; EXPORT_SYMBOL(memory_end); +static struct resource mem_resources[MAX_NUMNODES]; + int l1i_cache_shape, l1d_cache_shape, l2_cache_shape; static int __init early_parse_mem(char *p) @@ -169,6 +177,40 @@ static inline void __init reserve_crashkernel(void) {} #endif +void __init __add_active_range(unsigned int nid, unsigned long start_pfn, + unsigned long end_pfn) +{ + struct resource *res = &mem_resources[nid]; + + WARN_ON(res->name); /* max one active range per node for now */ + + res->name = "System RAM"; + res->start = start_pfn << PAGE_SHIFT; + res->end = (end_pfn << PAGE_SHIFT) - 1; + res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; + if (request_resource(&iomem_resource, res)) { + pr_err("unable to request memory_resource 0x%lx 0x%lx\n", + start_pfn, end_pfn); + return; + } + + /* + * We don't know which RAM region contains kernel data, + * so we try it repeatedly and let the resource manager + * test it. + */ + request_resource(res, &code_resource); + request_resource(res, &data_resource); + request_resource(res, &bss_resource); + +#ifdef CONFIG_KEXEC + if (crashk_res.start != crashk_res.end) + request_resource(res, &crashk_res); +#endif + + add_active_range(nid, start_pfn, end_pfn); +} + void __init setup_bootmem_allocator(unsigned long free_pfn) { unsigned long bootmap_size; @@ -181,7 +223,7 @@ void __init setup_bootmem_allocator(unsigned long free_pfn) bootmap_size = init_bootmem_node(NODE_DATA(0), free_pfn, min_low_pfn, max_low_pfn); - add_active_range(0, min_low_pfn, max_low_pfn); + __add_active_range(0, min_low_pfn, max_low_pfn); register_bootmem_low_pages(); node_set_online(0); @@ -250,6 +292,17 @@ void __init setup_arch(char **cmdline_p) ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV); + printk(KERN_NOTICE "Boot params:\n" + "... MOUNT_ROOT_RDONLY - %08lx\n" + "... RAMDISK_FLAGS - %08lx\n" + "... ORIG_ROOT_DEV - %08lx\n" + "... LOADER_TYPE - %08lx\n" + "... INITRD_START - %08lx\n" + "... INITRD_SIZE - %08lx\n", + MOUNT_ROOT_RDONLY, RAMDISK_FLAGS, + ORIG_ROOT_DEV, LOADER_TYPE, + INITRD_START, INITRD_SIZE); + #ifdef CONFIG_BLK_DEV_RAM rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK; rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0); @@ -267,6 +320,8 @@ void __init setup_arch(char **cmdline_p) code_resource.end = virt_to_phys(_etext)-1; data_resource.start = virt_to_phys(_etext); data_resource.end = virt_to_phys(_edata)-1; + bss_resource.start = virt_to_phys(__bss_start); + bss_resource.end = virt_to_phys(_ebss)-1; memory_start = (unsigned long)__va(__MEMORY_START); if (!memory_end) diff --git a/arch/sh/kernel/sh_ksyms_32.c b/arch/sh/kernel/sh_ksyms_32.c index 6d405462cee84774939382483436e8c69c0445fd..8f916536719c81261b443225d85e618baff4bd50 100644 --- a/arch/sh/kernel/sh_ksyms_32.c +++ b/arch/sh/kernel/sh_ksyms_32.c @@ -20,8 +20,6 @@ extern int dump_fpu(struct pt_regs *, elf_fpregset_t *); extern struct hw_interrupt_type no_irq_type; -EXPORT_SYMBOL(sh_mv); - /* platform dependent support */ EXPORT_SYMBOL(dump_fpu); EXPORT_SYMBOL(kernel_thread); diff --git a/arch/sh/kernel/sh_ksyms_64.c b/arch/sh/kernel/sh_ksyms_64.c index a310c9707f03266400cbeafa6c37545584d1bd4d..9324d32adacc669c6159a39f6752f59cf286c394 100644 --- a/arch/sh/kernel/sh_ksyms_64.c +++ b/arch/sh/kernel/sh_ksyms_64.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -29,25 +30,50 @@ extern int dump_fpu(struct pt_regs *, elf_fpregset_t *); EXPORT_SYMBOL(dump_fpu); EXPORT_SYMBOL(kernel_thread); +#if !defined(CONFIG_CACHE_OFF) && defined(CONFIG_MMU) +EXPORT_SYMBOL(clear_user_page); +#endif + +#ifndef CONFIG_CACHE_OFF +EXPORT_SYMBOL(flush_dcache_page); +#endif + /* Networking helper routines. */ +EXPORT_SYMBOL(csum_partial); EXPORT_SYMBOL(csum_partial_copy_nocheck); +#ifdef CONFIG_IPV6 +EXPORT_SYMBOL(csum_ipv6_magic); +#endif #ifdef CONFIG_VT EXPORT_SYMBOL(screen_info); #endif +EXPORT_SYMBOL(__put_user_asm_b); +EXPORT_SYMBOL(__put_user_asm_w); EXPORT_SYMBOL(__put_user_asm_l); +EXPORT_SYMBOL(__put_user_asm_q); +EXPORT_SYMBOL(__get_user_asm_b); +EXPORT_SYMBOL(__get_user_asm_w); EXPORT_SYMBOL(__get_user_asm_l); +EXPORT_SYMBOL(__get_user_asm_q); +EXPORT_SYMBOL(__strnlen_user); +EXPORT_SYMBOL(__strncpy_from_user); +EXPORT_SYMBOL(clear_page); +EXPORT_SYMBOL(__clear_user); EXPORT_SYMBOL(copy_page); EXPORT_SYMBOL(__copy_user); EXPORT_SYMBOL(empty_zero_page); EXPORT_SYMBOL(memcpy); EXPORT_SYMBOL(__udelay); EXPORT_SYMBOL(__ndelay); +EXPORT_SYMBOL(__const_udelay); /* Ugh. These come in from libgcc.a at link time. */ #define DECLARE_EXPORT(name) extern void name(void);EXPORT_SYMBOL(name) DECLARE_EXPORT(__sdivsi3); +DECLARE_EXPORT(__sdivsi3_2); DECLARE_EXPORT(__muldi3); DECLARE_EXPORT(__udivsi3); +DECLARE_EXPORT(__div_table); diff --git a/arch/sh/kernel/time_64.c b/arch/sh/kernel/time_64.c index 898977ee2030d99ca792425f22e58464b9ee8a0d..022a55f1c1d46b510c1efa784d1376d342104372 100644 --- a/arch/sh/kernel/time_64.c +++ b/arch/sh/kernel/time_64.c @@ -172,6 +172,7 @@ void do_gettimeofday(struct timeval *tv) tv->tv_sec = sec; tv->tv_usec = usec; } +EXPORT_SYMBOL(do_gettimeofday); int do_settimeofday(struct timespec *tv) { @@ -240,7 +241,7 @@ static inline void do_timer_interrupt(void) * the irq version of write_lock because as just said we have irq * locally disabled. -arca */ - write_lock(&xtime_lock); + write_seqlock(&xtime_lock); asm ("getcon cr62, %0" : "=r" (current_ctc)); ctc_last_interrupt = (unsigned long) current_ctc; @@ -266,7 +267,7 @@ static inline void do_timer_interrupt(void) /* do it again in 60 s */ last_rtc_update = xtime.tv_sec - 600; } - write_unlock(&xtime_lock); + write_sequnlock(&xtime_lock); #ifndef CONFIG_SMP update_process_times(user_mode(get_irq_regs())); diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c index a3bdc68ef02c75adcdbfaca4b5d61c3218c60521..438f1ebcc45330cc0a5d320fee82a4b6840bcf1d 100644 --- a/arch/sh/kernel/traps.c +++ b/arch/sh/kernel/traps.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #ifdef CONFIG_BUG @@ -21,7 +22,14 @@ static void handle_BUG(struct pt_regs *regs) int is_valid_bugaddr(unsigned long addr) { - return addr >= PAGE_OFFSET; + unsigned short opcode; + + if (addr < PAGE_OFFSET) + return 0; + if (probe_kernel_address((u16 *)addr, opcode)) + return 0; + + return opcode == TRAPA_BUG_OPCODE; } #endif diff --git a/arch/sh/lib/memcpy-sh4.S b/arch/sh/lib/memcpy-sh4.S index 560bc17eebdd6748d1e49e40730a476b3cbe1c3a..459fa92a7c5311b02c1e1f21c74536eb27432ed2 100644 --- a/arch/sh/lib/memcpy-sh4.S +++ b/arch/sh/lib/memcpy-sh4.S @@ -126,10 +126,10 @@ mov.l r3,@-r0 ! 30 LS #else -3: mov r1,r3 ! OPQR +3: mov r7,r3 ! OPQR shlr8 r3 ! xOPQ - mov.l @(r0,r5),r1 ! KLMN - mov r1,r6 + mov.l @(r0,r5),r7 ! KLMN + mov r7,r6 shll16 r6 shll8 r6 ! Nxxx or r6,r3 ! NOPQ @@ -733,24 +733,24 @@ ENTRY(memcpy) movca.l r0,@r1 ! 40 LS (latency=3-7) add #-0x1c, r1 ! 50 EX - mov.l r3, @(0x1c,r1) ! 33 LS + mov.l r3, @(0x18,r1) ! 33 LS xtrct r11, r10 ! 48 EX - mov.l r6, @(0x18,r1) ! 33 LS + mov.l r6, @(0x14,r1) ! 33 LS xtrct r12, r11 ! 48 EX - mov.l r7, @(0x14,r1) ! 33 LS + mov.l r7, @(0x10,r1) ! 33 LS - mov.l r8, @(0x10,r1) ! 33 LS - add #-0x3e, r5 ! 50 EX + mov.l r8, @(0x0c,r1) ! 33 LS + add #-0x1e, r5 ! 50 EX - mov.l r9, @(0x0c,r1) ! 33 LS + mov.l r9, @(0x08,r1) ! 33 LS cmp/eq r2,r1 ! 54 MT - mov.l r10, @(0x08,r1) ! 33 LS + mov.l r10, @(0x04,r1) ! 33 LS bf/s 2b ! 109 BR - mov.l r11, @(0x04,r1) ! 33 LS + mov.l r11, @(0x00,r1) ! 33 LS #endif mov.l @r15+, r12 diff --git a/arch/sh/lib64/dbg.c b/arch/sh/lib64/dbg.c index 75825ef6e0846443be7a549a1671961d64607de9..2fb8eaf6de60a01c6bbaae80d7839b0a2d1778bc 100644 --- a/arch/sh/lib64/dbg.c +++ b/arch/sh/lib64/dbg.c @@ -186,8 +186,8 @@ void evt_debug(int evt, int ret_addr, int event, int tra, struct pt_regs *regs) rr->pc = regs->pc; if (sp < stack_bottom + 3092) { - printk("evt_debug : stack underflow report\n"); int i, j; + printk("evt_debug : stack underflow report\n"); for (j=0, i = event_ptr; j<16; j++) { rr = event_ring + i; printk("evt=%08x event=%08x tra=%08x pid=%5d sp=%08lx pc=%08lx\n", diff --git a/arch/sh/mm/Makefile_64 b/arch/sh/mm/Makefile_64 index cbd6aa33c5ac108720c1e83db535a54b995976b6..0d92a8a3ac9a1e312870740b7d982e1eafebb021 100644 --- a/arch/sh/mm/Makefile_64 +++ b/arch/sh/mm/Makefile_64 @@ -2,10 +2,11 @@ # Makefile for the Linux SuperH-specific parts of the memory manager. # -obj-y := init.o extable_64.o consistent.o +obj-y := init.o consistent.o -mmu-y := tlb-nommu.o pg-nommu.o -mmu-$(CONFIG_MMU) := fault_64.o ioremap_64.o tlbflush_64.o tlb-sh5.o +mmu-y := tlb-nommu.o pg-nommu.o extable_32.o +mmu-$(CONFIG_MMU) := fault_64.o ioremap_64.o tlbflush_64.o tlb-sh5.o \ + extable_64.o ifndef CONFIG_CACHE_OFF obj-y += cache-sh5.o diff --git a/arch/sh/mm/cache-sh5.c b/arch/sh/mm/cache-sh5.c index 3877321fcede375cd8698cf98c2e9884798ac209..9e277ec7d5360e1b46e0a7ee0b934e9e8a75c08c 100644 --- a/arch/sh/mm/cache-sh5.c +++ b/arch/sh/mm/cache-sh5.c @@ -714,6 +714,7 @@ void flush_cache_sigtramp(unsigned long vaddr) sh64_icache_inv_current_user_range(vaddr, end); } +#ifdef CONFIG_MMU /* * These *MUST* lie in an area of virtual address space that's otherwise * unused. @@ -830,3 +831,4 @@ void clear_user_page(void *to, unsigned long address, struct page *page) else sh64_clear_user_page_coloured(to, address); } +#endif diff --git a/arch/sh/mm/ioremap_64.c b/arch/sh/mm/ioremap_64.c index cea224c3e49b6049b54edd6d5a6e782a02728dc2..6e0be24d26e2c3cd9168ff3ac7203d4f0466b298 100644 --- a/arch/sh/mm/ioremap_64.c +++ b/arch/sh/mm/ioremap_64.c @@ -343,6 +343,7 @@ unsigned long onchip_remap(unsigned long phys, unsigned long size, const char *n return shmedia_alloc_io(phys, size, name); } +EXPORT_SYMBOL(onchip_remap); void onchip_unmap(unsigned long vaddr) { @@ -370,6 +371,7 @@ void onchip_unmap(unsigned long vaddr) kfree(res); } } +EXPORT_SYMBOL(onchip_unmap); #ifdef CONFIG_PROC_FS static int diff --git a/arch/sh/mm/numa.c b/arch/sh/mm/numa.c index 2de7302724fc188cd6a8bf9680470bc55fad2dc7..1663199ce888649a6ecd0368f2c114ae7866a38e 100644 --- a/arch/sh/mm/numa.c +++ b/arch/sh/mm/numa.c @@ -59,7 +59,7 @@ void __init setup_bootmem_node(int nid, unsigned long start, unsigned long end) free_pfn = start_pfn = start >> PAGE_SHIFT; end_pfn = end >> PAGE_SHIFT; - add_active_range(nid, start_pfn, end_pfn); + __add_active_range(nid, start_pfn, end_pfn); /* Node-local pgdat */ NODE_DATA(nid) = pfn_to_kaddr(free_pfn); diff --git a/arch/sh/tools/mach-types b/arch/sh/tools/mach-types index 987c6682bf9906a51f120dc73cc478b00a07d8d8..1bba7d36be9067de687cbb2d28065393b2e1369a 100644 --- a/arch/sh/tools/mach-types +++ b/arch/sh/tools/mach-types @@ -28,7 +28,6 @@ HD64465 HD64465 7751SYSTEMH SH_7751_SYSTEMH HP6XX SH_HP6XX DREAMCAST SH_DREAMCAST -MPC1211 SH_MPC1211 SNAPGEAR SH_SECUREEDGE5410 EDOSK7705 SH_EDOSK7705 SH4202_MICRODEV SH_SH4202_MICRODEV diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S index 57d1bbdd0bd2aa5f996b9df420ff50415d64573e..4bcfe54f878d3250c98ed613cdc899770aaaa850 100644 --- a/arch/sparc/kernel/entry.S +++ b/arch/sparc/kernel/entry.S @@ -1306,6 +1306,8 @@ ret_from_fork: .align 4 .globl linux_sparc_syscall linux_sparc_syscall: + sethi %hi(PSR_SYSCALL), %l4 + or %l0, %l4, %l0 /* Direct access to user regs, must faster. */ cmp %g1, NR_SYSCALLS bgeu linux_sparc_ni_syscall diff --git a/arch/sparc/kernel/init_task.c b/arch/sparc/kernel/init_task.c index d9d4f96360c7bff691836f3683d7fce954b5311f..8e64ebc445ef8c158f8fd594ed424fd24efda6e6 100644 --- a/arch/sparc/kernel/init_task.c +++ b/arch/sparc/kernel/init_task.c @@ -9,7 +9,6 @@ #include static struct fs_struct init_fs = INIT_FS; -static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS(init_signals); static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); struct mm_struct init_mm = INIT_MM(init_mm); diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c index e7f35198ae34943f5adfeeedd7223014dfe146ff..da48d248cc17d6d9da5f9cb4faf96d1cb41e17e2 100644 --- a/arch/sparc/kernel/process.c +++ b/arch/sparc/kernel/process.c @@ -419,14 +419,26 @@ asmlinkage int sparc_do_fork(unsigned long clone_flags, unsigned long stack_size) { unsigned long parent_tid_ptr, child_tid_ptr; + unsigned long orig_i1 = regs->u_regs[UREG_I1]; + long ret; parent_tid_ptr = regs->u_regs[UREG_I2]; child_tid_ptr = regs->u_regs[UREG_I4]; - return do_fork(clone_flags, stack_start, - regs, stack_size, - (int __user *) parent_tid_ptr, - (int __user *) child_tid_ptr); + ret = do_fork(clone_flags, stack_start, + regs, stack_size, + (int __user *) parent_tid_ptr, + (int __user *) child_tid_ptr); + + /* If we get an error and potentially restart the system + * call, we're screwed because copy_thread() clobbered + * the parent's %o1. So detect that case and restore it + * here. + */ + if ((unsigned long)ret >= -ERESTART_RESTARTBLOCK) + regs->u_regs[UREG_I1] = orig_i1; + + return ret; } /* Copy a Sparc thread. The fork() return value conventions @@ -626,11 +638,6 @@ asmlinkage int sparc_execve(struct pt_regs *regs) (char __user * __user *)regs->u_regs[base + UREG_I2], regs); putname(filename); - if (error == 0) { - task_lock(current); - current->ptrace &= ~PT_DTRACE; - task_unlock(current); - } out: return error; } diff --git a/arch/sparc/kernel/ptrace.c b/arch/sparc/kernel/ptrace.c index 7f44ae69b29e52dd2ae7ff0a647d7ace053211fc..81f3b929743f12c17ec44642acb58f6526d4319c 100644 --- a/arch/sparc/kernel/ptrace.c +++ b/arch/sparc/kernel/ptrace.c @@ -170,8 +170,8 @@ static int genregs32_set(struct task_struct *target, switch (pos) { case 32: /* PSR */ psr = regs->psr; - psr &= ~PSR_ICC; - psr |= (reg & PSR_ICC); + psr &= ~(PSR_ICC | PSR_SYSCALL); + psr |= (reg & (PSR_ICC | PSR_SYSCALL)); regs->psr = psr; break; case 33: /* PC */ @@ -441,6 +441,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) break; default: + if (request == PTRACE_SPARC_DETACH) + request = PTRACE_DETACH; ret = ptrace_request(child, request, addr, data); break; } diff --git a/arch/sparc/kernel/rtrap.S b/arch/sparc/kernel/rtrap.S index 77ca6fd812538b2c2dae9b2c40c29f2303b6bdde..ab818cdc4cc0da412da435093b5cce37c30da0b1 100644 --- a/arch/sparc/kernel/rtrap.S +++ b/arch/sparc/kernel/rtrap.S @@ -50,8 +50,9 @@ rtrap_7win_patch5: and %g1, 0x7f, %g1 ret_trap_entry: ret_trap_lockless_ipi: andcc %t_psr, PSR_PS, %g0 + sethi %hi(PSR_SYSCALL), %g1 be 1f - nop + andn %t_psr, %g1, %t_psr wr %t_psr, 0x0, %psr b ret_trap_kernel @@ -73,7 +74,6 @@ signal_p: ld [%sp + STACKFRAME_SZ + PT_PSR], %t_psr mov %l5, %o1 - mov %l6, %o2 call do_signal add %sp, STACKFRAME_SZ, %o0 ! pt_regs ptr @@ -81,6 +81,8 @@ signal_p: ld [%sp + STACKFRAME_SZ + PT_PSR], %t_psr clr %l6 ret_trap_continue: + sethi %hi(PSR_SYSCALL), %g1 + andn %t_psr, %g1, %t_psr wr %t_psr, 0x0, %psr WRITE_PAUSE @@ -137,8 +139,9 @@ ret_trap_userwins_ok: LOAD_PT_PRIV(sp, t_psr, t_pc, t_npc) or %t_pc, %t_npc, %g2 andcc %g2, 0x3, %g0 + sethi %hi(PSR_SYSCALL), %g2 be 1f - nop + andn %t_psr, %g2, %t_psr b ret_trap_unaligned_pc add %sp, STACKFRAME_SZ, %o0 @@ -201,6 +204,8 @@ rtrap_patch5: and %g1, 0xff, %g1 1: LOAD_PT_ALL(sp, t_psr, t_pc, t_npc, g1) 2: + sethi %hi(PSR_SYSCALL), %twin_tmp1 + andn %t_psr, %twin_tmp1, %t_psr wr %t_psr, 0x0, %psr WRITE_PAUSE diff --git a/arch/sparc/kernel/signal.c b/arch/sparc/kernel/signal.c index 3c312290c3c288eda469d5272e71c3ae46226321..3fd1df9f9ba7e849609f5018d443378a301fb2e4 100644 --- a/arch/sparc/kernel/signal.c +++ b/arch/sparc/kernel/signal.c @@ -145,6 +145,9 @@ asmlinkage void do_sigreturn(struct pt_regs *regs) regs->psr = (up_psr & ~(PSR_ICC | PSR_EF)) | (regs->psr & (PSR_ICC | PSR_EF)); + /* Prevent syscall restart. */ + pt_regs_clear_syscall(regs); + err |= __get_user(fpu_save, &sf->fpu_save); if (fpu_save) @@ -199,6 +202,9 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs) regs->psr = (regs->psr & ~PSR_ICC) | (psr & PSR_ICC); + /* Prevent syscall restart. */ + pt_regs_clear_syscall(regs); + err |= __get_user(fpu_save, &sf->fpu_save); if (fpu_save) @@ -245,15 +251,29 @@ static inline int invalid_frame_pointer(void __user *fp, int fplen) static inline void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, unsigned long framesize) { - unsigned long sp; + unsigned long sp = regs->u_regs[UREG_FP]; - sp = regs->u_regs[UREG_FP]; + /* + * If we are on the alternate signal stack and would overflow it, don't. + * Return an always-bogus address instead so we will die with SIGSEGV. + */ + if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize))) + return (void __user *) -1L; /* This is the X/Open sanctioned signal stack switching. */ if (sa->sa_flags & SA_ONSTACK) { - if (!on_sig_stack(sp) && !((current->sas_ss_sp + current->sas_ss_size) & 7)) + if (sas_ss_flags(sp) == 0) sp = current->sas_ss_sp + current->sas_ss_size; } + + /* Always align the stack frame. This handles two cases. First, + * sigaltstack need not be mindful of platform specific stack + * alignment. Second, if we took this signal because the stack + * is not aligned properly, we'd like to take the signal cleanly + * and report that. + */ + sp &= ~7UL; + return (void __user *)(sp - framesize); } @@ -493,26 +513,36 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, * want to handle. Thus you cannot kill init even with a SIGKILL even by * mistake. */ -asmlinkage void do_signal(struct pt_regs * regs, unsigned long orig_i0, int restart_syscall) +asmlinkage void do_signal(struct pt_regs * regs, unsigned long orig_i0) { - siginfo_t info; - struct sparc_deliver_cookie cookie; struct k_sigaction ka; - int signr; + int restart_syscall; sigset_t *oldset; + siginfo_t info; + int signr; - cookie.restart_syscall = restart_syscall; - cookie.orig_i0 = orig_i0; + if (pt_regs_is_syscall(regs) && (regs->psr & PSR_C)) + restart_syscall = 1; + else + restart_syscall = 0; if (test_thread_flag(TIF_RESTORE_SIGMASK)) oldset = ¤t->saved_sigmask; else oldset = ¤t->blocked; - signr = get_signal_to_deliver(&info, &ka, regs, &cookie); + signr = get_signal_to_deliver(&info, &ka, regs, NULL); + + /* If the debugger messes with the program counter, it clears + * the software "in syscall" bit, directing us to not perform + * a syscall restart. + */ + if (restart_syscall && !pt_regs_is_syscall(regs)) + restart_syscall = 0; + if (signr > 0) { - if (cookie.restart_syscall) - syscall_restart(cookie.orig_i0, regs, &ka.sa); + if (restart_syscall) + syscall_restart(orig_i0, regs, &ka.sa); handle_signal(signr, &ka, &info, oldset, regs); /* a signal was successfully delivered; the saved @@ -524,16 +554,16 @@ asmlinkage void do_signal(struct pt_regs * regs, unsigned long orig_i0, int rest clear_thread_flag(TIF_RESTORE_SIGMASK); return; } - if (cookie.restart_syscall && + if (restart_syscall && (regs->u_regs[UREG_I0] == ERESTARTNOHAND || regs->u_regs[UREG_I0] == ERESTARTSYS || regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { /* replay the system call when we are done */ - regs->u_regs[UREG_I0] = cookie.orig_i0; + regs->u_regs[UREG_I0] = orig_i0; regs->pc -= 4; regs->npc -= 4; } - if (cookie.restart_syscall && + if (restart_syscall && regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { regs->u_regs[UREG_G1] = __NR_restart_syscall; regs->pc -= 4; @@ -585,27 +615,3 @@ do_sys_sigstack(struct sigstack __user *ssptr, struct sigstack __user *ossptr, out: return ret; } - -void ptrace_signal_deliver(struct pt_regs *regs, void *cookie) -{ - struct sparc_deliver_cookie *cp = cookie; - - if (cp->restart_syscall && - (regs->u_regs[UREG_I0] == ERESTARTNOHAND || - regs->u_regs[UREG_I0] == ERESTARTSYS || - regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { - /* replay the system call when we are done */ - regs->u_regs[UREG_I0] = cp->orig_i0; - regs->pc -= 4; - regs->npc -= 4; - cp->restart_syscall = 0; - } - - if (cp->restart_syscall && - regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { - regs->u_regs[UREG_G1] = __NR_restart_syscall; - regs->pc -= 4; - regs->npc -= 4; - cp->restart_syscall = 0; - } -} diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c index f188b5dc9fd001bec3691b03401408b5af655ce4..3c6b49a53ae82f8e7a77dc67b4445eb753591f6f 100644 --- a/arch/sparc/kernel/sys_sparc.c +++ b/arch/sparc/kernel/sys_sparc.c @@ -219,12 +219,11 @@ out: return err; } -int sparc_mmap_check(unsigned long addr, unsigned long len, unsigned long flags) +int sparc_mmap_check(unsigned long addr, unsigned long len) { if (ARCH_SUN4C_SUN4 && (len > 0x20000000 || - ((flags & MAP_FIXED) && - addr < 0xe0000000 && addr + len > 0x20000000))) + (addr < 0xe0000000 && addr + len > 0x20000000))) return -EINVAL; /* See asm-sparc/uaccess.h */ @@ -296,52 +295,14 @@ asmlinkage unsigned long sparc_mremap(unsigned long addr, unsigned long old_len, unsigned long new_len, unsigned long flags, unsigned long new_addr) { - struct vm_area_struct *vma; unsigned long ret = -EINVAL; - if (ARCH_SUN4C_SUN4) { - if (old_len > 0x20000000 || new_len > 0x20000000) - goto out; - if (addr < 0xe0000000 && addr + old_len > 0x20000000) - goto out; - } - if (old_len > TASK_SIZE - PAGE_SIZE || - new_len > TASK_SIZE - PAGE_SIZE) + + if (unlikely(sparc_mmap_check(addr, old_len))) + goto out; + if (unlikely(sparc_mmap_check(new_addr, new_len))) goto out; down_write(¤t->mm->mmap_sem); - if (flags & MREMAP_FIXED) { - if (ARCH_SUN4C_SUN4 && - new_addr < 0xe0000000 && - new_addr + new_len > 0x20000000) - goto out_sem; - if (new_addr + new_len > TASK_SIZE - PAGE_SIZE) - goto out_sem; - } else if ((ARCH_SUN4C_SUN4 && addr < 0xe0000000 && - addr + new_len > 0x20000000) || - addr + new_len > TASK_SIZE - PAGE_SIZE) { - unsigned long map_flags = 0; - struct file *file = NULL; - - ret = -ENOMEM; - if (!(flags & MREMAP_MAYMOVE)) - goto out_sem; - - vma = find_vma(current->mm, addr); - if (vma) { - if (vma->vm_flags & VM_SHARED) - map_flags |= MAP_SHARED; - file = vma->vm_file; - } - - new_addr = get_unmapped_area(file, addr, new_len, - vma ? vma->vm_pgoff : 0, - map_flags); - ret = new_addr; - if (new_addr & ~PAGE_MASK) - goto out_sem; - flags |= MREMAP_FIXED; - } ret = do_mremap(addr, old_len, new_len, flags, new_addr); -out_sem: up_write(¤t->mm->mmap_sem); out: return ret; diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig index aff93c9d13f45fb87e94c3100b599711a9efd085..76eb832527f29b093dd1d3232bcf420aa51ded8c 100644 --- a/arch/sparc64/defconfig +++ b/arch/sparc64/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.25 -# Sat Apr 26 03:11:06 2008 +# Linux kernel version: 2.6.26-rc2 +# Fri May 16 13:36:07 2008 # CONFIG_SPARC=y CONFIG_SPARC64=y @@ -74,6 +74,7 @@ CONFIG_SYSCTL=y # CONFIG_EMBEDDED is not set CONFIG_UID16=y CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set @@ -103,12 +104,14 @@ CONFIG_KPROBES=y CONFIG_KRETPROBES=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y +# CONFIG_HAVE_DMA_ATTRS is not set CONFIG_PROC_PAGE_MONITOR=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y CONFIG_MODVERSIONS=y @@ -170,6 +173,7 @@ CONFIG_HAVE_MEMORY_PRESENT=y CONFIG_SPARSEMEM_EXTREME=y CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y CONFIG_SPARSEMEM_VMEMMAP=y +CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_MIGRATION=y CONFIG_RESOURCES_64BIT=y @@ -402,7 +406,6 @@ CONFIG_IDEPCI_PCIBUS_ORDER=y CONFIG_BLK_DEV_IDEDMA_PCI=y # CONFIG_BLK_DEV_AEC62XX is not set CONFIG_BLK_DEV_ALI15X3=y -# CONFIG_WDC_ALI15X3 is not set # CONFIG_BLK_DEV_AMD74XX is not set # CONFIG_BLK_DEV_CMD64X is not set # CONFIG_BLK_DEV_TRIFLEX is not set @@ -609,6 +612,7 @@ CONFIG_NIU=m # CONFIG_MLX4_CORE is not set # CONFIG_TEHUTI is not set # CONFIG_BNX2X is not set +# CONFIG_SFC is not set # CONFIG_TR is not set # @@ -717,6 +721,7 @@ CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y # CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_DEVKMEM is not set # CONFIG_SERIAL_NONSTANDARD is not set # CONFIG_NOZOMI is not set @@ -793,12 +798,7 @@ CONFIG_I2C_ALGOBIT=y # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set # CONFIG_I2C_DEBUG_CHIP is not set - -# -# SPI support -# # CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set CONFIG_HWMON=y @@ -873,8 +873,17 @@ CONFIG_SSB_POSSIBLE=y # # Multimedia devices # + +# +# Multimedia core support +# # CONFIG_VIDEO_DEV is not set # CONFIG_DVB_CORE is not set +# CONFIG_VIDEO_MEDIA is not set + +# +# Multimedia drivers +# # CONFIG_DAB is not set # @@ -893,8 +902,8 @@ CONFIG_FB_CFB_IMAGEBLIT=y # CONFIG_FB_SYS_FILLRECT is not set # CONFIG_FB_SYS_COPYAREA is not set # CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set # CONFIG_FB_SYS_FOPS is not set -CONFIG_FB_DEFERRED_IO=y # CONFIG_FB_SVGALIB is not set # CONFIG_FB_MACMODES is not set # CONFIG_FB_BACKLIGHT is not set @@ -1099,6 +1108,10 @@ CONFIG_SND_SUN_CS4231=m # ALSA SoC audio for Freescale SOCs # +# +# SoC Audio for the Texas Instruments OMAP +# + # # Open Sound System # @@ -1135,10 +1148,12 @@ CONFIG_USB_DEVICEFS=y # # USB Host Controller Drivers # +# CONFIG_USB_C67X00_HCD is not set CONFIG_USB_EHCI_HCD=m # CONFIG_USB_EHCI_ROOT_HUB_TT is not set # CONFIG_USB_EHCI_TT_NEWSCHED is not set # CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set CONFIG_USB_OHCI_HCD=y # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set # CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set @@ -1173,6 +1188,7 @@ CONFIG_USB_STORAGE=m # CONFIG_USB_STORAGE_ALAUDA is not set # CONFIG_USB_STORAGE_ONETOUCH is not set # CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set # CONFIG_USB_LIBUSUAL is not set # @@ -1214,6 +1230,7 @@ CONFIG_USB_STORAGE=m # CONFIG_MMC is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set # CONFIG_INFINIBAND is not set # CONFIG_RTC_CLASS is not set # CONFIG_UIO is not set @@ -1367,6 +1384,7 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_PRINTK_TIME=y # CONFIG_ENABLE_WARN_DEPRECATED is not set CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=2048 CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_FS=y @@ -1377,6 +1395,7 @@ CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHED_DEBUG is not set CONFIG_SCHEDSTATS=y # CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set # CONFIG_SLUB_DEBUG_ON is not set # CONFIG_SLUB_STATS is not set # CONFIG_DEBUG_RT_MUTEXES is not set @@ -1402,6 +1421,8 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_LKDTM is not set # CONFIG_FAULT_INJECTION is not set # CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_DEBUG_DCFLUSH is not set # CONFIG_STACK_DEBUG is not set @@ -1503,6 +1524,7 @@ CONFIG_CRYPTO_HW=y # Library routines # CONFIG_BITREVERSE=y +# CONFIG_GENERIC_FIND_FIRST_BIT is not set CONFIG_CRC_CCITT=m CONFIG_CRC16=m # CONFIG_CRC_ITU_T is not set diff --git a/arch/sparc64/kernel/etrap.S b/arch/sparc64/kernel/etrap.S index b49d3b60bc0ca267cb79a61dc293c29d7faae83b..f25e1da3fd0307992d1f80c9b4ee5d5e466cbc3c 100644 --- a/arch/sparc64/kernel/etrap.S +++ b/arch/sparc64/kernel/etrap.S @@ -27,11 +27,12 @@ .text .align 64 - .globl etrap, etrap_irq, etraptl1 + .globl etrap_syscall, etrap, etrap_irq, etraptl1 etrap: rdpr %pil, %g2 -etrap_irq: - TRAP_LOAD_THREAD_REG(%g6, %g1) +etrap_irq: clr %g3 +etrap_syscall: TRAP_LOAD_THREAD_REG(%g6, %g1) rdpr %tstate, %g1 + or %g1, %g3, %g1 sllx %g2, 20, %g3 andcc %g1, TSTATE_PRIV, %g0 or %g1, %g3, %g1 diff --git a/arch/sparc64/kernel/init_task.c b/arch/sparc64/kernel/init_task.c index 90007cf88bac650517c67951f81aa056ca7ae71f..d2b312381c19abeb26fd8812d32201beb26005d2 100644 --- a/arch/sparc64/kernel/init_task.c +++ b/arch/sparc64/kernel/init_task.c @@ -10,7 +10,6 @@ #include static struct fs_struct init_fs = INIT_FS; -static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS(init_signals); static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); struct mm_struct init_mm = INIT_MM(init_mm); diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c index 500ac6d483a0cec74f7c8ab51940167813267127..4129c0449856bbe61a34e670ec87996cd71bd19a 100644 --- a/arch/sparc64/kernel/process.c +++ b/arch/sparc64/kernel/process.c @@ -503,6 +503,8 @@ asmlinkage long sparc_do_fork(unsigned long clone_flags, unsigned long stack_size) { int __user *parent_tid_ptr, *child_tid_ptr; + unsigned long orig_i1 = regs->u_regs[UREG_I1]; + long ret; #ifdef CONFIG_COMPAT if (test_thread_flag(TIF_32BIT)) { @@ -515,9 +517,19 @@ asmlinkage long sparc_do_fork(unsigned long clone_flags, child_tid_ptr = (int __user *) regs->u_regs[UREG_I4]; } - return do_fork(clone_flags, stack_start, - regs, stack_size, - parent_tid_ptr, child_tid_ptr); + ret = do_fork(clone_flags, stack_start, + regs, stack_size, + parent_tid_ptr, child_tid_ptr); + + /* If we get an error and potentially restart the system + * call, we're screwed because copy_thread() clobbered + * the parent's %o1. So detect that case and restore it + * here. + */ + if ((unsigned long)ret >= -ERESTART_RESTARTBLOCK) + regs->u_regs[UREG_I1] = orig_i1; + + return ret; } /* Copy a Sparc thread. The fork() return value conventions diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c index e9fc0aa2da386e8161a7a4badedb8f77b8ce7789..f6c9fc92921d4405693f6f23ab2817bdee3993fa 100644 --- a/arch/sparc64/kernel/ptrace.c +++ b/arch/sparc64/kernel/ptrace.c @@ -287,11 +287,11 @@ static int genregs64_set(struct task_struct *target, 32 * sizeof(u64), 33 * sizeof(u64)); if (!ret) { - /* Only the condition codes can be modified - * in the %tstate register. + /* Only the condition codes and the "in syscall" + * state can be modified in the %tstate register. */ - tstate &= (TSTATE_ICC | TSTATE_XCC); - regs->tstate &= ~(TSTATE_ICC | TSTATE_XCC); + tstate &= (TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL); + regs->tstate &= ~(TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL); regs->tstate |= tstate; } } @@ -657,8 +657,10 @@ static int genregs32_set(struct task_struct *target, switch (pos) { case 32: /* PSR */ tstate = regs->tstate; - tstate &= ~(TSTATE_ICC | TSTATE_XCC); + tstate &= ~(TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL); tstate |= psr_to_tstate_icc(reg); + if (reg & PSR_SYSCALL) + tstate |= TSTATE_SYSCALL; regs->tstate = tstate; break; case 33: /* PC */ @@ -944,6 +946,8 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, break; default: + if (request == PTRACE_SPARC_DETACH) + request = PTRACE_DETACH; ret = compat_ptrace_request(child, request, addr, data); break; } @@ -1036,6 +1040,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) break; default: + if (request == PTRACE_SPARC_DETACH) + request = PTRACE_DETACH; ret = ptrace_request(child, request, addr, data); break; } diff --git a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S index ecf6753b204a07d2da8b5a9c1bad0bbc35995218..16689b2930dbd9b1eada99f4c115074a53749ed6 100644 --- a/arch/sparc64/kernel/rtrap.S +++ b/arch/sparc64/kernel/rtrap.S @@ -46,7 +46,7 @@ __handle_user_windows: wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate ldx [%g6 + TI_FLAGS], %l0 -1: andcc %l0, (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), %g0 +1: andcc %l0, _TIF_SIGPENDING, %g0 be,pt %xcc, __handle_user_windows_continue nop mov %l5, %o1 @@ -86,7 +86,7 @@ __handle_perfctrs: wrpr %g0, RTRAP_PSTATE, %pstate wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate ldx [%g6 + TI_FLAGS], %l0 -1: andcc %l0, (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), %g0 +1: andcc %l0, _TIF_SIGPENDING, %g0 be,pt %xcc, __handle_perfctrs_continue sethi %hi(TSTATE_PEF), %o0 @@ -195,7 +195,7 @@ __handle_preemption_continue: andcc %l1, %o0, %g0 andcc %l0, _TIF_NEED_RESCHED, %g0 bne,pn %xcc, __handle_preemption - andcc %l0, (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), %g0 + andcc %l0, _TIF_SIGPENDING, %g0 bne,pn %xcc, __handle_signal __handle_signal_continue: ldub [%g6 + TI_WSAVED], %o2 @@ -257,6 +257,7 @@ rt_continue: ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1 wr %o3, %g0, %y wrpr %l4, 0x0, %pil wrpr %g0, 0x1, %tl + andn %l1, TSTATE_SYSCALL, %l1 wrpr %l1, %g0, %tstate wrpr %l2, %g0, %tpc wrpr %o2, %g0, %tnpc diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c index 45d6bf632daa6a6e4fe5c6826629c3ff9eb1f732..6e4dc67d16afb6f2ba4762e5fd484ca9cc7c5198 100644 --- a/arch/sparc64/kernel/signal.c +++ b/arch/sparc64/kernel/signal.c @@ -247,7 +247,9 @@ static long _sigpause_common(old_sigset_t set) current->state = TASK_INTERRUPTIBLE; schedule(); - set_thread_flag(TIF_RESTORE_SIGMASK); + + set_restore_sigmask(); + return -ERESTARTNOHAND; } @@ -333,7 +335,7 @@ void do_rt_sigreturn(struct pt_regs *regs) regs->tnpc = tnpc; /* Prevent syscall restart. */ - pt_regs_clear_trap_type(regs); + pt_regs_clear_syscall(regs); sigdelsetmask(&set, ~_BLOCKABLE); spin_lock_irq(¤t->sighand->siglock); @@ -376,16 +378,29 @@ save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, unsigned long framesize) { - unsigned long sp; + unsigned long sp = regs->u_regs[UREG_FP] + STACK_BIAS; - sp = regs->u_regs[UREG_FP] + STACK_BIAS; + /* + * If we are on the alternate signal stack and would overflow it, don't. + * Return an always-bogus address instead so we will die with SIGSEGV. + */ + if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize))) + return (void __user *) -1L; /* This is the X/Open sanctioned signal stack switching. */ if (ka->sa.sa_flags & SA_ONSTACK) { - if (!on_sig_stack(sp) && - !((current->sas_ss_sp + current->sas_ss_size) & 7)) + if (sas_ss_flags(sp) == 0) sp = current->sas_ss_sp + current->sas_ss_size; } + + /* Always align the stack frame. This handles two cases. First, + * sigaltstack need not be mindful of platform specific stack + * alignment. Second, if we took this signal because the stack + * is not aligned properly, we'd like to take the signal cleanly + * and report that. + */ + sp &= ~7UL; + return (void __user *)(sp - framesize); } @@ -486,7 +501,7 @@ static inline void handle_signal(unsigned long signr, struct k_sigaction *ka, } static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, - struct sigaction *sa) + struct sigaction *sa) { switch (regs->u_regs[UREG_I0]) { case ERESTART_RESTARTBLOCK: @@ -512,21 +527,19 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, */ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) { - struct signal_deliver_cookie cookie; struct k_sigaction ka; + int restart_syscall; sigset_t *oldset; siginfo_t info; int signr; if (pt_regs_is_syscall(regs) && (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) { - pt_regs_clear_trap_type(regs); - cookie.restart_syscall = 1; + restart_syscall = 1; } else - cookie.restart_syscall = 0; - cookie.orig_i0 = orig_i0; + restart_syscall = 0; - if (test_thread_flag(TIF_RESTORE_SIGMASK)) + if (current_thread_info()->status & TS_RESTORE_SIGMASK) oldset = ¤t->saved_sigmask; else oldset = ¤t->blocked; @@ -534,77 +547,62 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) #ifdef CONFIG_COMPAT if (test_thread_flag(TIF_32BIT)) { extern void do_signal32(sigset_t *, struct pt_regs *, - struct signal_deliver_cookie *); - do_signal32(oldset, regs, &cookie); + int restart_syscall, + unsigned long orig_i0); + do_signal32(oldset, regs, restart_syscall, orig_i0); return; } #endif - signr = get_signal_to_deliver(&info, &ka, regs, &cookie); + signr = get_signal_to_deliver(&info, &ka, regs, NULL); + + /* If the debugger messes with the program counter, it clears + * the software "in syscall" bit, directing us to not perform + * a syscall restart. + */ + if (restart_syscall && !pt_regs_is_syscall(regs)) + restart_syscall = 0; + if (signr > 0) { - if (cookie.restart_syscall) - syscall_restart(cookie.orig_i0, regs, &ka.sa); + if (restart_syscall) + syscall_restart(orig_i0, regs, &ka.sa); handle_signal(signr, &ka, &info, oldset, regs); - /* a signal was successfully delivered; the saved + /* A signal was successfully delivered; the saved * sigmask will have been stored in the signal frame, * and will be restored by sigreturn, so we can simply - * clear the TIF_RESTORE_SIGMASK flag. + * clear the TS_RESTORE_SIGMASK flag. */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) - clear_thread_flag(TIF_RESTORE_SIGMASK); + current_thread_info()->status &= ~TS_RESTORE_SIGMASK; return; } - if (cookie.restart_syscall && + if (restart_syscall && (regs->u_regs[UREG_I0] == ERESTARTNOHAND || regs->u_regs[UREG_I0] == ERESTARTSYS || regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { /* replay the system call when we are done */ - regs->u_regs[UREG_I0] = cookie.orig_i0; + regs->u_regs[UREG_I0] = orig_i0; regs->tpc -= 4; regs->tnpc -= 4; } - if (cookie.restart_syscall && + if (restart_syscall && regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { regs->u_regs[UREG_G1] = __NR_restart_syscall; regs->tpc -= 4; regs->tnpc -= 4; } - /* if there's no signal to deliver, we just put the saved sigmask + /* If there's no signal to deliver, we just put the saved sigmask * back */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) { - clear_thread_flag(TIF_RESTORE_SIGMASK); + if (current_thread_info()->status & TS_RESTORE_SIGMASK) { + current_thread_info()->status &= ~TS_RESTORE_SIGMASK; sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } } void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long thread_info_flags) { - if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) + if (thread_info_flags & _TIF_SIGPENDING) do_signal(regs, orig_i0); } - -void ptrace_signal_deliver(struct pt_regs *regs, void *cookie) -{ - struct signal_deliver_cookie *cp = cookie; - - if (cp->restart_syscall && - (regs->u_regs[UREG_I0] == ERESTARTNOHAND || - regs->u_regs[UREG_I0] == ERESTARTSYS || - regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { - /* replay the system call when we are done */ - regs->u_regs[UREG_I0] = cp->orig_i0; - regs->tpc -= 4; - regs->tnpc -= 4; - cp->restart_syscall = 0; - } - if (cp->restart_syscall && - regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { - regs->u_regs[UREG_G1] = __NR_restart_syscall; - regs->tpc -= 4; - regs->tnpc -= 4; - cp->restart_syscall = 0; - } -} diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c index 9415d2c918c5fc8301aa9e45c499fbe86539552c..97cdd1bf4a100201a60a77de7f40ab37e5fb27e8 100644 --- a/arch/sparc64/kernel/signal32.c +++ b/arch/sparc64/kernel/signal32.c @@ -269,7 +269,7 @@ void do_sigreturn32(struct pt_regs *regs) regs->tstate |= psr_to_tstate_icc(psr); /* Prevent syscall restart. */ - pt_regs_clear_trap_type(regs); + pt_regs_clear_syscall(regs); err |= __get_user(fpu_save, &sf->fpu_save); if (fpu_save) @@ -355,7 +355,7 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs) regs->tstate |= psr_to_tstate_icc(psr); /* Prevent syscall restart. */ - pt_regs_clear_trap_type(regs); + pt_regs_clear_syscall(regs); err |= __get_user(fpu_save, &sf->fpu_save); if (fpu_save) @@ -406,11 +406,27 @@ static void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, uns regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL; sp = regs->u_regs[UREG_FP]; + /* + * If we are on the alternate signal stack and would overflow it, don't. + * Return an always-bogus address instead so we will die with SIGSEGV. + */ + if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize))) + return (void __user *) -1L; + /* This is the X/Open sanctioned signal stack switching. */ if (sa->sa_flags & SA_ONSTACK) { - if (!on_sig_stack(sp) && !((current->sas_ss_sp + current->sas_ss_size) & 7)) + if (sas_ss_flags(sp) == 0) sp = current->sas_ss_sp + current->sas_ss_size; } + + /* Always align the stack frame. This handles two cases. First, + * sigaltstack need not be mindful of platform specific stack + * alignment. Second, if we took this signal because the stack + * is not aligned properly, we'd like to take the signal cleanly + * and report that. + */ + sp &= ~7UL; + return (void __user *)(sp - framesize); } @@ -752,48 +768,55 @@ static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs * mistake. */ void do_signal32(sigset_t *oldset, struct pt_regs * regs, - struct signal_deliver_cookie *cookie) + int restart_syscall, unsigned long orig_i0) { struct k_sigaction ka; siginfo_t info; int signr; - signr = get_signal_to_deliver(&info, &ka, regs, cookie); + signr = get_signal_to_deliver(&info, &ka, regs, NULL); + + /* If the debugger messes with the program counter, it clears + * the "in syscall" bit, directing us to not perform a syscall + * restart. + */ + if (restart_syscall && !pt_regs_is_syscall(regs)) + restart_syscall = 0; + if (signr > 0) { - if (cookie->restart_syscall) - syscall_restart32(cookie->orig_i0, regs, &ka.sa); + if (restart_syscall) + syscall_restart32(orig_i0, regs, &ka.sa); handle_signal32(signr, &ka, &info, oldset, regs); - /* a signal was successfully delivered; the saved + /* A signal was successfully delivered; the saved * sigmask will have been stored in the signal frame, * and will be restored by sigreturn, so we can simply - * clear the TIF_RESTORE_SIGMASK flag. + * clear the TS_RESTORE_SIGMASK flag. */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) - clear_thread_flag(TIF_RESTORE_SIGMASK); + current_thread_info()->status &= ~TS_RESTORE_SIGMASK; return; } - if (cookie->restart_syscall && + if (restart_syscall && (regs->u_regs[UREG_I0] == ERESTARTNOHAND || regs->u_regs[UREG_I0] == ERESTARTSYS || regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { /* replay the system call when we are done */ - regs->u_regs[UREG_I0] = cookie->orig_i0; + regs->u_regs[UREG_I0] = orig_i0; regs->tpc -= 4; regs->tnpc -= 4; } - if (cookie->restart_syscall && + if (restart_syscall && regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { regs->u_regs[UREG_G1] = __NR_restart_syscall; regs->tpc -= 4; regs->tnpc -= 4; } - /* if there's no signal to deliver, we just put the saved sigmask + /* If there's no signal to deliver, we just put the saved sigmask * back */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) { - clear_thread_flag(TIF_RESTORE_SIGMASK); + if (current_thread_info()->status & TS_RESTORE_SIGMASK) { + current_thread_info()->status &= ~TS_RESTORE_SIGMASK; sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } } diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index 3aba47624df45aa0e773c169fe6498b5bb5e377e..0d6403a630acd1f4c2e22201755d67de04a83cc1 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c @@ -865,21 +865,14 @@ void smp_call_function_client(int irq, struct pt_regs *regs) void *info = call_data->info; clear_softint(1 << irq); - - irq_enter(); - - if (!call_data->wait) { - /* let initiator proceed after getting data */ - atomic_inc(&call_data->finished); - } - - func(info); - - irq_exit(); - if (call_data->wait) { /* let initiator proceed only after completion */ + func(info); atomic_inc(&call_data->finished); + } else { + /* let initiator proceed after getting data */ + atomic_inc(&call_data->finished); + func(info); } } @@ -1041,9 +1034,7 @@ void smp_receive_signal(int cpu) void smp_receive_signal_client(int irq, struct pt_regs *regs) { - irq_enter(); clear_softint(1 << irq); - irq_exit(); } void smp_new_mmu_context_version_client(int irq, struct pt_regs *regs) @@ -1051,8 +1042,6 @@ void smp_new_mmu_context_version_client(int irq, struct pt_regs *regs) struct mm_struct *mm; unsigned long flags; - irq_enter(); - clear_softint(1 << irq); /* See if we need to allocate a new TLB context because @@ -1072,8 +1061,6 @@ void smp_new_mmu_context_version_client(int irq, struct pt_regs *regs) load_secondary_context(mm); __flush_tlb_mm(CTX_HWBITS(mm->context), SECONDARY_CONTEXT); - - irq_exit(); } void smp_new_mmu_context_version(void) @@ -1239,8 +1226,6 @@ void smp_penguin_jailcell(int irq, struct pt_regs *regs) { clear_softint(1 << irq); - irq_enter(); - preempt_disable(); __asm__ __volatile__("flushw"); @@ -1253,8 +1238,6 @@ void smp_penguin_jailcell(int irq, struct pt_regs *regs) prom_world(0); preempt_enable(); - - irq_exit(); } /* /proc/profile writes can call this, don't __init it please. */ diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c index 8d4761f15fa932cdede6dc4dc4336fdaa2b1cc88..ac1bff58c1ac8319eb0178e0980eeda35dfb1a32 100644 --- a/arch/sparc64/kernel/sys_sparc.c +++ b/arch/sparc64/kernel/sys_sparc.c @@ -542,20 +542,19 @@ asmlinkage long sparc64_personality(unsigned long personality) return ret; } -int sparc64_mmap_check(unsigned long addr, unsigned long len, - unsigned long flags) +int sparc64_mmap_check(unsigned long addr, unsigned long len) { if (test_thread_flag(TIF_32BIT)) { if (len >= STACK_TOP32) return -EINVAL; - if ((flags & MAP_FIXED) && addr > STACK_TOP32 - len) + if (addr > STACK_TOP32 - len) return -EINVAL; } else { if (len >= VA_EXCLUDE_START) return -EINVAL; - if ((flags & MAP_FIXED) && invalid_64bit_range(addr, len)) + if (invalid_64bit_range(addr, len)) return -EINVAL; } @@ -609,46 +608,19 @@ asmlinkage unsigned long sys64_mremap(unsigned long addr, unsigned long old_len, unsigned long new_len, unsigned long flags, unsigned long new_addr) { - struct vm_area_struct *vma; unsigned long ret = -EINVAL; if (test_thread_flag(TIF_32BIT)) goto out; if (unlikely(new_len >= VA_EXCLUDE_START)) goto out; - if (unlikely(invalid_64bit_range(addr, old_len))) + if (unlikely(sparc64_mmap_check(addr, old_len))) + goto out; + if (unlikely(sparc64_mmap_check(new_addr, new_len))) goto out; down_write(¤t->mm->mmap_sem); - if (flags & MREMAP_FIXED) { - if (invalid_64bit_range(new_addr, new_len)) - goto out_sem; - } else if (invalid_64bit_range(addr, new_len)) { - unsigned long map_flags = 0; - struct file *file = NULL; - - ret = -ENOMEM; - if (!(flags & MREMAP_MAYMOVE)) - goto out_sem; - - vma = find_vma(current->mm, addr); - if (vma) { - if (vma->vm_flags & VM_SHARED) - map_flags |= MAP_SHARED; - file = vma->vm_file; - } - - /* MREMAP_FIXED checked above. */ - new_addr = get_unmapped_area(file, addr, new_len, - vma ? vma->vm_pgoff : 0, - map_flags); - ret = new_addr; - if (new_addr & ~PAGE_MASK) - goto out_sem; - flags |= MREMAP_FIXED; - } ret = do_mremap(addr, old_len, new_len, flags, new_addr); -out_sem: up_write(¤t->mm->mmap_sem); out: return ret; diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c index 161ce4710fe76143326905011db732358de7c891..ba5bd626b39e39a263a2aec0a1b6939ea0d70c94 100644 --- a/arch/sparc64/kernel/sys_sparc32.c +++ b/arch/sparc64/kernel/sys_sparc32.c @@ -236,13 +236,6 @@ asmlinkage long sys32_getegid16(void) /* 32-bit timeval and related flotsam. */ -static long get_tv32(struct timeval *o, struct compat_timeval __user *i) -{ - return (!access_ok(VERIFY_READ, i, sizeof(*i)) || - (__get_user(o->tv_sec, &i->tv_sec) | - __get_user(o->tv_usec, &i->tv_usec))); -} - static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i) { return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) || @@ -757,30 +750,6 @@ asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv, return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL); } -asmlinkage long sys32_utimes(char __user *filename, - struct compat_timeval __user *tvs) -{ - struct timespec tv[2]; - - if (tvs) { - struct timeval ktvs[2]; - if (get_tv32(&ktvs[0], tvs) || - get_tv32(&ktvs[1], 1+tvs)) - return -EFAULT; - - if (ktvs[0].tv_usec < 0 || ktvs[0].tv_usec >= 1000000 || - ktvs[1].tv_usec < 0 || ktvs[1].tv_usec >= 1000000) - return -EINVAL; - - tv[0].tv_sec = ktvs[0].tv_sec; - tv[0].tv_nsec = 1000 * ktvs[0].tv_usec; - tv[1].tv_sec = ktvs[1].tv_sec; - tv[1].tv_nsec = 1000 * ktvs[1].tv_usec; - } - - return do_utimes(AT_FDCWD, filename, tvs ? tv : NULL, 0); -} - /* These are here just in case some old sparc32 binary calls it. */ asmlinkage long sys32_pause(void) { @@ -898,44 +867,15 @@ asmlinkage unsigned long sys32_mremap(unsigned long addr, unsigned long old_len, unsigned long new_len, unsigned long flags, u32 __new_addr) { - struct vm_area_struct *vma; unsigned long ret = -EINVAL; unsigned long new_addr = __new_addr; - if (old_len > STACK_TOP32 || new_len > STACK_TOP32) + if (unlikely(sparc64_mmap_check(addr, old_len))) goto out; - if (addr > STACK_TOP32 - old_len) + if (unlikely(sparc64_mmap_check(new_addr, new_len))) goto out; down_write(¤t->mm->mmap_sem); - if (flags & MREMAP_FIXED) { - if (new_addr > STACK_TOP32 - new_len) - goto out_sem; - } else if (addr > STACK_TOP32 - new_len) { - unsigned long map_flags = 0; - struct file *file = NULL; - - ret = -ENOMEM; - if (!(flags & MREMAP_MAYMOVE)) - goto out_sem; - - vma = find_vma(current->mm, addr); - if (vma) { - if (vma->vm_flags & VM_SHARED) - map_flags |= MAP_SHARED; - file = vma->vm_file; - } - - /* MREMAP_FIXED checked above. */ - new_addr = get_unmapped_area(file, addr, new_len, - vma ? vma->vm_pgoff : 0, - map_flags); - ret = new_addr; - if (new_addr & ~PAGE_MASK) - goto out_sem; - flags |= MREMAP_FIXED; - } ret = do_mremap(addr, old_len, new_len, flags, new_addr); -out_sem: up_write(¤t->mm->mmap_sem); out: return ret; diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S index a4fef2ba1ae162848d801034f7cf18008b10b8de..8b5282d433c44b6c1d04ebaf525cda6470b9a9f2 100644 --- a/arch/sparc64/kernel/systbls.S +++ b/arch/sparc64/kernel/systbls.S @@ -45,7 +45,7 @@ sys_call_table32: /*120*/ .word compat_sys_readv, compat_sys_writev, sys32_settimeofday, sys32_fchown16, sys_fchmod .word sys_nis_syscall, sys32_setreuid16, sys32_setregid16, sys_rename, sys_truncate /*130*/ .word sys_ftruncate, sys_flock, compat_sys_lstat64, sys_nis_syscall, sys_nis_syscall - .word sys_nis_syscall, sys32_mkdir, sys_rmdir, sys32_utimes, compat_sys_stat64 + .word sys_nis_syscall, sys32_mkdir, sys_rmdir, compat_sys_utimes, compat_sys_stat64 /*140*/ .word sys32_sendfile64, sys_nis_syscall, sys32_futex, sys_gettid, compat_sys_getrlimit .word compat_sys_setrlimit, sys_pivot_root, sys32_prctl, sys_pciconfig_read, sys_pciconfig_write /*150*/ .word sys_nis_syscall, sys_inotify_init, sys_inotify_add_watch, sys_poll, sys_getdents64 diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index 4cad0b32b0afcd5256dce395a1ce6e682c50715c..3c7b9471eafb508f80cd007a56ee4b196f171e9a 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -610,8 +610,6 @@ static void __init remap_kernel(void) static void __init inherit_prom_mappings(void) { - read_obp_translations(); - /* Now fixup OBP's idea about where we really are mapped. */ printk("Remapping the kernel... "); remap_kernel(); @@ -770,7 +768,10 @@ static void __init find_ramdisk(unsigned long phys_base) initrd_start = ramdisk_image; initrd_end = ramdisk_image + sparc_ramdisk_size; - lmb_reserve(initrd_start, initrd_end); + lmb_reserve(initrd_start, sparc_ramdisk_size); + + initrd_start += PAGE_OFFSET; + initrd_end += PAGE_OFFSET; } #endif } @@ -1744,7 +1745,17 @@ void __init paging_init(void) lmb_init(); - /* Find available physical memory... */ + /* Find available physical memory... + * + * Read it twice in order to work around a bug in openfirmware. + * The call to grab this table itself can cause openfirmware to + * allocate memory, which in turn can take away some space from + * the list of available memory. Reading it twice makes sure + * we really do get the final value. + */ + read_obp_translations(); + read_obp_memory("reg", &pall[0], &pall_ents); + read_obp_memory("available", &pavail[0], &pavail_ents); read_obp_memory("available", &pavail[0], &pavail_ents); phys_base = 0xffffffffffffffffUL; @@ -1785,8 +1796,6 @@ void __init paging_init(void) inherit_prom_mappings(); - read_obp_memory("reg", &pall[0], &pall_ents); - init_kpte_bitmap(); /* Ok, we can use our TLB miss and window trap handlers safely. */ @@ -2362,16 +2371,3 @@ void __flush_tlb_all(void) __asm__ __volatile__("wrpr %0, 0, %%pstate" : : "r" (pstate)); } - -#ifdef CONFIG_MEMORY_HOTPLUG - -void online_page(struct page *page) -{ - ClearPageReserved(page); - init_page_count(page); - __free_page(page); - totalram_pages++; - num_physpages++; -} - -#endif /* CONFIG_MEMORY_HOTPLUG */ diff --git a/arch/um/Kconfig.char b/arch/um/Kconfig.char index 3a4b396d7979916177b30d5689b759d277eafe35..1b238ebae6b39973cbf7d57b0d7dbe8a40f49a06 100644 --- a/arch/um/Kconfig.char +++ b/arch/um/Kconfig.char @@ -145,14 +145,14 @@ config LEGACY_PTYS systems, it is safe to say N. config RAW_DRIVER - tristate "RAW driver (/dev/raw/rawN) (OBSOLETE)" + tristate "RAW driver (/dev/raw/rawN)" + depends on BLOCK help The raw driver permits block devices to be bound to /dev/raw/rawN. Once bound, I/O against /dev/raw/rawN uses efficient zero-copy I/O. See the raw(8) manpage for more details. - The raw driver is deprecated and will be removed soon. - Applications should simply open the device (eg /dev/hda1) + Applications should preferably open the device (eg /dev/hda1) with the O_DIRECT flag. config MAX_RAW_DEVS diff --git a/arch/um/Makefile b/arch/um/Makefile index 01b97c19a8ba99da4a07db8194397b1611b265e6..dbeab15e7bb7c160db7dda887a4c9d14982f742c 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile @@ -77,10 +77,7 @@ include $(srctree)/$(ARCH_DIR)/Makefile-os-$(OS) KERNEL_DEFINES = $(strip -Derrno=kernel_errno -Dsigprocmask=kernel_sigprocmask \ -Dmktime=kernel_mktime $(ARCH_KERNEL_DEFINES)) KBUILD_CFLAGS += $(KERNEL_DEFINES) -# Disable unit-at-a-time mode on pre-gcc-4.0 compilers, it makes gcc use -# a lot more stack due to the lack of sharing of stacklots: -KBUILD_CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then \ - echo $(call cc-option,-fno-unit-at-a-time); fi ;) +KBUILD_CFLAGS += $(call cc-option,-fno-unit-at-a-time,) PHONY += linux diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c index 025764089ac8ea7b739652c827fbe88b3a400324..cfeb3f4a44afc0ef9cb6a5edf5e08d0d81ec32a1 100644 --- a/arch/um/drivers/chan_user.c +++ b/arch/um/drivers/chan_user.c @@ -11,6 +11,7 @@ #include #include #include "chan_user.h" +#include "kern_constants.h" #include "os.h" #include "um_malloc.h" #include "user.h" diff --git a/arch/um/drivers/cow_sys.h b/arch/um/drivers/cow_sys.h index ca8c9e11a39b9f94361b10c6739e8712ec3a932c..f5701fd2ef90b2d8d1964c3222ebb155c2594ec1 100644 --- a/arch/um/drivers/cow_sys.h +++ b/arch/um/drivers/cow_sys.h @@ -8,7 +8,7 @@ static inline void *cow_malloc(int size) { - return kmalloc(size, UM_GFP_KERNEL); + return uml_kmalloc(size, UM_GFP_KERNEL); } static inline void cow_free(void *ptr) diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c index f23c109a055c865e9e5aac0337a2afed17c96888..f8e85e0bdace20fddc82ca805e6101bcc9c76a8d 100644 --- a/arch/um/drivers/daemon_user.c +++ b/arch/um/drivers/daemon_user.c @@ -34,7 +34,7 @@ static struct sockaddr_un *new_addr(void *name, int len) { struct sockaddr_un *sun; - sun = kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL); + sun = uml_kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL); if (sun == NULL) { printk(UM_KERN_ERR "new_addr: allocation of sockaddr_un " "failed\n"); @@ -83,7 +83,7 @@ static int connect_to_switch(struct daemon_data *pri) goto out_close; } - sun = kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL); + sun = uml_kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL); if (sun == NULL) { printk(UM_KERN_ERR "new_addr: allocation of sockaddr_un " "failed\n"); diff --git a/arch/um/drivers/fd.c b/arch/um/drivers/fd.c index 0a2bb5b64b82e8ca5bc66c0d76e06cab0e818ed6..f5a981a16240e4d8dd92afca3fb710d9d4d84588 100644 --- a/arch/um/drivers/fd.c +++ b/arch/um/drivers/fd.c @@ -40,7 +40,7 @@ static void *fd_init(char *str, int device, const struct chan_opts *opts) return NULL; } - data = kmalloc(sizeof(*data), UM_GFP_KERNEL); + data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL); if (data == NULL) return NULL; diff --git a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c index ff1b22b69e9c73fb56f842ba367c814c423508af..368219cc2366d666ca92e0ac38497f111d888501 100644 --- a/arch/um/drivers/hostaudio_kern.c +++ b/arch/um/drivers/hostaudio_kern.c @@ -154,7 +154,7 @@ static int hostaudio_ioctl(struct inode *inode, struct file *file, case SNDCTL_DSP_SUBDIVIDE: case SNDCTL_DSP_SETFRAGMENT: if (get_user(data, (int __user *) arg)) - return EFAULT; + return -EFAULT; break; default: break; diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index 10b86e1cc659ee8ca02bee67c2e931067eef8de2..5047490fc299aa69ae999b348760277767684569 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -191,9 +191,9 @@ void line_flush_chars(struct tty_struct *tty) line_flush_buffer(tty); } -void line_put_char(struct tty_struct *tty, unsigned char ch) +int line_put_char(struct tty_struct *tty, unsigned char ch) { - line_write(tty, &ch, sizeof(ch)); + return line_write(tty, &ch, sizeof(ch)); } int line_write(struct tty_struct *tty, const unsigned char *buf, int len) diff --git a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c index 5f647d7a7292946dfdd36fecf0759198802c35a7..ee19e91568a2585765127970fc9d1ba821bcc613 100644 --- a/arch/um/drivers/mcast_user.c +++ b/arch/um/drivers/mcast_user.c @@ -15,6 +15,7 @@ #include #include #include +#include "kern_constants.h" #include "mcast.h" #include "net_user.h" #include "um_malloc.h" @@ -24,7 +25,7 @@ static struct sockaddr_in *new_addr(char *addr, unsigned short port) { struct sockaddr_in *sin; - sin = kmalloc(sizeof(struct sockaddr_in), UM_GFP_KERNEL); + sin = uml_kmalloc(sizeof(struct sockaddr_in), UM_GFP_KERNEL); if (sin == NULL) { printk(UM_KERN_ERR "new_addr: allocation of sockaddr_in " "failed\n"); diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c index abf2653f5517cbf6f65b851dd10455e7bc8e27e2..9415dd9e63ef1e98c15505733c3ba1c1eff02029 100644 --- a/arch/um/drivers/net_user.c +++ b/arch/um/drivers/net_user.c @@ -222,7 +222,7 @@ static void change(char *dev, char *what, unsigned char *addr, netmask[2], netmask[3]); output_len = UM_KERN_PAGE_SIZE; - output = kmalloc(output_len, UM_GFP_KERNEL); + output = uml_kmalloc(output_len, UM_GFP_KERNEL); if (output == NULL) printk(UM_KERN_ERR "change : failed to allocate output " "buffer\n"); diff --git a/arch/um/drivers/port_user.c b/arch/um/drivers/port_user.c index d269ca387f108de63595a5bf46085864668537e6..b49bf56a56aa4a7b0b94a2b3709c972a144302f4 100644 --- a/arch/um/drivers/port_user.c +++ b/arch/um/drivers/port_user.c @@ -47,7 +47,7 @@ static void *port_init(char *str, int device, const struct chan_opts *opts) if (kern_data == NULL) return NULL; - data = kmalloc(sizeof(*data), UM_GFP_KERNEL); + data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL); if (data == NULL) goto err; diff --git a/arch/um/drivers/pty.c b/arch/um/drivers/pty.c index 49c79dda6046492fc936c4c921a04d71d7584c2b..1113911dcb2bfb70696785ac194089705c9c8693 100644 --- a/arch/um/drivers/pty.c +++ b/arch/um/drivers/pty.c @@ -29,7 +29,7 @@ static void *pty_chan_init(char *str, int device, const struct chan_opts *opts) { struct pty_chan *data; - data = kmalloc(sizeof(*data), UM_GFP_KERNEL); + data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL); if (data == NULL) return NULL; diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c index 71f0959c15357b4587cd10c816d3eca1db1fbe92..4949044773ba78b93797d43701ab751b0a1bce23 100644 --- a/arch/um/drivers/random.c +++ b/arch/um/drivers/random.c @@ -1,4 +1,5 @@ -/* Copyright (C) 2005 Jeff Dike */ +/* Copyright (C) 2005 - 2008 Jeff Dike */ + /* Much of this ripped from drivers/char/hw_random.c, see there for other * copyright. * @@ -8,16 +9,18 @@ #include #include #include +#include #include #include #include +#include "irq_kern.h" #include "os.h" /* * core module and version information */ #define RNG_VERSION "1.0.0" -#define RNG_MODULE_NAME "random" +#define RNG_MODULE_NAME "hw_random" #define RNG_MISCDEV_MINOR 183 /* official */ @@ -26,47 +29,67 @@ * protects against a module being loaded twice at the same time. */ static int random_fd = -1; +static DECLARE_WAIT_QUEUE_HEAD(host_read_wait); static int rng_dev_open (struct inode *inode, struct file *filp) { /* enforce read-only access to this chrdev */ if ((filp->f_mode & FMODE_READ) == 0) return -EINVAL; - if (filp->f_mode & FMODE_WRITE) + if ((filp->f_mode & FMODE_WRITE) != 0) return -EINVAL; return 0; } +static atomic_t host_sleep_count = ATOMIC_INIT(0); + static ssize_t rng_dev_read (struct file *filp, char __user *buf, size_t size, - loff_t * offp) + loff_t *offp) { - u32 data; - int n, ret = 0, have_data; - - while(size){ - n = os_read_file(random_fd, &data, sizeof(data)); - if(n > 0){ - have_data = n; - while (have_data && size) { - if (put_user((u8)data, buf++)) { - ret = ret ? : -EFAULT; - break; - } - size--; - ret++; - have_data--; - data>>=8; - } - } - else if(n == -EAGAIN){ - if (filp->f_flags & O_NONBLOCK) - return ret ? : -EAGAIN; - - if(need_resched()) - schedule_timeout_interruptible(1); - } - else return n; + u32 data; + int n, ret = 0, have_data; + + while (size) { + n = os_read_file(random_fd, &data, sizeof(data)); + if (n > 0) { + have_data = n; + while (have_data && size) { + if (put_user((u8) data, buf++)) { + ret = ret ? : -EFAULT; + break; + } + size--; + ret++; + have_data--; + data >>= 8; + } + } + else if (n == -EAGAIN) { + DECLARE_WAITQUEUE(wait, current); + + if (filp->f_flags & O_NONBLOCK) + return ret ? : -EAGAIN; + + atomic_inc(&host_sleep_count); + reactivate_fd(random_fd, RANDOM_IRQ); + add_sigio_fd(random_fd); + + add_wait_queue(&host_read_wait, &wait); + set_task_state(current, TASK_INTERRUPTIBLE); + + schedule(); + set_task_state(current, TASK_RUNNING); + remove_wait_queue(&host_read_wait, &wait); + + if (atomic_dec_and_test(&host_sleep_count)) { + ignore_sigio_fd(random_fd); + deactivate_fd(random_fd, RANDOM_IRQ); + } + } + else + return n; + if (signal_pending (current)) return ret ? : -ERESTARTSYS; } @@ -86,6 +109,13 @@ static struct miscdevice rng_miscdev = { &rng_chrdev_ops, }; +static irqreturn_t random_interrupt(int irq, void *data) +{ + wake_up(&host_read_wait); + + return IRQ_HANDLED; +} + /* * rng_init - initialize RNG module */ @@ -93,28 +123,33 @@ static int __init rng_init (void) { int err; - err = os_open_file("/dev/random", of_read(OPENFLAGS()), 0); - if(err < 0) - goto out; + err = os_open_file("/dev/random", of_read(OPENFLAGS()), 0); + if (err < 0) + goto out; - random_fd = err; + random_fd = err; - err = os_set_fd_block(random_fd, 0); - if(err) + err = um_request_irq(RANDOM_IRQ, random_fd, IRQ_READ, random_interrupt, + IRQF_DISABLED | IRQF_SAMPLE_RANDOM, "random", + NULL); + if (err) goto err_out_cleanup_hw; + sigio_broken(random_fd, 1); + err = misc_register (&rng_miscdev); if (err) { - printk (KERN_ERR RNG_MODULE_NAME ": misc device register failed\n"); + printk (KERN_ERR RNG_MODULE_NAME ": misc device register " + "failed\n"); goto err_out_cleanup_hw; } +out: + return err; - out: - return err; - - err_out_cleanup_hw: - random_fd = -1; - goto out; +err_out_cleanup_hw: + os_close_file(random_fd); + random_fd = -1; + goto out; } /* @@ -122,6 +157,7 @@ static int __init rng_init (void) */ static void __exit rng_cleanup (void) { + os_close_file(random_fd); misc_deregister (&rng_miscdev); } diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c index 8b80505a3fb0117ed35676de600cce0b11b2f721..a1c2d2c98a942b9798994444f00501ddd5678132 100644 --- a/arch/um/drivers/slip_user.c +++ b/arch/um/drivers/slip_user.c @@ -96,7 +96,7 @@ static int slip_tramp(char **argv, int fd) pid = err; output_len = UM_KERN_PAGE_SIZE; - output = kmalloc(output_len, UM_GFP_KERNEL); + output = uml_kmalloc(output_len, UM_GFP_KERNEL); if (output == NULL) { printk(UM_KERN_ERR "slip_tramp : failed to allocate output " "buffer\n"); diff --git a/arch/um/drivers/tty.c b/arch/um/drivers/tty.c index c930fedc517235979c72989826a1f552f6454279..495858a090e4f49e50d4a79db016173ea4b3a6df 100644 --- a/arch/um/drivers/tty.c +++ b/arch/um/drivers/tty.c @@ -29,7 +29,7 @@ static void *tty_chan_init(char *str, int device, const struct chan_opts *opts) } str++; - data = kmalloc(sizeof(*data), UM_GFP_KERNEL); + data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL); if (data == NULL) return NULL; *data = ((struct tty_chan) { .dev = str, diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 5e45e39a8a8db5a5c57e4f27162804773c465c9e..44ad1607be2dc0d0d14d6a7d8539ffce94c452d7 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -1178,8 +1178,8 @@ static void cowify_bitmap(__u64 io_offset, int length, unsigned long *cow_mask, * by one word. Thanks to Lynn Kerby for the fix and James McMechan * for the original diagnosis. */ - if(*cow_offset == ((bitmap_len + sizeof(unsigned long) - 1) / - sizeof(unsigned long) - 1)) + if (*cow_offset == (DIV_ROUND_UP(bitmap_len, + sizeof(unsigned long)) - 1)) (*cow_offset)--; bitmap_words[0] = bitmap[*cow_offset]; diff --git a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c index 8a1c18a9b2406e678e820fd7ccc6ba979da8079a..da2caa5a21efa91333ffd44c9c7743b467ec3f26 100644 --- a/arch/um/drivers/xterm.c +++ b/arch/um/drivers/xterm.c @@ -30,7 +30,7 @@ static void *xterm_init(char *str, int device, const struct chan_opts *opts) { struct xterm_chan *data; - data = kmalloc(sizeof(*data), UM_GFP_KERNEL); + data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL); if (data == NULL) return NULL; *data = ((struct xterm_chan) { .pid = -1, diff --git a/arch/um/include/as-layout.h b/arch/um/include/as-layout.h index cac542d8ff70783d10a153b6dd342852004cdf25..58e852dfb0ce95ff1e6877eaa549c2200b50e620 100644 --- a/arch/um/include/as-layout.h +++ b/arch/um/include/as-layout.h @@ -23,16 +23,16 @@ */ #ifdef __ASSEMBLY__ -#define _AC(X, Y) (Y) +#define _UML_AC(X, Y) (Y) #else -#define __AC(X, Y) (X (Y)) -#define _AC(X, Y) __AC(X, Y) +#define __UML_AC(X, Y) (X(Y)) +#define _UML_AC(X, Y) __UML_AC(X, Y) #endif -#define STUB_START _AC(, 0x100000) -#define STUB_CODE _AC((unsigned long), STUB_START) -#define STUB_DATA _AC((unsigned long), STUB_CODE + UM_KERN_PAGE_SIZE) -#define STUB_END _AC((unsigned long), STUB_DATA + UM_KERN_PAGE_SIZE) +#define STUB_START _UML_AC(, 0x100000) +#define STUB_CODE _UML_AC((unsigned long), STUB_START) +#define STUB_DATA _UML_AC((unsigned long), STUB_CODE + UM_KERN_PAGE_SIZE) +#define STUB_END _UML_AC((unsigned long), STUB_DATA + UM_KERN_PAGE_SIZE) #ifndef __ASSEMBLY__ diff --git a/arch/um/include/line.h b/arch/um/include/line.h index 1223f2c844b4085c798e79400419bcb718dc979c..311a0d3d93af2302224e9b9d6b76614643a23a67 100644 --- a/arch/um/include/line.h +++ b/arch/um/include/line.h @@ -58,11 +58,11 @@ struct line { }; #define LINE_INIT(str, d) \ - { .count_lock = SPIN_LOCK_UNLOCKED, \ + { .count_lock = __SPIN_LOCK_UNLOCKED((str).count_lock), \ .init_str = str, \ .init_pri = INIT_STATIC, \ .valid = 1, \ - .lock = SPIN_LOCK_UNLOCKED, \ + .lock = __SPIN_LOCK_UNLOCKED((str).lock), \ .driver = d } extern void line_close(struct tty_struct *tty, struct file * filp); @@ -71,7 +71,7 @@ extern int line_setup(struct line *lines, unsigned int sizeof_lines, char *init, char **error_out); extern int line_write(struct tty_struct *tty, const unsigned char *buf, int len); -extern void line_put_char(struct tty_struct *tty, unsigned char ch); +extern int line_put_char(struct tty_struct *tty, unsigned char ch); extern void line_set_termios(struct tty_struct *tty, struct ktermios * old); extern int line_chars_in_buffer(struct tty_struct *tty); extern void line_flush_buffer(struct tty_struct *tty); diff --git a/arch/um/include/os.h b/arch/um/include/os.h index 32c799e3a495729cad00c48f7bc5da0cd03b925c..e2716ac8889accd7f33ca8d381f014d3b1bd7283 100644 --- a/arch/um/include/os.h +++ b/arch/um/include/os.h @@ -290,6 +290,7 @@ extern void os_set_ioignore(void); extern int add_sigio_fd(int fd); extern int ignore_sigio_fd(int fd); extern void maybe_sigio_broken(int fd, int read); +extern void sigio_broken(int fd, int read); /* sys-x86_64/prctl.c */ extern int os_arch_prctl(int pid, int code, unsigned long *addr); diff --git a/arch/um/include/process.h b/arch/um/include/process.h index 5af9157ff54fb0e300350bff1678340167d08848..bb873a51262e5a6707ae434e478b9bc13cbfe413 100644 --- a/arch/um/include/process.h +++ b/arch/um/include/process.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2000 - 2008 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ @@ -8,18 +8,10 @@ #include -extern void sig_handler(int sig, struct sigcontext sc); -extern void alarm_handler(int sig, struct sigcontext sc); +/* Copied from linux/compiler-gcc.h since we can't include it directly */ +#define barrier() __asm__ __volatile__("": : :"memory") -#endif +extern void sig_handler(int sig, struct sigcontext *sc); +extern void alarm_handler(int sig, struct sigcontext *sc); -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ +#endif diff --git a/arch/um/include/skas_ptrace.h b/arch/um/include/skas_ptrace.h index cd2327d09c8dfe669732182bf7e4e8537a2e6482..3d31bbacd016c910bfcc311892a0f7789bdae8e8 100644 --- a/arch/um/include/skas_ptrace.h +++ b/arch/um/include/skas_ptrace.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ @@ -12,14 +12,3 @@ #include "sysdep/skas_ptrace.h" #endif - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/arch/um/include/sysdep-i386/ptrace_user.h b/arch/um/include/sysdep-i386/ptrace_user.h index 75650723c38f15506144d12f5cfedfb0f63a8072..ef56247e414305f66824a954ee8ede30065e26b5 100644 --- a/arch/um/include/sysdep-i386/ptrace_user.h +++ b/arch/um/include/sysdep-i386/ptrace_user.h @@ -41,38 +41,10 @@ #define PT_SP_OFFSET PT_OFFSET(UESP) #define PT_SP(regs) ((regs)[UESP]) -#define FP_SIZE ((HOST_XFP_SIZE > HOST_FP_SIZE) ? HOST_XFP_SIZE : HOST_FP_SIZE) +#define FP_SIZE ((HOST_FPX_SIZE > HOST_FP_SIZE) ? HOST_FPX_SIZE : HOST_FP_SIZE) #ifndef FRAME_SIZE #define FRAME_SIZE (17) #endif -#define FRAME_SIZE_OFFSET (FRAME_SIZE * sizeof(unsigned long)) - -#define FP_FRAME_SIZE (27) -#define FPX_FRAME_SIZE (128) - -#ifdef PTRACE_GETREGS -#define UM_HAVE_GETREGS -#endif - -#ifdef PTRACE_SETREGS -#define UM_HAVE_SETREGS -#endif - -#ifdef PTRACE_GETFPREGS -#define UM_HAVE_GETFPREGS -#endif - -#ifdef PTRACE_SETFPREGS -#define UM_HAVE_SETFPREGS -#endif - -#ifdef PTRACE_GETFPXREGS -#define UM_HAVE_GETFPXREGS -#endif - -#ifdef PTRACE_SETFPXREGS -#define UM_HAVE_SETFPXREGS -#endif #endif diff --git a/arch/um/include/sysdep-i386/sigcontext.h b/arch/um/include/sysdep-i386/sigcontext.h index 67e77122aa45f42ba7f718d73e84907b065e4d76..f583c87111a0ca9a0a0e515539dc84fe95e8236e 100644 --- a/arch/um/include/sysdep-i386/sigcontext.h +++ b/arch/um/include/sysdep-i386/sigcontext.h @@ -10,7 +10,7 @@ #define IP_RESTART_SYSCALL(ip) ((ip) -= 2) -#define GET_FAULTINFO_FROM_SC(fi,sc) \ +#define GET_FAULTINFO_FROM_SC(fi, sc) \ { \ (fi).cr2 = SC_CR2(sc); \ (fi).error_code = SC_ERR(sc); \ diff --git a/arch/um/include/sysdep-x86_64/ptrace_user.h b/arch/um/include/sysdep-x86_64/ptrace_user.h index 45c0bd881cb3a36b64b657ee9090ee8a0bdf3b5a..4dbccdb58f48980fe164bde4c65ee3d89c7d6b9b 100644 --- a/arch/um/include/sysdep-x86_64/ptrace_user.h +++ b/arch/um/include/sysdep-x86_64/ptrace_user.h @@ -48,7 +48,8 @@ #define PT_ORIG_RAX_OFFSET (ORIG_RAX) #define PT_ORIG_RAX(regs) ((regs)[PT_INDEX(ORIG_RAX)]) -/* x86_64 FC3 doesn't define this in /usr/include/linux/ptrace.h even though +/* + * x86_64 FC3 doesn't define this in /usr/include/linux/ptrace.h even though * it's defined in the kernel's include/linux/ptrace.h. Additionally, use the * 2.4 name and value for 2.4 host compatibility. */ @@ -56,7 +57,8 @@ #define PTRACE_OLDSETOPTIONS 21 #endif -/* These are before the system call, so the system call number is RAX +/* + * These are before the system call, so the system call number is RAX * rather than ORIG_RAX, and arg4 is R10 rather than RCX */ #define REGS_SYSCALL_NR PT_INDEX(RAX) @@ -73,14 +75,3 @@ #define FP_SIZE (HOST_FP_SIZE) #endif - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/arch/um/include/um_malloc.h b/arch/um/include/um_malloc.h index 0ad17cb83d96ef6b0ace0a4ea800113a8cc05040..c554d706d1060b9a1e9502f33525a23c64aed60b 100644 --- a/arch/um/include/um_malloc.h +++ b/arch/um/include/um_malloc.h @@ -8,15 +8,12 @@ #include "kern_constants.h" -extern void *__kmalloc(int size, int flags); -static inline void *kmalloc(int size, int flags) -{ - return __kmalloc(size, flags); -} - +extern void *uml_kmalloc(int size, int flags); extern void kfree(const void *ptr); extern void *vmalloc(unsigned long size); extern void vfree(void *ptr); #endif /* __UM_MALLOC_H__ */ + + diff --git a/arch/um/kernel/dyn.lds.S b/arch/um/kernel/dyn.lds.S index 26090b7f323ecf3806f0a86668250ebad253bc6f..9975e1ab44fb38aa71c720e70170eceee8c91198 100644 --- a/arch/um/kernel/dyn.lds.S +++ b/arch/um/kernel/dyn.lds.S @@ -1,4 +1,5 @@ #include +#include OUTPUT_FORMAT(ELF_FORMAT) OUTPUT_ARCH(ELF_ARCH) @@ -21,7 +22,7 @@ SECTIONS _einittext = .; } - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); /* Read-only sections, merged into text segment: */ .hash : { *(.hash) } @@ -68,9 +69,9 @@ SECTIONS /* .gnu.warning sections are handled specially by elf32.em. */ *(.gnu.warning) - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); } =0x90909090 - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); .syscall_stub : { __syscall_stub_start = .; *(.__syscall_stub*) diff --git a/arch/um/kernel/init_task.c b/arch/um/kernel/init_task.c index dcfceca950523ce7b1e7ebba36994d2816d071ca..910eda8fca188526cf564ec0e35c137079e4c339 100644 --- a/arch/um/kernel/init_task.c +++ b/arch/um/kernel/init_task.c @@ -12,7 +12,6 @@ static struct fs_struct init_fs = INIT_FS; struct mm_struct init_mm = INIT_MM(init_mm); -static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS(init_signals); static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); EXPORT_SYMBOL(init_mm); diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c index 2eea1ff235e6c2cac17b80fdc343f2a9394f52d4..b0ee64622ff70a91bc3a44d52965b402dfaa81c1 100644 --- a/arch/um/kernel/mem.c +++ b/arch/um/kernel/mem.c @@ -375,3 +375,8 @@ pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) return pmd; } #endif + +void *uml_kmalloc(int size, int flags) +{ + return kmalloc(size, flags); +} diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c index 0d0cea2ac98d5df30a308aa4468b14db3f7f681b..c3e2f369c33cae2af0c682eb5a9a32a03781e056 100644 --- a/arch/um/kernel/time.c +++ b/arch/um/kernel/time.c @@ -75,7 +75,7 @@ static irqreturn_t um_timer(int irq, void *dev) static cycle_t itimer_read(void) { - return os_nsecs(); + return os_nsecs() / 1000; } static struct clocksource itimer_clocksource = { @@ -83,7 +83,7 @@ static struct clocksource itimer_clocksource = { .rating = 300, .read = itimer_read, .mask = CLOCKSOURCE_MASK(64), - .mult = 1, + .mult = 1000, .shift = 0, .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 56deed623446bd0726e2e7408d6f6bbc687df2b0..9db85b2ce6987141f314ea0dcc8ddc7f8960cdeb 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -150,7 +150,7 @@ __uml_setup("root=", uml_root_setup, static int __init no_skas_debug_setup(char *line, int *add) { printf("'debug' is not necessary to gdb UML in skas mode - run \n"); - printf("'gdb linux'"); + printf("'gdb linux'\n"); return 0; } @@ -258,6 +258,7 @@ int __init linux_main(int argc, char **argv) { unsigned long avail, diff; unsigned long virtmem_size, max_physmem; + unsigned long stack; unsigned int i; int add; char * mode; @@ -348,7 +349,9 @@ int __init linux_main(int argc, char **argv) } virtmem_size = physmem_size; - avail = TASK_SIZE - start_vm; + stack = (unsigned long) argv; + stack &= ~(1024 * 1024 - 1); + avail = stack - start_vm; if (physmem_size > avail) virtmem_size = avail; end_vm = start_vm + virtmem_size; diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S index 5828c1d54505f7fa0603c86a1b819fd52e528e7a..11b835248b865338f025a88d40a2c276ad3b7d88 100644 --- a/arch/um/kernel/uml.lds.S +++ b/arch/um/kernel/uml.lds.S @@ -1,4 +1,5 @@ #include +#include OUTPUT_FORMAT(ELF_FORMAT) OUTPUT_ARCH(ELF_ARCH) @@ -26,7 +27,7 @@ SECTIONS INIT_TEXT _einittext = .; } - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); .text : { @@ -39,7 +40,7 @@ SECTIONS *(.gnu.linkonce.t*) } - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); .syscall_stub : { __syscall_stub_start = .; *(.__syscall_stub*) @@ -79,7 +80,7 @@ SECTIONS .sdata : { *(.sdata) } _edata = .; PROVIDE (edata = .); - . = ALIGN(0x1000); + . = ALIGN(PAGE_SIZE); .sbss : { __bss_start = .; diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c index 6fb0b174f538df06711bf0f5b779f62ea4eb1f63..cc72cb2c1af61302ff98cc88516d0889dad40829 100644 --- a/arch/um/os-Linux/drivers/ethertap_user.c +++ b/arch/um/os-Linux/drivers/ethertap_user.c @@ -52,7 +52,7 @@ static void etap_change(int op, unsigned char *addr, unsigned char *netmask, return; } - output = kmalloc(UM_KERN_PAGE_SIZE, UM_GFP_KERNEL); + output = uml_kmalloc(UM_KERN_PAGE_SIZE, UM_GFP_KERNEL); if (output == NULL) printk(UM_KERN_ERR "etap_change : Failed to allocate output " "buffer\n"); @@ -165,7 +165,7 @@ static int etap_open(void *data) err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0], control_fds[1], data_fds[0], data_fds[1]); output_len = UM_KERN_PAGE_SIZE; - output = kmalloc(output_len, UM_GFP_KERNEL); + output = uml_kmalloc(output_len, UM_GFP_KERNEL); read_output(control_fds[0], output, output_len); if (output == NULL) diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c index f25c29a12d007676d736ed8b8fcb9c9e47a0eaed..74ca7aabf4e17374e8a38026b07b40b85580af76 100644 --- a/arch/um/os-Linux/helper.c +++ b/arch/um/os-Linux/helper.c @@ -71,8 +71,8 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv) data.pre_data = pre_data; data.argv = argv; data.fd = fds[1]; - data.buf = __cant_sleep() ? kmalloc(PATH_MAX, UM_GFP_ATOMIC) : - kmalloc(PATH_MAX, UM_GFP_KERNEL); + data.buf = __cant_sleep() ? uml_kmalloc(PATH_MAX, UM_GFP_ATOMIC) : + uml_kmalloc(PATH_MAX, UM_GFP_KERNEL); pid = clone(helper_child, (void *) sp, CLONE_VM, &data); if (pid < 0) { ret = -errno; diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c index abb9b0ffd9600402e770d93fce945c9b0295b98b..eee69b9f52c92bfd355303fd72b5afbf70502d7e 100644 --- a/arch/um/os-Linux/main.c +++ b/arch/um/os-Linux/main.c @@ -199,7 +199,7 @@ void *__wrap_malloc(int size) return __real_malloc(size); else if (size <= UM_KERN_PAGE_SIZE) /* finding contiguous pages can be hard*/ - ret = kmalloc(size, UM_GFP_KERNEL); + ret = uml_kmalloc(size, UM_GFP_KERNEL); else ret = vmalloc(size); /* diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c index abf47a7c4abd795c039f4c98136163819adb92a4..eb8f2e4be1929c8f731b8349bbf161afea27c751 100644 --- a/arch/um/os-Linux/sigio.c +++ b/arch/um/os-Linux/sigio.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * Copyright (C) 2002 - 2008 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ @@ -15,6 +15,7 @@ #include "kern_util.h" #include "init.h" #include "os.h" +#include "process.h" #include "sigio.h" #include "um_malloc.h" #include "user.h" @@ -109,7 +110,7 @@ static int need_poll(struct pollfds *polls, int n) if (n <= polls->size) return 0; - new = kmalloc(n * sizeof(struct pollfd), UM_GFP_ATOMIC); + new = uml_kmalloc(n * sizeof(struct pollfd), UM_GFP_ATOMIC); if (new == NULL) { printk(UM_KERN_ERR "need_poll : failed to allocate new " "pollfds\n"); @@ -243,7 +244,7 @@ static struct pollfd *setup_initial_poll(int fd) { struct pollfd *p; - p = kmalloc(sizeof(struct pollfd), UM_GFP_KERNEL); + p = uml_kmalloc(sizeof(struct pollfd), UM_GFP_KERNEL); if (p == NULL) { printk(UM_KERN_ERR "setup_initial_poll : failed to allocate " "poll\n"); @@ -338,20 +339,10 @@ out_close1: close(l_write_sigio_fds[1]); } -/* Changed during early boot */ -static int pty_output_sigio = 0; -static int pty_close_sigio = 0; - -void maybe_sigio_broken(int fd, int read) +void sigio_broken(int fd, int read) { int err; - if (!isatty(fd)) - return; - - if ((read || pty_output_sigio) && (!read || pty_close_sigio)) - return; - write_sigio_workaround(); sigio_lock(); @@ -370,6 +361,21 @@ out: sigio_unlock(); } +/* Changed during early boot */ +static int pty_output_sigio; +static int pty_close_sigio; + +void maybe_sigio_broken(int fd, int read) +{ + if (!isatty(fd)) + return; + + if ((read || pty_output_sigio) && (!read || pty_close_sigio)) + return; + + sigio_broken(fd, read); +} + static void sigio_cleanup(void) { if (write_sigio_pid == -1) @@ -383,7 +389,7 @@ static void sigio_cleanup(void) __uml_exitcall(sigio_cleanup); /* Used as a flag during SIGIO testing early in boot */ -static volatile int got_sigio = 0; +static int got_sigio; static void __init handler(int sig) { @@ -498,7 +504,8 @@ static void tty_output(int master, int slave) if (errno != EAGAIN) printk(UM_KERN_ERR "tty_output : write failed, errno = %d\n", errno); - while (((n = read(slave, buf, sizeof(buf))) > 0) && !got_sigio) + while (((n = read(slave, buf, sizeof(buf))) > 0) && + !({ barrier(); got_sigio; })) ; if (got_sigio) { diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index 3f1694b134cb2606efa628deb4291c5813a549c0..5aade6027e40e71f78ae1c49d5253a2a79bcc534 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c @@ -12,6 +12,7 @@ #include "as-layout.h" #include "kern_util.h" #include "os.h" +#include "process.h" #include "sysdep/barrier.h" #include "sysdep/sigcontext.h" #include "user.h" diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 1e8cba6550a99824df296e468747fabc109d6d44..6be028ca1817cfa0cab378ad0a49816798040b7b 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -442,7 +442,7 @@ void userspace(struct uml_pt_regs *regs) unblock_signals(); break; default: - printk(UM_KERN_ERR "userspace - child stopped " + printk(UM_KERN_ERR "userspace - child stopped " "with signal %d\n", sig); fatal_sigsegv(); } diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c index 997d01944f91d5c84e4778c59b1ac429c814b4bb..b4b36e0f2e8960d3d195d9617576fe02a8d86f08 100644 --- a/arch/um/os-Linux/start_up.c +++ b/arch/um/os-Linux/start_up.c @@ -23,6 +23,7 @@ #include "mem_user.h" #include "ptrace_user.h" #include "registers.h" +#include "skas.h" #include "skas_ptrace.h" static void ptrace_child(void) @@ -140,14 +141,27 @@ static int stop_ptraced_child(int pid, int exitcode, int mustexit) } /* Changed only during early boot */ -int ptrace_faultinfo = 1; -int ptrace_ldt = 1; -int proc_mm = 1; -int skas_needs_stub = 0; +int ptrace_faultinfo; +static int disable_ptrace_faultinfo; + +int ptrace_ldt; +static int disable_ptrace_ldt; + +int proc_mm; +static int disable_proc_mm; + +int have_switch_mm; +static int disable_switch_mm; + +int skas_needs_stub; static int __init skas0_cmd_param(char *str, int* add) { - ptrace_faultinfo = proc_mm = 0; + disable_ptrace_faultinfo = 1; + disable_ptrace_ldt = 1; + disable_proc_mm = 1; + disable_switch_mm = 1; + return 0; } @@ -157,15 +171,12 @@ static int __init mode_skas0_cmd_param(char *str, int* add) __attribute__((alias("skas0_cmd_param"))); __uml_setup("skas0", skas0_cmd_param, - "skas0\n" - " Disables SKAS3 usage, so that SKAS0 is used, unless \n" - " you specify mode=tt.\n\n"); +"skas0\n" +" Disables SKAS3 and SKAS4 usage, so that SKAS0 is used\n\n"); __uml_setup("mode=skas0", mode_skas0_cmd_param, - "mode=skas0\n" - " Disables SKAS3 usage, so that SKAS0 is used, unless you \n" - " specify mode=tt. Note that this was recently added - on \n" - " older kernels you must use simply \"skas0\".\n\n"); +"mode=skas0\n" +" Disables SKAS3 and SKAS4 usage, so that SKAS0 is used.\n\n"); /* Changed only during early boot */ static int force_sysemu_disabled = 0; @@ -360,7 +371,7 @@ void __init os_early_checks(void) static int __init noprocmm_cmd_param(char *str, int* add) { - proc_mm = 0; + disable_proc_mm = 1; return 0; } @@ -372,7 +383,7 @@ __uml_setup("noprocmm", noprocmm_cmd_param, static int __init noptracefaultinfo_cmd_param(char *str, int* add) { - ptrace_faultinfo = 0; + disable_ptrace_faultinfo = 1; return 0; } @@ -384,7 +395,7 @@ __uml_setup("noptracefaultinfo", noptracefaultinfo_cmd_param, static int __init noptraceldt_cmd_param(char *str, int* add) { - ptrace_ldt = 0; + disable_ptrace_ldt = 1; return 0; } @@ -404,17 +415,15 @@ static inline void check_skas3_ptrace_faultinfo(void) n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi); if (n < 0) { - ptrace_faultinfo = 0; if (errno == EIO) non_fatal("not found\n"); else perror("not found"); - } + } else if (disable_ptrace_faultinfo) + non_fatal("found but disabled on command line\n"); else { - if (!ptrace_faultinfo) - non_fatal("found but disabled on command line\n"); - else - non_fatal("found\n"); + ptrace_faultinfo = 1; + non_fatal("found\n"); } stop_ptraced_child(pid, 1, 1); @@ -437,38 +446,30 @@ static inline void check_skas3_ptrace_ldt(void) if (n < 0) { if (errno == EIO) non_fatal("not found\n"); - else { + else perror("not found"); - } - ptrace_ldt = 0; - } + } else if (disable_ptrace_ldt) + non_fatal("found, but use is disabled\n"); else { - if (ptrace_ldt) - non_fatal("found\n"); - else - non_fatal("found, but use is disabled\n"); + ptrace_ldt = 1; + non_fatal("found\n"); } stop_ptraced_child(pid, 1, 1); -#else - /* PTRACE_LDT might be disabled via cmdline option. - * We want to override this, else we might use the stub - * without real need - */ - ptrace_ldt = 1; #endif } static inline void check_skas3_proc_mm(void) { non_fatal(" - /proc/mm..."); - if (access("/proc/mm", W_OK) < 0) { - proc_mm = 0; + if (access("/proc/mm", W_OK) < 0) perror("not found"); - } - else if (!proc_mm) + else if (disable_proc_mm) non_fatal("found but disabled on command line\n"); - else non_fatal("found\n"); + else { + proc_mm = 1; + non_fatal("found\n"); + } } void can_do_skas(void) diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c index b613473b3ec1c1ef9ba83da234a207ef6f08aa38..c6183e7aec3d73cb2a4d0b70e27578b7a364afc1 100644 --- a/arch/um/os-Linux/sys-i386/registers.c +++ b/arch/um/os-Linux/sys-i386/registers.c @@ -5,6 +5,7 @@ */ #include +#include #include "kern_constants.h" #include "longjmp.h" #include "user.h" @@ -74,10 +75,10 @@ int put_fp_registers(int pid, unsigned long *regs) void arch_init_registers(int pid) { - unsigned long fpx_regs[HOST_XFP_SIZE]; + struct user_fxsr_struct fpx_regs; int err; - err = ptrace(PTRACE_GETFPXREGS, pid, 0, fpx_regs); + err = ptrace(PTRACE_GETFPXREGS, pid, 0, &fpx_regs); if (!err) return; diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c index e49280599465ec9ed4f44f4b0ffdf7e0807d2339..bee98f466d660543cd16d14ce355b6c2fc09db0a 100644 --- a/arch/um/os-Linux/time.c +++ b/arch/um/os-Linux/time.c @@ -9,7 +9,9 @@ #include #include #include "kern_constants.h" +#include "kern_util.h" #include "os.h" +#include "process.h" #include "user.h" int set_interval(void) @@ -58,12 +60,17 @@ static inline long long timeval_to_ns(const struct timeval *tv) long long disable_timer(void) { struct itimerval time = ((struct itimerval) { { 0, 0 }, { 0, 0 } }); + int remain, max = UM_NSEC_PER_SEC / UM_HZ; if (setitimer(ITIMER_VIRTUAL, &time, &time) < 0) printk(UM_KERN_ERR "disable_timer - setitimer failed, " "errno = %d\n", errno); - return timeval_to_ns(&time.it_value); + remain = timeval_to_ns(&time.it_value); + if (remain > max) + remain = max; + + return remain; } long long os_nsecs(void) @@ -79,7 +86,44 @@ static int after_sleep_interval(struct timespec *ts) { return 0; } + +static void deliver_alarm(void) +{ + alarm_handler(SIGVTALRM, NULL); +} + +static unsigned long long sleep_time(unsigned long long nsecs) +{ + return nsecs; +} + #else +unsigned long long last_tick; +unsigned long long skew; + +static void deliver_alarm(void) +{ + unsigned long long this_tick = os_nsecs(); + int one_tick = UM_NSEC_PER_SEC / UM_HZ; + + if (last_tick == 0) + last_tick = this_tick - one_tick; + + skew += this_tick - last_tick; + + while (skew >= one_tick) { + alarm_handler(SIGVTALRM, NULL); + skew -= one_tick; + } + + last_tick = this_tick; +} + +static unsigned long long sleep_time(unsigned long long nsecs) +{ + return nsecs > skew ? nsecs - skew : 0; +} + static inline long long timespec_to_us(const struct timespec *ts) { return ((long long) ts->tv_sec * UM_USEC_PER_SEC) + @@ -102,6 +146,8 @@ static int after_sleep_interval(struct timespec *ts) */ if (start_usecs > usec) start_usecs = usec; + + start_usecs -= skew / UM_NSEC_PER_USEC; tv = ((struct timeval) { .tv_sec = start_usecs / UM_USEC_PER_SEC, .tv_usec = start_usecs % UM_USEC_PER_SEC }); interval = ((struct itimerval) { { 0, usec }, tv }); @@ -113,8 +159,6 @@ static int after_sleep_interval(struct timespec *ts) } #endif -extern void alarm_handler(int sig, struct sigcontext *sc); - void idle_sleep(unsigned long long nsecs) { struct timespec ts; @@ -126,10 +170,12 @@ void idle_sleep(unsigned long long nsecs) */ if (nsecs == 0) nsecs = UM_NSEC_PER_SEC / UM_HZ; + + nsecs = sleep_time(nsecs); ts = ((struct timespec) { .tv_sec = nsecs / UM_NSEC_PER_SEC, .tv_nsec = nsecs % UM_NSEC_PER_SEC }); if (nanosleep(&ts, &ts) == 0) - alarm_handler(SIGVTALRM, NULL); + deliver_alarm(); after_sleep_interval(&ts); } diff --git a/arch/um/sys-i386/ptrace.c b/arch/um/sys-i386/ptrace.c index 6b4499906a6c96be3139a594681b7c632b8139c1..c9b176534d65bd15d97a86769cf978c510b7c475 100644 --- a/arch/um/sys-i386/ptrace.c +++ b/arch/um/sys-i386/ptrace.c @@ -148,14 +148,13 @@ int peek_user(struct task_struct *child, long addr, long data) int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) { int err, n, cpu = ((struct thread_info *) child->stack)->cpu; - long fpregs[HOST_FP_SIZE]; + struct user_i387_struct fpregs; - BUG_ON(sizeof(*buf) != sizeof(fpregs)); - err = save_fp_registers(userspace_pid[cpu], fpregs); + err = save_fp_registers(userspace_pid[cpu], (unsigned long *) &fpregs); if (err) return err; - n = copy_to_user(buf, fpregs, sizeof(fpregs)); + n = copy_to_user(buf, &fpregs, sizeof(fpregs)); if(n > 0) return -EFAULT; @@ -165,27 +164,26 @@ int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) { int n, cpu = ((struct thread_info *) child->stack)->cpu; - long fpregs[HOST_FP_SIZE]; + struct user_i387_struct fpregs; - BUG_ON(sizeof(*buf) != sizeof(fpregs)); - n = copy_from_user(fpregs, buf, sizeof(fpregs)); + n = copy_from_user(&fpregs, buf, sizeof(fpregs)); if (n > 0) return -EFAULT; - return restore_fp_registers(userspace_pid[cpu], fpregs); + return restore_fp_registers(userspace_pid[cpu], + (unsigned long *) &fpregs); } int get_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child) { int err, n, cpu = ((struct thread_info *) child->stack)->cpu; - long fpregs[HOST_XFP_SIZE]; + struct user_fxsr_struct fpregs; - BUG_ON(sizeof(*buf) != sizeof(fpregs)); - err = save_fpx_registers(userspace_pid[cpu], fpregs); + err = save_fpx_registers(userspace_pid[cpu], (unsigned long *) &fpregs); if (err) return err; - n = copy_to_user(buf, fpregs, sizeof(fpregs)); + n = copy_to_user(buf, &fpregs, sizeof(fpregs)); if(n > 0) return -EFAULT; @@ -195,14 +193,14 @@ int get_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child) int set_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child) { int n, cpu = ((struct thread_info *) child->stack)->cpu; - long fpregs[HOST_XFP_SIZE]; + struct user_fxsr_struct fpregs; - BUG_ON(sizeof(*buf) != sizeof(fpregs)); - n = copy_from_user(fpregs, buf, sizeof(fpregs)); + n = copy_from_user(&fpregs, buf, sizeof(fpregs)); if (n > 0) return -EFAULT; - return restore_fpx_registers(userspace_pid[cpu], fpregs); + return restore_fpx_registers(userspace_pid[cpu], + (unsigned long *) &fpregs); } long subarch_ptrace(struct task_struct *child, long request, long addr, diff --git a/arch/um/sys-i386/user-offsets.c b/arch/um/sys-i386/user-offsets.c index 39bd32bf84f0bbe029398e1c3076d7ca2092767f..5f883bfe773fe37899f361507131129e800059d8 100644 --- a/arch/um/sys-i386/user-offsets.c +++ b/arch/um/sys-i386/user-offsets.c @@ -22,7 +22,7 @@ void foo(void) OFFSET(HOST_SC_CR2, sigcontext, cr2); DEFINE_LONGS(HOST_FP_SIZE, sizeof(struct user_fpregs_struct)); - DEFINE_LONGS(HOST_XFP_SIZE, sizeof(struct user_fpxregs_struct)); + DEFINE_LONGS(HOST_FPX_SIZE, sizeof(struct user_fpxregs_struct)); DEFINE(HOST_IP, EIP); DEFINE(HOST_SP, UESP); diff --git a/arch/um/sys-x86_64/user-offsets.c b/arch/um/sys-x86_64/user-offsets.c index 2f3443c6e859f4d890ef8b4e8c21c03c2e7bb152..973585414a66372e3f5e3e30f57a2842e10fed3f 100644 --- a/arch/um/sys-x86_64/user-offsets.c +++ b/arch/um/sys-x86_64/user-offsets.c @@ -24,7 +24,6 @@ void foo(void) OFFSET(HOST_SC_TRAPNO, sigcontext, trapno); DEFINE(HOST_FP_SIZE, sizeof(struct _fpstate) / sizeof(unsigned long)); - DEFINE(HOST_XFP_SIZE, 0); DEFINE_LONGS(HOST_RBX, RBX); DEFINE_LONGS(HOST_RCX, RCX); DEFINE_LONGS(HOST_RDI, RDI); diff --git a/arch/v850/kernel/init_task.c b/arch/v850/kernel/init_task.c index ed2f93cf7c666379f0df923d5d3da34aac608641..44b274dff33fb043e5ec9763cdc03b1cdcd559fb 100644 --- a/arch/v850/kernel/init_task.c +++ b/arch/v850/kernel/init_task.c @@ -21,7 +21,6 @@ #include static struct fs_struct init_fs = INIT_FS; -static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS (init_signals); static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); struct mm_struct init_mm = INIT_MM (init_mm); diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index bbcafaa160c04f566c470a0978cba652669c4fa9..fe361ae7ef2f18ecffe362e0c492c29d370347ba 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -335,6 +335,7 @@ config X86_RDC321X select GENERIC_GPIO select LEDS_CLASS select LEDS_GPIO + select NEW_LEDS help This option is needed for RDC R-321x system-on-chip, also known as R-8610-(G). @@ -1662,7 +1663,6 @@ config GEODE_MFGPT_TIMER config OLPC bool "One Laptop Per Child support" - depends on MGEODE_LX default n help Add support for detecting the unique features of the OLPC diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index bbdacb398d48e05a05c17f23af0d2b650751d912..5e618c3b47208ed2f301c685a5596135b30cc78f 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -83,9 +83,7 @@ obj-$(CONFIG_KVM_GUEST) += kvm.o obj-$(CONFIG_KVM_CLOCK) += kvmclock.o obj-$(CONFIG_PARAVIRT) += paravirt.o paravirt_patch_$(BITS).o -ifdef CONFIG_INPUT_PCSPKR -obj-y += pcspeaker.o -endif +obj-$(CONFIG_PCSPKR_PLATFORM) += pcspeaker.o obj-$(CONFIG_SCx200) += scx200.o scx200-y += scx200_32.o diff --git a/arch/x86/kernel/acpi/realmode/wakeup.lds.S b/arch/x86/kernel/acpi/realmode/wakeup.lds.S index 22fab6c4be157b3a09d2bb78d389da403451879f..7da00b799cdab3806c97a42e4e854754c57fe01b 100644 --- a/arch/x86/kernel/acpi/realmode/wakeup.lds.S +++ b/arch/x86/kernel/acpi/realmode/wakeup.lds.S @@ -12,11 +12,6 @@ ENTRY(_start) SECTIONS { - . = HEADER_OFFSET; - .header : { - *(.header) - } - . = 0; .text : { *(.text*) @@ -50,6 +45,11 @@ SECTIONS __bss_end = .; } + . = HEADER_OFFSET; + .header : { + *(.header) + } + . = ALIGN(16); _end = .; diff --git a/arch/x86/kernel/cpu/addon_cpuid_features.c b/arch/x86/kernel/cpu/addon_cpuid_features.c index 238468ae19931be3116e1e9de9ae0f0c1db1d2e2..c2e1ce33c7cb0e9a9bdab5d16c204c9a83447f7a 100644 --- a/arch/x86/kernel/cpu/addon_cpuid_features.c +++ b/arch/x86/kernel/cpu/addon_cpuid_features.c @@ -6,6 +6,7 @@ #include +#include #include struct cpuid_bit { @@ -48,3 +49,23 @@ void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c) set_cpu_cap(c, cb->feature); } } + +#ifdef CONFIG_X86_PAT +void __cpuinit validate_pat_support(struct cpuinfo_x86 *c) +{ + switch (c->x86_vendor) { + case X86_VENDOR_AMD: + if (c->x86 >= 0xf && c->x86 <= 0x11) + return; + break; + case X86_VENDOR_INTEL: + if (c->x86 == 0xF || (c->x86 == 6 && c->x86_model >= 15)) + return; + break; + } + + pat_disable(cpu_has_pat ? + "PAT disabled. Not yet verified on this CPU type." : + "PAT not supported by CPU."); +} +#endif diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 35b4f6a9c8effca5b2a609aedb669417d26b5f66..d0463a9462477716bd065b5c822cd34e96812282 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -12,6 +12,7 @@ #include #include #include +#include #ifdef CONFIG_X86_LOCAL_APIC #include #include @@ -308,19 +309,6 @@ static void __cpuinit early_get_cap(struct cpuinfo_x86 *c) } - clear_cpu_cap(c, X86_FEATURE_PAT); - - switch (c->x86_vendor) { - case X86_VENDOR_AMD: - if (c->x86 >= 0xf && c->x86 <= 0x11) - set_cpu_cap(c, X86_FEATURE_PAT); - break; - case X86_VENDOR_INTEL: - if (c->x86 == 0xF || (c->x86 == 6 && c->x86_model >= 15)) - set_cpu_cap(c, X86_FEATURE_PAT); - break; - } - } /* @@ -409,18 +397,6 @@ static void __cpuinit generic_identify(struct cpuinfo_x86 *c) init_scattered_cpuid_features(c); } - clear_cpu_cap(c, X86_FEATURE_PAT); - - switch (c->x86_vendor) { - case X86_VENDOR_AMD: - if (c->x86 >= 0xf && c->x86 <= 0x11) - set_cpu_cap(c, X86_FEATURE_PAT); - break; - case X86_VENDOR_INTEL: - if (c->x86 == 0xF || (c->x86 == 6 && c->x86_model >= 15)) - set_cpu_cap(c, X86_FEATURE_PAT); - break; - } } static void __cpuinit squash_the_stupid_serial_number(struct cpuinfo_x86 *c) @@ -651,6 +627,7 @@ void __init early_cpu_init(void) cpu_devs[cvdev->vendor] = cvdev->cpu_dev; early_cpu_detect(); + validate_pat_support(&boot_cpu_data); } /* Make sure %fs is initialized properly in idle threads */ diff --git a/arch/x86/kernel/geode_32.c b/arch/x86/kernel/geode_32.c index 9dad6ca6cd70d2812426d7da93224aeaa2d69e33..e8edd63ab000cd5d13c3ecf8aab94341b2828df4 100644 --- a/arch/x86/kernel/geode_32.c +++ b/arch/x86/kernel/geode_32.c @@ -161,6 +161,25 @@ void geode_gpio_setup_event(unsigned int gpio, int pair, int pme) } EXPORT_SYMBOL_GPL(geode_gpio_setup_event); +int geode_has_vsa2(void) +{ + static int has_vsa2 = -1; + + if (has_vsa2 == -1) { + /* + * The VSA has virtual registers that we can query for a + * signature. + */ + outw(VSA_VR_UNLOCK, VSA_VRC_INDEX); + outw(VSA_VR_SIGNATURE, VSA_VRC_INDEX); + + has_vsa2 = (inw(VSA_VRC_DATA) == VSA_SIG); + } + + return has_vsa2; +} +EXPORT_SYMBOL_GPL(geode_has_vsa2); + static int __init geode_southbridge_init(void) { if (!is_geode()) diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c index db6839b53195e1a83d9186a76bf9a05562fc39e6..e03cc952f233db9a2d77a1592798a96cf68a0674 100644 --- a/arch/x86/kernel/i387.c +++ b/arch/x86/kernel/i387.c @@ -450,7 +450,6 @@ static inline int restore_i387_fsave(struct _fpstate_ia32 __user *buf) { struct task_struct *tsk = current; - clear_fpu(tsk); return __copy_from_user(&tsk->thread.xstate->fsave, buf, sizeof(struct i387_fsave_struct)); } @@ -461,7 +460,6 @@ static int restore_i387_fxsave(struct _fpstate_ia32 __user *buf) struct user_i387_ia32_struct env; int err; - clear_fpu(tsk); err = __copy_from_user(&tsk->thread.xstate->fxsave, &buf->_fxsr_env[0], sizeof(struct i387_fxsave_struct)); /* mxcsr reserved bits must be masked to zero for security reasons */ @@ -478,6 +476,16 @@ int restore_i387_ia32(struct _fpstate_ia32 __user *buf) int err; if (HAVE_HWFP) { + struct task_struct *tsk = current; + + clear_fpu(tsk); + + if (!used_math()) { + err = init_fpu(tsk); + if (err) + return err; + } + if (cpu_has_fxsr) err = restore_i387_fxsave(buf); else diff --git a/arch/x86/kernel/init_task.c b/arch/x86/kernel/init_task.c index 3d01e47777db6106a2387016f39a6c70bd744ece..a4f93b4120c155c20889947942d7bdb5c286908d 100644 --- a/arch/x86/kernel/init_task.c +++ b/arch/x86/kernel/init_task.c @@ -11,7 +11,6 @@ #include static struct fs_struct init_fs = INIT_FS; -static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS(init_signals); static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); struct mm_struct init_mm = INIT_MM(init_mm); diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c index 0c37f16b69502e1fe31f4e94c80775dc1fd22060..c5ef1af8e79de6883b005cfa99d59bb9164e978c 100644 --- a/arch/x86/kernel/pci-dma.c +++ b/arch/x86/kernel/pci-dma.c @@ -385,11 +385,13 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, if (dma_alloc_from_coherent_mem(dev, size, dma_handle, &memory)) return memory; - if (!dev) + if (!dev) { dev = &fallback_dev; + gfp |= GFP_DMA; + } dma_mask = dev->coherent_dma_mask; if (dma_mask == 0) - dma_mask = DMA_32BIT_MASK; + dma_mask = (gfp & GFP_DMA) ? DMA_24BIT_MASK : DMA_32BIT_MASK; /* Device not DMA able */ if (dev->dma_mask == NULL) @@ -403,7 +405,7 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, larger than 16MB and in this case we have a chance of finding fitting memory in the next higher zone first. If not retry with true GFP_DMA. -AK */ - if (dma_mask <= DMA_32BIT_MASK) + if (dma_mask <= DMA_32BIT_MASK && !(gfp & GFP_DMA)) gfp |= GFP_DMA32; #endif diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 67e9b4a1e89d5a1ac3a3851beaab9d48bbe22c0b..ba370dc8685bf8f9bf31e9100f78c4e800ea755e 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -99,15 +99,6 @@ static void mwait_idle(void) local_irq_enable(); } - -static int __cpuinit mwait_usable(const struct cpuinfo_x86 *c) -{ - if (force_mwait) - return 1; - /* Any C1 states supported? */ - return c->cpuid_level >= 5 && ((cpuid_edx(5) >> 4) & 0xf) > 0; -} - /* * On SMP it's slightly faster (but much more power-consuming!) * to poll the ->work.need_resched flag instead of waiting for the @@ -119,6 +110,33 @@ static void poll_idle(void) cpu_relax(); } +/* + * mwait selection logic: + * + * It depends on the CPU. For AMD CPUs that support MWAIT this is + * wrong. Family 0x10 and 0x11 CPUs will enter C1 on HLT. Powersavings + * then depend on a clock divisor and current Pstate of the core. If + * all cores of a processor are in halt state (C1) the processor can + * enter the C1E (C1 enhanced) state. If mwait is used this will never + * happen. + * + * idle=mwait overrides this decision and forces the usage of mwait. + */ +static int __cpuinit mwait_usable(const struct cpuinfo_x86 *c) +{ + if (force_mwait) + return 1; + + if (c->x86_vendor == X86_VENDOR_AMD) { + switch(c->x86) { + case 0x10: + case 0x11: + return 0; + } + } + return 1; +} + void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) { static int selected; diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index fb03ef380f0e230ebf5f3835bc7ec57e1c9fed20..a7835f2829361bcd964f85118839751fba24b12b 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -1303,6 +1303,9 @@ static const struct user_regset_view user_x86_64_view = { #define genregs32_get genregs_get #define genregs32_set genregs_set +#define user_i387_ia32_struct user_i387_struct +#define user32_fxsr_struct user_fxsr_struct + #endif /* CONFIG_X86_64 */ #if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION @@ -1315,13 +1318,13 @@ static const struct user_regset x86_32_regsets[] = { }, [REGSET_FP] = { .core_note_type = NT_PRFPREG, - .n = sizeof(struct user_i387_struct) / sizeof(u32), + .n = sizeof(struct user_i387_ia32_struct) / sizeof(u32), .size = sizeof(u32), .align = sizeof(u32), .active = fpregs_active, .get = fpregs_get, .set = fpregs_set }, [REGSET_XFP] = { .core_note_type = NT_PRXFPREG, - .n = sizeof(struct user_i387_struct) / sizeof(u32), + .n = sizeof(struct user32_fxsr_struct) / sizeof(u32), .size = sizeof(u32), .align = sizeof(u32), .active = xfpregs_active, .get = xfpregs_get, .set = xfpregs_set }, diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index cc6f5eb20b24316a08e85a926c808cf3512bffab..6f80b852a1961a6b496bc2404c5194769557d97a 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -12,6 +12,7 @@ #include #include +#ifdef CONFIG_X86_LOCAL_APIC unsigned int num_processors; unsigned disabled_cpus __cpuinitdata; /* Processor that is doing the boot up */ @@ -23,8 +24,9 @@ EXPORT_PER_CPU_SYMBOL(x86_cpu_to_apicid); /* Bitmask of physically existing CPUs */ physid_mask_t phys_cpu_present_map; +#endif -#if defined(CONFIG_HAVE_SETUP_PER_CPU_AREA) && defined(CONFIG_SMP) +#if defined(CONFIG_HAVE_SETUP_PER_CPU_AREA) && defined(CONFIG_X86_SMP) /* * Copy data used in early init routines from the initial arrays to the * per cpu data areas. These arrays then become expendable and the @@ -95,7 +97,7 @@ void __init setup_per_cpu_areas(void) /* Copy section for each CPU (we discard the original) */ size = PERCPU_ENOUGH_ROOM; - printk(KERN_INFO "PERCPU: Allocating %zd bytes of per cpu data\n", + printk(KERN_INFO "PERCPU: Allocating %lu bytes of per cpu data\n", size); for_each_possible_cpu(i) { diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 2283422af7946fef30a86189dddb0a7a12fe3fc1..2c5f8b213e868658d8ad189bb925151dea3bc7b1 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -127,7 +127,12 @@ static struct resource standard_io_resources[] = { { }, { .name = "keyboard", .start = 0x0060, - .end = 0x006f, + .end = 0x0060, + .flags = IORESOURCE_BUSY | IORESOURCE_IO +}, { + .name = "keyboard", + .start = 0x0064, + .end = 0x0064, .flags = IORESOURCE_BUSY | IORESOURCE_IO }, { .name = "dma page reg", diff --git a/arch/x86/kernel/setup_64.c b/arch/x86/kernel/setup_64.c index 22c14e21c97c435a8d172d8f23159738bf0dbe2f..6dff1286ad8adec4b9fc6bb7808c3a233c476fd2 100644 --- a/arch/x86/kernel/setup_64.c +++ b/arch/x86/kernel/setup_64.c @@ -70,6 +70,7 @@ #include #include #include +#include #include #ifdef CONFIG_PARAVIRT @@ -128,7 +129,9 @@ static struct resource standard_io_resources[] = { .flags = IORESOURCE_BUSY | IORESOURCE_IO }, { .name = "timer1", .start = 0x50, .end = 0x53, .flags = IORESOURCE_BUSY | IORESOURCE_IO }, - { .name = "keyboard", .start = 0x60, .end = 0x6f, + { .name = "keyboard", .start = 0x60, .end = 0x60, + .flags = IORESOURCE_BUSY | IORESOURCE_IO }, + { .name = "keyboard", .start = 0x64, .end = 0x64, .flags = IORESOURCE_BUSY | IORESOURCE_IO }, { .name = "dma page reg", .start = 0x80, .end = 0x8f, .flags = IORESOURCE_BUSY | IORESOURCE_IO }, @@ -948,7 +951,7 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) static void __cpuinit early_init_centaur(struct cpuinfo_x86 *c) { if (c->x86 == 0x6 && c->x86_model >= 0xf) - set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability); + set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); } static void __cpuinit init_centaur(struct cpuinfo_x86 *c) @@ -1063,25 +1066,19 @@ static void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c) if (c->extended_cpuid_level >= 0x80000007) c->x86_power = cpuid_edx(0x80000007); - - clear_cpu_cap(c, X86_FEATURE_PAT); - switch (c->x86_vendor) { case X86_VENDOR_AMD: early_init_amd(c); - if (c->x86 >= 0xf && c->x86 <= 0x11) - set_cpu_cap(c, X86_FEATURE_PAT); break; case X86_VENDOR_INTEL: early_init_intel(c); - if (c->x86 == 0xF || (c->x86 == 6 && c->x86_model >= 15)) - set_cpu_cap(c, X86_FEATURE_PAT); break; case X86_VENDOR_CENTAUR: early_init_centaur(c); break; } + validate_pat_support(c); } /* diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c index 8f75893a6467e0e00c62e55b154fa674ae839e1c..0cb7aadc87cd44a5e0c2402731cadbfd8c88ce8d 100644 --- a/arch/x86/kernel/smp.c +++ b/arch/x86/kernel/smp.c @@ -231,7 +231,8 @@ native_smp_call_function_mask(cpumask_t mask, wmb(); /* Send a message to other CPUs */ - if (cpus_equal(mask, allbutself)) + if (cpus_equal(mask, allbutself) && + cpus_equal(cpu_online_map, cpu_callout_map)) send_IPI_allbutself(CALL_FUNCTION_VECTOR); else send_IPI_mask(mask, CALL_FUNCTION_VECTOR); diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 6b087ab6cd8f3e3ea6c35c4bbe73ae85ae0d0686..38988491c6222e99c6bb7772eb09ee0cc81fb270 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -86,6 +86,7 @@ void *x86_bios_cpu_apicid_early_ptr; #ifdef CONFIG_X86_32 u8 apicid_2_node[MAX_APICID]; +static int low_mappings; #endif /* State of each CPU */ @@ -326,6 +327,12 @@ static void __cpuinit start_secondary(void *unused) enable_8259A_irq(0); } +#ifdef CONFIG_X86_32 + while (low_mappings) + cpu_relax(); + __flush_tlb_all(); +#endif + /* This must be done before setting cpu_online_map */ set_cpu_sibling_map(raw_smp_processor_id()); wmb(); @@ -1040,14 +1047,20 @@ int __cpuinit native_cpu_up(unsigned int cpu) #ifdef CONFIG_X86_32 /* init low mem mapping */ clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY, - min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY)); + min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY)); flush_tlb_all(); -#endif + low_mappings = 1; err = do_boot_cpu(apicid, cpu); - if (err < 0) { + + zap_low_mappings(); + low_mappings = 0; +#else + err = do_boot_cpu(apicid, cpu); +#endif + if (err) { Dprintk("do_boot_cpu failed %d\n", err); - return err; + return -EIO; } /* @@ -1259,9 +1272,6 @@ void __init native_smp_cpus_done(unsigned int max_cpus) setup_ioapic_dest(); #endif check_nmi_watchdog(); -#ifdef CONFIG_X86_32 - zap_low_mappings(); -#endif } #ifdef CONFIG_HOTPLUG_CPU diff --git a/arch/x86/kernel/x8664_ksyms_64.c b/arch/x86/kernel/x8664_ksyms_64.c index 58882f9f2637b03c0647f52b5e0901ab2deac582..f6c05d0410fb08717fe7f736320225bc476f0533 100644 --- a/arch/x86/kernel/x8664_ksyms_64.c +++ b/arch/x86/kernel/x8664_ksyms_64.c @@ -2,6 +2,7 @@ All C exports should go in the respective C files. */ #include +#include #include #include @@ -29,6 +30,8 @@ EXPORT_SYMBOL(__copy_from_user_inatomic); EXPORT_SYMBOL(copy_page); EXPORT_SYMBOL(clear_page); +EXPORT_SYMBOL(csum_partial); + /* * Export string functions. We normally rely on gcc builtin for most of these, * but gcc sometimes decides not to inline them. diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c index 3324d90038e438ab1361d53f31be78948d72aba8..7c077a9d97770c8faee45123b9c049eeb8b33465 100644 --- a/arch/x86/kvm/i8254.c +++ b/arch/x86/kvm/i8254.c @@ -216,7 +216,7 @@ int pit_has_pending_timer(struct kvm_vcpu *vcpu) { struct kvm_pit *pit = vcpu->kvm->arch.vpit; - if (pit && vcpu->vcpu_id == 0) + if (pit && vcpu->vcpu_id == 0 && pit->pit_state.inject_pending) return atomic_read(&pit->pit_state.pit_timer.pending); return 0; diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 36809d79788bedffcd8332609c7313175aa09e3a..c297c50eba63535968f72c1596d6a969fb4eb9c9 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -957,7 +957,7 @@ int apic_has_pending_timer(struct kvm_vcpu *vcpu) { struct kvm_lapic *lapic = vcpu->arch.apic; - if (lapic) + if (lapic && apic_enabled(lapic) && apic_lvt_enabled(lapic, APIC_LVTT)) return atomic_read(&lapic->timer.pending); return 0; diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index f2a696d6a24383b893504be0eb7a2a904d7abab3..8a96320ab071b06f1d3102518b55877d297517b8 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c @@ -677,8 +677,9 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt, c->use_modrm_ea = 1; if (c->modrm_mod == 3) { - c->modrm_val = *(unsigned long *) - decode_register(c->modrm_rm, c->regs, c->d & ByteOp); + c->modrm_ptr = decode_register(c->modrm_rm, + c->regs, c->d & ByteOp); + c->modrm_val = *(unsigned long *)c->modrm_ptr; return rc; } @@ -1005,6 +1006,7 @@ done_prefixes: if ((c->d & ModRM) && c->modrm_mod == 3) { c->src.type = OP_REG; c->src.val = c->modrm_val; + c->src.ptr = c->modrm_ptr; break; } c->src.type = OP_MEM; @@ -1049,6 +1051,7 @@ done_prefixes: if ((c->d & ModRM) && c->modrm_mod == 3) { c->dst.type = OP_REG; c->dst.val = c->dst.orig_val = c->modrm_val; + c->dst.ptr = c->modrm_ptr; break; } c->dst.type = OP_MEM; diff --git a/arch/x86/lib/csum-partial_64.c b/arch/x86/lib/csum-partial_64.c index bc503f506903a486a9a2fb4c56afd144466fff18..bf51144d97e1ffa4d19bc82968146f02db564888 100644 --- a/arch/x86/lib/csum-partial_64.c +++ b/arch/x86/lib/csum-partial_64.c @@ -136,8 +136,6 @@ __wsum csum_partial(const void *buff, int len, __wsum sum) (__force u32)sum); } -EXPORT_SYMBOL(csum_partial); - /* * this routine is used for miscellaneous IP-like checksums, mainly * in icmp.c diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c index de236e419cb5f019feb154b710d519f6c3c95f55..ec30d10154b657a63ab07b5e25b4298c10f4aabe 100644 --- a/arch/x86/mm/init_32.c +++ b/arch/x86/mm/init_32.c @@ -438,8 +438,6 @@ void zap_low_mappings(void) { int i; - save_pg_dir(); - /* * Zap initial low-memory mappings. * @@ -663,16 +661,8 @@ void __init mem_init(void) test_wp_bit(); cpa_init(); - - /* - * Subtle. SMP is doing it's boot stuff late (because it has to - * fork idle threads) - but it also needs low mappings for the - * protected-mode entry to work. We zap these entries only after - * the WP-bit has been tested. - */ -#ifndef CONFIG_SMP + save_pg_dir(); zap_low_mappings(); -#endif } #ifdef CONFIG_MEMORY_HOTPLUG diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index 277446cd30b6de81a4634061949385cb6eaede69..de3a998124506df3c4a43011033dfb55602f2d59 100644 --- a/arch/x86/mm/pat.c +++ b/arch/x86/mm/pat.c @@ -25,31 +25,24 @@ #include #include -int pat_wc_enabled = 1; +#ifdef CONFIG_X86_PAT +int __read_mostly pat_wc_enabled = 1; -static u64 __read_mostly boot_pat_state; - -static int nopat(char *str) +void __cpuinit pat_disable(char *reason) { pat_wc_enabled = 0; - printk(KERN_INFO "x86: PAT support disabled.\n"); - - return 0; + printk(KERN_INFO "%s\n", reason); } -early_param("nopat", nopat); -static int pat_known_cpu(void) +static int nopat(char *str) { - if (!pat_wc_enabled) - return 0; - - if (cpu_has_pat) - return 1; - - pat_wc_enabled = 0; - printk(KERN_INFO "CPU and/or kernel does not support PAT.\n"); + pat_disable("PAT support disabled."); return 0; } +early_param("nopat", nopat); +#endif + +static u64 __read_mostly boot_pat_state; enum { PAT_UC = 0, /* uncached */ @@ -66,17 +59,19 @@ void pat_init(void) { u64 pat; -#ifndef CONFIG_X86_PAT - nopat(NULL); -#endif - - /* Boot CPU enables PAT based on CPU feature */ - if (!smp_processor_id() && !pat_known_cpu()) + if (!pat_wc_enabled) return; - /* APs enable PAT iff boot CPU has enabled it before */ - if (smp_processor_id() && !pat_wc_enabled) - return; + /* Paranoia check. */ + if (!cpu_has_pat) { + printk(KERN_ERR "PAT enabled, but CPU feature cleared\n"); + /* + * Panic if this happens on the secondary CPU, and we + * switched to PAT on the boot CPU. We have no way to + * undo PAT. + */ + BUG_ON(boot_pat_state); + } /* Set PWT to Write-Combining. All other bits stay the same */ /* @@ -95,9 +90,8 @@ void pat_init(void) PAT(4,WB) | PAT(5,WC) | PAT(6,UC_MINUS) | PAT(7,UC); /* Boot CPU check */ - if (!smp_processor_id()) { + if (!boot_pat_state) rdmsrl(MSR_IA32_CR_PAT, boot_pat_state); - } wrmsrl(MSR_IA32_CR_PAT, pat); printk(KERN_INFO "x86 PAT enabled: cpu %d, old 0x%Lx, new 0x%Lx\n", @@ -561,7 +555,7 @@ int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn, "%s:%d /dev/mem ioremap_change_attr failed %s for %Lx-%Lx\n", current->comm, current->pid, cattr_name(flags), - offset, offset + size); + offset, (unsigned long long)(offset + size)); return 0; } @@ -582,7 +576,7 @@ void map_devmem(unsigned long pfn, unsigned long size, pgprot_t vma_prot) "%s:%d /dev/mem expected mapping type %s for %Lx-%Lx, got %s\n", current->comm, current->pid, cattr_name(want_flags), - addr, addr + size, + addr, (unsigned long long)(addr + size), cattr_name(flags)); } } diff --git a/arch/x86/mm/pgtable_32.c b/arch/x86/mm/pgtable_32.c index 9ee007be914299ab8dae9d3f52df22ae606816f1..369cf065b6a48f78f9870ddaf9f27e59b6980c0c 100644 --- a/arch/x86/mm/pgtable_32.c +++ b/arch/x86/mm/pgtable_32.c @@ -172,10 +172,3 @@ void reserve_top_address(unsigned long reserve) __FIXADDR_TOP = -reserve - PAGE_SIZE; __VMALLOC_RESERVE += reserve; } - -int pmd_bad(pmd_t pmd) -{ - WARN_ON_ONCE(pmd_bad_v1(pmd) != pmd_bad_v2(pmd)); - - return pmd_bad_v1(pmd); -} diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index bfa72a9475b33470e406f8019ec4b8e0ce340b40..8545c8a9d107c1947243eb38f1bba77dc1f58ff8 100644 --- a/arch/x86/pci/common.c +++ b/arch/x86/pci/common.c @@ -77,19 +77,6 @@ int pcibios_scanned; */ DEFINE_SPINLOCK(pci_config_lock); -static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) -{ - struct resource *rom_r = &dev->resource[PCI_ROM_RESOURCE]; - - if (rom_r->parent) - return; - if (rom_r->start) - /* we deal with BIOS assigned ROM later */ - return; - if (!(pci_probe & PCI_ASSIGN_ROMS)) - rom_r->start = rom_r->end = rom_r->flags = 0; -} - static int __devinit can_skip_ioresource_align(const struct dmi_system_id *d) { pci_probe |= PCI_CAN_SKIP_ISA_ALIGN; @@ -141,11 +128,7 @@ void __init dmi_check_skip_isa_align(void) void __devinit pcibios_fixup_bus(struct pci_bus *b) { - struct pci_dev *dev; - pci_read_bridge_bases(b); - list_for_each_entry(dev, &b->devices, bus_list) - pcibios_fixup_device_resources(dev); } /* diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c index 8af0f0bae2af45f0baca08051056946235db7d1e..10fb308fded8efc85bfbbe7e4630f44342991e0a 100644 --- a/arch/x86/pci/i386.c +++ b/arch/x86/pci/i386.c @@ -301,15 +301,13 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, prot = pgprot_val(vma->vm_page_prot); if (pat_wc_enabled && write_combine) prot |= _PAGE_CACHE_WC; - else if (pat_wc_enabled) + else if (pat_wc_enabled || boot_cpu_data.x86 > 3) /* * ioremap() and ioremap_nocache() defaults to UC MINUS for now. * To avoid attribute conflicts, request UC MINUS here * aswell. */ prot |= _PAGE_CACHE_UC_MINUS; - else if (boot_cpu_data.x86 > 3) - prot |= _PAGE_CACHE_UC; vma->vm_page_prot = __pgprot(prot); diff --git a/arch/x86/pci/k8-bus_64.c b/arch/x86/pci/k8-bus_64.c index ab6d4b18a88fdcc01fc63835ca60f1eded7827e1..5c2799c20e47b7a48b05e1fd15cbdbc79229d86b 100644 --- a/arch/x86/pci/k8-bus_64.c +++ b/arch/x86/pci/k8-bus_64.c @@ -504,14 +504,6 @@ static int __init early_fill_mp_bus_info(void) } } -#ifdef CONFIG_NUMA - for (i = 0; i < BUS_NR; i++) { - node = mp_bus_to_node[i]; - if (node >= 0) - printk(KERN_DEBUG "bus: %02x to node: %02x\n", i, node); - } -#endif - for (i = 0; i < pci_root_num; i++) { int res_num; int busnum; diff --git a/arch/xtensa/kernel/init_task.c b/arch/xtensa/kernel/init_task.c index 021b4f46ff94693bd7d9bfd020ec01c683afab9f..3df469dbe81438c760960cb36a0a4e1d76ff8012 100644 --- a/arch/xtensa/kernel/init_task.c +++ b/arch/xtensa/kernel/init_task.c @@ -22,7 +22,6 @@ #include static struct fs_struct init_fs = INIT_FS; -static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS(init_signals); static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); struct mm_struct init_mm = INIT_MM(init_mm); diff --git a/block/blk-core.c b/block/blk-core.c index b754a4a2f9bd26e2e3aaed11fb6fa3a9c3d67d0b..6a9cc0d22a61c1aa2300d18c9728a7546c15cf0a 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -54,15 +54,16 @@ static DEFINE_PER_CPU(struct list_head, blk_cpu_done); static void drive_stat_acct(struct request *rq, int new_io) { + struct hd_struct *part; int rw = rq_data_dir(rq); if (!blk_fs_request(rq) || !rq->rq_disk) return; - if (!new_io) { - __all_stat_inc(rq->rq_disk, merges[rw], rq->sector); - } else { - struct hd_struct *part = get_part(rq->rq_disk, rq->sector); + part = get_part(rq->rq_disk, rq->sector); + if (!new_io) + __all_stat_inc(rq->rq_disk, part, merges[rw], rq->sector); + else { disk_round_stats(rq->rq_disk); rq->rq_disk->in_flight++; if (part) { @@ -253,9 +254,11 @@ EXPORT_SYMBOL(__generic_unplug_device); **/ void generic_unplug_device(struct request_queue *q) { - spin_lock_irq(q->queue_lock); - __generic_unplug_device(q); - spin_unlock_irq(q->queue_lock); + if (blk_queue_plugged(q)) { + spin_lock_irq(q->queue_lock); + __generic_unplug_device(q); + spin_unlock_irq(q->queue_lock); + } } EXPORT_SYMBOL(generic_unplug_device); @@ -479,6 +482,7 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id) kobject_init(&q->kobj, &blk_queue_ktype); mutex_init(&q->sysfs_lock); + spin_lock_init(&q->__queue_lock); return q; } @@ -541,10 +545,8 @@ blk_init_queue_node(request_fn_proc *rfn, spinlock_t *lock, int node_id) * if caller didn't supply a lock, they get per-queue locking with * our embedded lock */ - if (!lock) { - spin_lock_init(&q->__queue_lock); + if (!lock) lock = &q->__queue_lock; - } q->request_fn = rfn; q->prep_rq_fn = NULL; @@ -1536,10 +1538,11 @@ static int __end_that_request_first(struct request *req, int error, } if (blk_fs_request(req) && req->rq_disk) { + struct hd_struct *part = get_part(req->rq_disk, req->sector); const int rw = rq_data_dir(req); - all_stat_add(req->rq_disk, sectors[rw], - nr_bytes >> 9, req->sector); + all_stat_add(req->rq_disk, part, sectors[rw], + nr_bytes >> 9, req->sector); } total_bytes = bio_nbytes = 0; @@ -1725,8 +1728,8 @@ static void end_that_request_last(struct request *req, int error) const int rw = rq_data_dir(req); struct hd_struct *part = get_part(disk, req->sector); - __all_stat_inc(disk, ios[rw], req->sector); - __all_stat_add(disk, ticks[rw], duration, req->sector); + __all_stat_inc(disk, part, ios[rw], req->sector); + __all_stat_add(disk, part, ticks[rw], duration, req->sector); disk_round_stats(disk); disk->in_flight--; if (part) { diff --git a/block/blk-ioc.c b/block/blk-ioc.c index e34df7c9fc367048de2c9e669a70291922467ba9..012f065ac8e248d4e42485a7ef9a728692bb43a1 100644 --- a/block/blk-ioc.c +++ b/block/blk-ioc.c @@ -41,8 +41,8 @@ int put_io_context(struct io_context *ioc) rcu_read_lock(); if (ioc->aic && ioc->aic->dtor) ioc->aic->dtor(ioc->aic); - rcu_read_unlock(); cfq_dtor(ioc); + rcu_read_unlock(); kmem_cache_free(iocontext_cachep, ioc); return 1; diff --git a/block/blk-merge.c b/block/blk-merge.c index 73b23562af20086f3a8623df6e9f32561ae330b5..651136aae76e45ba821205a830a919a3d6d105c5 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c @@ -149,9 +149,9 @@ static int blk_phys_contig_segment(struct request_queue *q, struct bio *bio, static int blk_hw_contig_segment(struct request_queue *q, struct bio *bio, struct bio *nxt) { - if (unlikely(!bio_flagged(bio, BIO_SEG_VALID))) + if (!bio_flagged(bio, BIO_SEG_VALID)) blk_recount_segments(q, bio); - if (unlikely(!bio_flagged(nxt, BIO_SEG_VALID))) + if (!bio_flagged(nxt, BIO_SEG_VALID)) blk_recount_segments(q, nxt); if (!BIOVEC_VIRT_MERGEABLE(__BVEC_END(bio), __BVEC_START(nxt)) || BIOVEC_VIRT_OVERSIZE(bio->bi_hw_back_size + nxt->bi_hw_front_size)) @@ -312,9 +312,9 @@ int ll_back_merge_fn(struct request_queue *q, struct request *req, q->last_merge = NULL; return 0; } - if (unlikely(!bio_flagged(req->biotail, BIO_SEG_VALID))) + if (!bio_flagged(req->biotail, BIO_SEG_VALID)) blk_recount_segments(q, req->biotail); - if (unlikely(!bio_flagged(bio, BIO_SEG_VALID))) + if (!bio_flagged(bio, BIO_SEG_VALID)) blk_recount_segments(q, bio); len = req->biotail->bi_hw_back_size + bio->bi_hw_front_size; if (BIOVEC_VIRT_MERGEABLE(__BVEC_END(req->biotail), __BVEC_START(bio)) @@ -352,9 +352,9 @@ int ll_front_merge_fn(struct request_queue *q, struct request *req, return 0; } len = bio->bi_hw_back_size + req->bio->bi_hw_front_size; - if (unlikely(!bio_flagged(bio, BIO_SEG_VALID))) + if (!bio_flagged(bio, BIO_SEG_VALID)) blk_recount_segments(q, bio); - if (unlikely(!bio_flagged(req->bio, BIO_SEG_VALID))) + if (!bio_flagged(req->bio, BIO_SEG_VALID)) blk_recount_segments(q, req->bio); if (BIOVEC_VIRT_MERGEABLE(__BVEC_END(bio), __BVEC_START(req->bio)) && !BIOVEC_VIRT_OVERSIZE(len)) { diff --git a/block/blk-settings.c b/block/blk-settings.c index bb93d4c32775abdc2fdba16c3bc208fb20045f47..8dd86418f35d88229fdebc890e28cbfb62705c55 100644 --- a/block/blk-settings.c +++ b/block/blk-settings.c @@ -286,8 +286,14 @@ void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b) t->max_hw_segments = min(t->max_hw_segments, b->max_hw_segments); t->max_segment_size = min(t->max_segment_size, b->max_segment_size); t->hardsect_size = max(t->hardsect_size, b->hardsect_size); - if (!test_bit(QUEUE_FLAG_CLUSTER, &b->queue_flags)) + if (!t->queue_lock) + WARN_ON_ONCE(1); + else if (!test_bit(QUEUE_FLAG_CLUSTER, &b->queue_flags)) { + unsigned long flags; + spin_lock_irqsave(t->queue_lock, flags); queue_flag_clear(QUEUE_FLAG_CLUSTER, t); + spin_unlock_irqrestore(t->queue_lock, flags); + } } EXPORT_SYMBOL(blk_queue_stack_limits); diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c index e85c4013e8a29a5924c4657447a2b6611eb17702..304ec73ab8215f270cbea1a50e870fd8b5b7bf54 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c @@ -146,11 +146,13 @@ static ssize_t queue_nomerges_store(struct request_queue *q, const char *page, unsigned long nm; ssize_t ret = queue_var_store(&nm, page, count); + spin_lock_irq(q->queue_lock); if (nm) - set_bit(QUEUE_FLAG_NOMERGES, &q->queue_flags); + queue_flag_set(QUEUE_FLAG_NOMERGES, q); else - clear_bit(QUEUE_FLAG_NOMERGES, &q->queue_flags); + queue_flag_clear(QUEUE_FLAG_NOMERGES, q); + spin_unlock_irq(q->queue_lock); return ret; } diff --git a/block/blk-tag.c b/block/blk-tag.c index de64e04299771f08eebb391616d63b72c2fca64a..32667beb03eebf4d04b283f0a0cac999d66ad3e7 100644 --- a/block/blk-tag.c +++ b/block/blk-tag.c @@ -70,7 +70,7 @@ void __blk_queue_free_tags(struct request_queue *q) __blk_free_tags(bqt); q->queue_tags = NULL; - queue_flag_clear(QUEUE_FLAG_QUEUED, q); + queue_flag_clear_unlocked(QUEUE_FLAG_QUEUED, q); } /** @@ -98,7 +98,7 @@ EXPORT_SYMBOL(blk_free_tags); **/ void blk_queue_free_tags(struct request_queue *q) { - queue_flag_clear(QUEUE_FLAG_QUEUED, q); + queue_flag_clear_unlocked(QUEUE_FLAG_QUEUED, q); } EXPORT_SYMBOL(blk_queue_free_tags); @@ -171,6 +171,9 @@ EXPORT_SYMBOL(blk_init_tags); * @q: the request queue for the device * @depth: the maximum queue depth supported * @tags: the tag to use + * + * Queue lock must be held here if the function is called to resize an + * existing map. **/ int blk_queue_init_tags(struct request_queue *q, int depth, struct blk_queue_tag *tags) @@ -197,7 +200,7 @@ int blk_queue_init_tags(struct request_queue *q, int depth, * assign it, all done */ q->queue_tags = tags; - queue_flag_set(QUEUE_FLAG_QUEUED, q); + queue_flag_set_unlocked(QUEUE_FLAG_QUEUED, q); INIT_LIST_HEAD(&q->tag_busy_list); return 0; fail: diff --git a/block/blktrace.c b/block/blktrace.c index 568588cd16b22d546771e18fb4e34f9be4811afe..b2cbb4e5d7673c7a49ea557d962022f7ba3594f9 100644 --- a/block/blktrace.c +++ b/block/blktrace.c @@ -476,7 +476,7 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg) switch (cmd) { case BLKTRACESETUP: - strcpy(b, bdevname(bdev, b)); + bdevname(bdev, b); ret = blk_trace_setup(q, b, bdev->bd_dev, arg); break; case BLKTRACESTART: diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index f4e1006c253d3ade81cc9b39ce80da6612b277a6..b399c62936e01a503715273ffef29ac2fafef8a4 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -1142,6 +1142,17 @@ static void cfq_put_queue(struct cfq_queue *cfqq) kmem_cache_free(cfq_pool, cfqq); } +static void +__call_for_each_cic(struct io_context *ioc, + void (*func)(struct io_context *, struct cfq_io_context *)) +{ + struct cfq_io_context *cic; + struct hlist_node *n; + + hlist_for_each_entry_rcu(cic, n, &ioc->cic_list, cic_list) + func(ioc, cic); +} + /* * Call func for each cic attached to this ioc. */ @@ -1149,12 +1160,8 @@ static void call_for_each_cic(struct io_context *ioc, void (*func)(struct io_context *, struct cfq_io_context *)) { - struct cfq_io_context *cic; - struct hlist_node *n; - rcu_read_lock(); - hlist_for_each_entry_rcu(cic, n, &ioc->cic_list, cic_list) - func(ioc, cic); + __call_for_each_cic(ioc, func); rcu_read_unlock(); } @@ -1198,7 +1205,7 @@ static void cfq_free_io_context(struct io_context *ioc) * should be ok to iterate over the known list, we will see all cic's * since no new ones are added. */ - call_for_each_cic(ioc, cic_free_func); + __call_for_each_cic(ioc, cic_free_func); } static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq) @@ -1296,10 +1303,10 @@ static void cfq_init_prio_data(struct cfq_queue *cfqq, struct io_context *ioc) printk(KERN_ERR "cfq: bad prio %x\n", ioprio_class); case IOPRIO_CLASS_NONE: /* - * no prio set, place us in the middle of the BE classes + * no prio set, inherit CPU scheduling settings */ cfqq->ioprio = task_nice_ioprio(tsk); - cfqq->ioprio_class = IOPRIO_CLASS_BE; + cfqq->ioprio_class = task_nice_ioclass(tsk); break; case IOPRIO_CLASS_RT: cfqq->ioprio = task_ioprio(ioc); diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c index c70d0b6f666fff96feb69f97fe9ed30e2990fa19..c23177e4623f1ba73804479460742dd63339556a 100644 --- a/block/compat_ioctl.c +++ b/block/compat_ioctl.c @@ -555,7 +555,7 @@ static int compat_blk_trace_setup(struct block_device *bdev, char __user *arg) if (copy_from_user(&cbuts, arg, sizeof(cbuts))) return -EFAULT; - strcpy(b, bdevname(bdev, b)); + bdevname(bdev, b); buts = (struct blk_user_trace_setup) { .act_mask = cbuts.act_mask, diff --git a/block/genhd.c b/block/genhd.c index fda9c7a63c29e3ecc323fa373365843771860ec4..129ad939f9dd7179cab6da67497133cafee7156f 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -653,7 +653,7 @@ void genhd_media_change_notify(struct gendisk *disk) EXPORT_SYMBOL_GPL(genhd_media_change_notify); #endif /* 0 */ -dev_t blk_lookup_devt(const char *name) +dev_t blk_lookup_devt(const char *name, int part) { struct device *dev; dev_t devt = MKDEV(0, 0); @@ -661,7 +661,11 @@ dev_t blk_lookup_devt(const char *name) mutex_lock(&block_class_lock); list_for_each_entry(dev, &block_class.devices, node) { if (strcmp(dev->bus_id, name) == 0) { - devt = dev->devt; + struct gendisk *disk = dev_to_disk(dev); + + if (part < disk->minors) + devt = MKDEV(MAJOR(dev->devt), + MINOR(dev->devt) + part); break; } } @@ -669,7 +673,6 @@ dev_t blk_lookup_devt(const char *name) return devt; } - EXPORT_SYMBOL(blk_lookup_devt); struct gendisk *alloc_disk(int minors) diff --git a/crypto/hmac.c b/crypto/hmac.c index b60c3c7aa320ba08548c050f4fc05d231321de61..14c6351e639d9484aa093fac191c7919a99127b4 100644 --- a/crypto/hmac.c +++ b/crypto/hmac.c @@ -57,14 +57,35 @@ static int hmac_setkey(struct crypto_hash *parent, if (keylen > bs) { struct hash_desc desc; struct scatterlist tmp; + int tmplen; int err; desc.tfm = tfm; desc.flags = crypto_hash_get_flags(parent); desc.flags &= CRYPTO_TFM_REQ_MAY_SLEEP; - sg_init_one(&tmp, inkey, keylen); - err = crypto_hash_digest(&desc, &tmp, keylen, digest); + err = crypto_hash_init(&desc); + if (err) + return err; + + tmplen = bs * 2 + ds; + sg_init_one(&tmp, ipad, tmplen); + + for (; keylen > tmplen; inkey += tmplen, keylen -= tmplen) { + memcpy(ipad, inkey, tmplen); + err = crypto_hash_update(&desc, &tmp, tmplen); + if (err) + return err; + } + + if (keylen) { + memcpy(ipad, inkey, keylen); + err = crypto_hash_update(&desc, &tmp, keylen); + if (err) + return err; + } + + err = crypto_hash_final(&desc, digest); if (err) return err; diff --git a/drivers/accessibility/Kconfig b/drivers/accessibility/Kconfig index 1264c4b980942447afbade6fe1f0c947e311aea1..ef3b65bfdd0ac57d49a323174fab431b167c69c0 100644 --- a/drivers/accessibility/Kconfig +++ b/drivers/accessibility/Kconfig @@ -1,7 +1,17 @@ menuconfig ACCESSIBILITY bool "Accessibility support" ---help--- - Enable a submenu where accessibility items may be enabled. + Accessibility handles all special kinds of hardware devices or + software adapters which help people with disabilities (e.g. + blindness) to use computers. + + That includes braille devices, speech synthesis, keyboard + remapping, etc. + + Say Y here to get to see options for accessibility. + This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. If unsure, say N. diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 1c11df9a5f32a92e3ff7fda7700450deccf228b4..9bf2986a2788d6bd11e26bdd459bdf9ed376fcb5 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -205,8 +205,8 @@ config SATA_VITESSE If unsure, say N. config SATA_INIC162X - tristate "Initio 162x SATA support (HIGHLY EXPERIMENTAL)" - depends on PCI && EXPERIMENTAL + tristate "Initio 162x SATA support" + depends on PCI help This option enables support for Initio 162x Serial ATA. @@ -697,6 +697,15 @@ config PATA_SCC If unsure, say N. +config PATA_SCH + tristate "Intel SCH PATA support" + depends on PCI + help + This option enables support for Intel SCH PATA on the Intel + SCH (US15W, US15L, UL11L) series host controllers. + + If unsure, say N. + config PATA_BF54X tristate "Blackfin 54x ATAPI support" depends on BF542 || BF548 || BF549 diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index b693d829383a3b7ff9e33bd0d181523f23297379..674965fa326dafa621311ed92dfcc91d80380296 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile @@ -67,6 +67,7 @@ obj-$(CONFIG_PATA_SIS) += pata_sis.o obj-$(CONFIG_PATA_TRIFLEX) += pata_triflex.o obj-$(CONFIG_PATA_IXP4XX_CF) += pata_ixp4xx_cf.o obj-$(CONFIG_PATA_SCC) += pata_scc.o +obj-$(CONFIG_PATA_SCH) += pata_sch.o obj-$(CONFIG_PATA_BF54X) += pata_bf54x.o obj-$(CONFIG_PATA_PLATFORM) += pata_platform.o obj-$(CONFIG_PATA_OF_PLATFORM) += pata_of_platform.o diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 8cace9aa9c0398bafe101115ba511bb5dd29f0fb..97f83fb2ee2eef25af748297cb474c859ba6545e 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -1267,9 +1267,7 @@ static int ahci_check_ready(struct ata_link *link) void __iomem *port_mmio = ahci_port_base(link->ap); u8 status = readl(port_mmio + PORT_TFDATA) & 0xFF; - if (!(status & ATA_BUSY)) - return 1; - return 0; + return ata_check_ready(status); } static int ahci_softreset(struct ata_link *link, unsigned int *class, diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c index 47aeccd52fa951b900bacd63d4af7e71cf370039..75a406f5e6945525d4799bc44de7ccf6e1552feb 100644 --- a/drivers/ata/ata_generic.c +++ b/drivers/ata/ata_generic.c @@ -152,6 +152,12 @@ static int ata_generic_init_one(struct pci_dev *dev, const struct pci_device_id if (dev->vendor == PCI_VENDOR_ID_AL) ata_pci_bmdma_clear_simplex(dev); + if (dev->vendor == PCI_VENDOR_ID_ATI) { + int rc = pcim_enable_device(dev); + if (rc < 0) + return rc; + pcim_pin_device(dev); + } return ata_pci_sff_init_one(dev, ppi, &generic_sht, NULL); } diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index ea2c7649d399b38c70c987703246de96e9e2b00a..a9027b8fbdd53fbb7ea3e2b6257a84924375b9f3 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -1348,6 +1348,8 @@ static void __devinit piix_init_sidpr(struct ata_host *host) { struct pci_dev *pdev = to_pci_dev(host->dev); struct piix_host_priv *hpriv = host->private_data; + struct ata_device *dev0 = &host->ports[0]->link.device[0]; + u32 scontrol; int i; /* check for availability */ @@ -1366,6 +1368,29 @@ static void __devinit piix_init_sidpr(struct ata_host *host) return; hpriv->sidpr = pcim_iomap_table(pdev)[PIIX_SIDPR_BAR]; + + /* SCR access via SIDPR doesn't work on some configurations. + * Give it a test drive by inhibiting power save modes which + * we'll do anyway. + */ + scontrol = piix_sidpr_read(dev0, SCR_CONTROL); + + /* if IPM is already 3, SCR access is probably working. Don't + * un-inhibit power save modes as BIOS might have inhibited + * them for a reason. + */ + if ((scontrol & 0xf00) != 0x300) { + scontrol |= 0x300; + piix_sidpr_write(dev0, SCR_CONTROL, scontrol); + scontrol = piix_sidpr_read(dev0, SCR_CONTROL); + + if ((scontrol & 0xf00) != 0x300) { + dev_printk(KERN_INFO, host->dev, "SCR access via " + "SIDPR is available but doesn't work\n"); + return; + } + } + host->ports[0]->ops = &piix_sidpr_sata_ops; host->ports[1]->ops = &piix_sidpr_sata_ops; } diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 70b77e0899a84848d5da89b736505aaee977f2b2..dbf6ca781f66ff578a57ad6226c4dc921f5efca4 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -118,8 +118,8 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap) ap->pflags |= ATA_PFLAG_INIT_GTM_VALID; } -static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev, - u32 event) +static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device + *dev, u32 event) { char event_string[12]; char *envp[] = { event_string, NULL }; @@ -127,6 +127,9 @@ static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev, struct kobject *kobj = NULL; int wait = 0; unsigned long flags; + acpi_handle handle, tmphandle; + unsigned long sta; + acpi_status status; if (!ap) ap = dev->link->ap; @@ -134,32 +137,57 @@ static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev, spin_lock_irqsave(ap->lock, flags); + if (dev) + handle = dev->acpi_handle; + else + handle = ap->acpi_handle; + + status = acpi_get_handle(handle, "_EJ0", &tmphandle); + if (ACPI_FAILURE(status)) { + /* This device is not ejectable */ + spin_unlock_irqrestore(ap->lock, flags); + return; + } + + status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); + if (ACPI_FAILURE(status)) { + printk ("Unable to determine bay status\n"); + spin_unlock_irqrestore(ap->lock, flags); + return; + } + switch (event) { case ACPI_NOTIFY_BUS_CHECK: case ACPI_NOTIFY_DEVICE_CHECK: ata_ehi_push_desc(ehi, "ACPI event"); - ata_ehi_hotplugged(ehi); - ata_port_freeze(ap); - break; - - case ACPI_NOTIFY_EJECT_REQUEST: - ata_ehi_push_desc(ehi, "ACPI event"); - if (dev) - dev->flags |= ATA_DFLAG_DETACH; - else { - struct ata_link *tlink; - struct ata_device *tdev; - - ata_port_for_each_link(tlink, ap) - ata_link_for_each_dev(tdev, tlink) - tdev->flags |= ATA_DFLAG_DETACH; + if (!sta) { + /* Device has been unplugged */ + if (dev) + dev->flags |= ATA_DFLAG_DETACH; + else { + struct ata_link *tlink; + struct ata_device *tdev; + + ata_port_for_each_link(tlink, ap) { + ata_link_for_each_dev(tdev, tlink) { + tdev->flags |= + ATA_DFLAG_DETACH; + } + } + } + ata_port_schedule_eh(ap); + wait = 1; + } else { + ata_ehi_hotplugged(ehi); + ata_port_freeze(ap); } - - ata_port_schedule_eh(ap); - wait = 1; - break; } + spin_unlock_irqrestore(ap->lock, flags); + + if (wait) + ata_port_wait_eh(ap); + if (dev) { if (dev->sdev) kobj = &dev->sdev->sdev_gendev.kobj; @@ -170,11 +198,6 @@ static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev, sprintf(event_string, "BAY_EVENT=%d", event); kobject_uevent_env(kobj, KOBJ_CHANGE, envp); } - - spin_unlock_irqrestore(ap->lock, flags); - - if (wait) - ata_port_wait_eh(ap); } static void ata_acpi_dev_notify(acpi_handle handle, u32 event, void *data) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 3bc488538204abe225b388346d3b2a65a1c5ed5d..3c89f205c83fd73cb9ef0976ada0115cf4f42cac 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -2126,6 +2126,13 @@ int ata_dev_configure(struct ata_device *dev) dev->horkage |= ata_dev_blacklisted(dev); ata_force_horkage(dev); + if (dev->horkage & ATA_HORKAGE_DISABLE) { + ata_dev_printk(dev, KERN_INFO, + "unsupported device, disabling\n"); + ata_dev_disable(dev); + return 0; + } + /* let ACPI work its magic */ rc = ata_acpi_on_devcfg(dev); if (rc) @@ -3490,22 +3497,11 @@ int sata_link_resume(struct ata_link *link, const unsigned long *params, if ((rc = sata_link_debounce(link, params, deadline))) return rc; - /* Clear SError. PMP and some host PHYs require this to - * operate and clearing should be done before checking PHY - * online status to avoid race condition (hotplugging between - * link resume and status check). - */ + /* clear SError, some PHYs require this even for SRST to work */ if (!(rc = sata_scr_read(link, SCR_ERROR, &serror))) rc = sata_scr_write(link, SCR_ERROR, serror); - if (rc == 0 || rc == -EINVAL) { - unsigned long flags; - spin_lock_irqsave(link->ap->lock, flags); - link->eh_info.serror = 0; - spin_unlock_irqrestore(link->ap->lock, flags); - rc = 0; - } - return rc; + return rc != -EINVAL ? rc : 0; } /** @@ -3653,9 +3649,13 @@ int sata_link_hardreset(struct ata_link *link, const unsigned long *timing, if (check_ready) rc = ata_wait_ready(link, deadline, check_ready); out: - if (rc && rc != -EAGAIN) + if (rc && rc != -EAGAIN) { + /* online is set iff link is online && reset succeeded */ + if (online) + *online = false; ata_link_printk(link, KERN_ERR, "COMRESET failed (errno=%d)\n", rc); + } DPRINTK("EXIT, rc=%d\n", rc); return rc; } @@ -3700,8 +3700,14 @@ int sata_std_hardreset(struct ata_link *link, unsigned int *class, */ void ata_std_postreset(struct ata_link *link, unsigned int *classes) { + u32 serror; + DPRINTK("ENTER\n"); + /* reset complete, clear SError */ + if (!sata_scr_read(link, SCR_ERROR, &serror)) + sata_scr_write(link, SCR_ERROR, serror); + /* print link status */ sata_print_link_status(link); @@ -3894,8 +3900,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { { "SAMSUNG CD-ROM SN-124", "N001", ATA_HORKAGE_NODMA }, { "Seagate STT20000A", NULL, ATA_HORKAGE_NODMA }, /* Odd clown on sil3726/4726 PMPs */ - { "Config Disk", NULL, ATA_HORKAGE_NODMA | - ATA_HORKAGE_SKIP_PM }, + { "Config Disk", NULL, ATA_HORKAGE_DISABLE }, /* Weird ATAPI devices */ { "TORiSAN DVD-ROM DRD-N216", NULL, ATA_HORKAGE_MAX_SEC_128 }, @@ -5616,7 +5621,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht) spin_lock_irqsave(ap->lock, flags); ehi->probe_mask |= ATA_ALL_DEVICES; - ehi->action |= ATA_EH_RESET; + ehi->action |= ATA_EH_RESET | ATA_EH_LPM; ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET; ap->pflags &= ~ATA_PFLAG_INITIALIZING; @@ -5649,7 +5654,6 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht) struct ata_port *ap = host->ports[i]; ata_scsi_scan_host(ap, 1); - ata_lpm_schedule(ap, ap->pm_policy); } return 0; @@ -6292,6 +6296,7 @@ EXPORT_SYMBOL_GPL(ata_eh_freeze_port); EXPORT_SYMBOL_GPL(ata_eh_thaw_port); EXPORT_SYMBOL_GPL(ata_eh_qc_complete); EXPORT_SYMBOL_GPL(ata_eh_qc_retry); +EXPORT_SYMBOL_GPL(ata_eh_analyze_ncq_error); EXPORT_SYMBOL_GPL(ata_do_eh); EXPORT_SYMBOL_GPL(ata_std_error_handler); diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 61dcd0026c64c301c8ce43a0ec89e5eebaf755f8..7894d83ea1eb8d10f57db21f4c71013cd22209f8 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -1308,12 +1308,7 @@ static void ata_eh_analyze_serror(struct ata_link *link) unsigned int err_mask = 0, action = 0; u32 hotplug_mask; - if (serror & SERR_PERSISTENT) { - err_mask |= AC_ERR_ATA_BUS; - action |= ATA_EH_RESET; - } - if (serror & - (SERR_DATA_RECOVERED | SERR_COMM_RECOVERED | SERR_DATA)) { + if (serror & (SERR_PERSISTENT | SERR_DATA)) { err_mask |= AC_ERR_ATA_BUS; action |= ATA_EH_RESET; } @@ -1357,7 +1352,7 @@ static void ata_eh_analyze_serror(struct ata_link *link) * LOCKING: * Kernel thread context (may sleep). */ -static void ata_eh_analyze_ncq_error(struct ata_link *link) +void ata_eh_analyze_ncq_error(struct ata_link *link) { struct ata_port *ap = link->ap; struct ata_eh_context *ehc = &link->eh_context; @@ -2047,19 +2042,11 @@ static int ata_do_reset(struct ata_link *link, ata_reset_fn_t reset, unsigned int *classes, unsigned long deadline) { struct ata_device *dev; - int rc; ata_link_for_each_dev(dev, link) classes[dev->devno] = ATA_DEV_UNKNOWN; - rc = reset(link, classes, deadline); - - /* convert all ATA_DEV_UNKNOWN to ATA_DEV_NONE */ - ata_link_for_each_dev(dev, link) - if (classes[dev->devno] == ATA_DEV_UNKNOWN) - classes[dev->devno] = ATA_DEV_NONE; - - return rc; + return reset(link, classes, deadline); } static int ata_eh_followup_srst_needed(struct ata_link *link, @@ -2096,9 +2083,11 @@ int ata_eh_reset(struct ata_link *link, int classify, ata_reset_fn_t reset; unsigned long flags; u32 sstatus; - int rc; + int nr_known, rc; - /* about to reset */ + /* + * Prepare to reset + */ spin_lock_irqsave(ap->lock, flags); ap->pflags |= ATA_PFLAG_RESETTING; spin_unlock_irqrestore(ap->lock, flags); @@ -2124,16 +2113,8 @@ int ata_eh_reset(struct ata_link *link, int classify, ap->ops->set_piomode(ap, dev); } - if (!softreset && !hardreset) { - if (verbose) - ata_link_printk(link, KERN_INFO, "no reset method " - "available, skipping reset\n"); - if (!(lflags & ATA_LFLAG_ASSUME_CLASS)) - lflags |= ATA_LFLAG_ASSUME_ATA; - goto done; - } - /* prefer hardreset */ + reset = NULL; ehc->i.action &= ~ATA_EH_RESET; if (hardreset) { reset = hardreset; @@ -2141,11 +2122,6 @@ int ata_eh_reset(struct ata_link *link, int classify, } else if (softreset) { reset = softreset; ehc->i.action = ATA_EH_SOFTRESET; - } else { - ata_link_printk(link, KERN_ERR, "BUG: no reset method, " - "please report to linux-ide@vger.kernel.org\n"); - dump_stack(); - return -EINVAL; } if (prereset) { @@ -2165,55 +2141,71 @@ int ata_eh_reset(struct ata_link *link, int classify, "prereset failed (errno=%d)\n", rc); goto out; } - } - /* prereset() might have cleared ATA_EH_RESET */ - if (!(ehc->i.action & ATA_EH_RESET)) { - /* prereset told us not to reset, bang classes and return */ - ata_link_for_each_dev(dev, link) - classes[dev->devno] = ATA_DEV_NONE; - rc = 0; - goto out; + /* prereset() might have cleared ATA_EH_RESET. If so, + * bang classes and return. + */ + if (reset && !(ehc->i.action & ATA_EH_RESET)) { + ata_link_for_each_dev(dev, link) + classes[dev->devno] = ATA_DEV_NONE; + rc = 0; + goto out; + } } retry: + /* + * Perform reset + */ + if (ata_is_host_link(link)) + ata_eh_freeze_port(ap); + deadline = jiffies + ata_eh_reset_timeouts[try++]; - /* shut up during boot probing */ - if (verbose) - ata_link_printk(link, KERN_INFO, "%s resetting link\n", - reset == softreset ? "soft" : "hard"); + if (reset) { + if (verbose) + ata_link_printk(link, KERN_INFO, "%s resetting link\n", + reset == softreset ? "soft" : "hard"); - /* mark that this EH session started with reset */ - if (reset == hardreset) - ehc->i.flags |= ATA_EHI_DID_HARDRESET; - else - ehc->i.flags |= ATA_EHI_DID_SOFTRESET; + /* mark that this EH session started with reset */ + if (reset == hardreset) + ehc->i.flags |= ATA_EHI_DID_HARDRESET; + else + ehc->i.flags |= ATA_EHI_DID_SOFTRESET; - rc = ata_do_reset(link, reset, classes, deadline); + rc = ata_do_reset(link, reset, classes, deadline); - if (reset == hardreset && - ata_eh_followup_srst_needed(link, rc, classify, classes)) { - /* okay, let's do follow-up softreset */ - reset = softreset; + if (reset == hardreset && + ata_eh_followup_srst_needed(link, rc, classify, classes)) { + /* okay, let's do follow-up softreset */ + reset = softreset; - if (!reset) { - ata_link_printk(link, KERN_ERR, - "follow-up softreset required " - "but no softreset avaliable\n"); - rc = -EINVAL; - goto fail; + if (!reset) { + ata_link_printk(link, KERN_ERR, + "follow-up softreset required " + "but no softreset avaliable\n"); + rc = -EINVAL; + goto fail; + } + + ata_eh_about_to_do(link, NULL, ATA_EH_RESET); + rc = ata_do_reset(link, reset, classes, deadline); } - ata_eh_about_to_do(link, NULL, ATA_EH_RESET); - rc = ata_do_reset(link, reset, classes, deadline); + /* -EAGAIN can happen if we skipped followup SRST */ + if (rc && rc != -EAGAIN) + goto fail; + } else { + if (verbose) + ata_link_printk(link, KERN_INFO, "no reset method " + "available, skipping reset\n"); + if (!(lflags & ATA_LFLAG_ASSUME_CLASS)) + lflags |= ATA_LFLAG_ASSUME_ATA; } - /* -EAGAIN can happen if we skipped followup SRST */ - if (rc && rc != -EAGAIN) - goto fail; - - done: + /* + * Post-reset processing + */ ata_link_for_each_dev(dev, link) { /* After the reset, the device state is PIO 0 and the * controller state is undefined. Reset also wakes up @@ -2236,9 +2228,53 @@ int ata_eh_reset(struct ata_link *link, int classify, if (sata_scr_read(link, SCR_STATUS, &sstatus) == 0) link->sata_spd = (sstatus >> 4) & 0xf; + /* thaw the port */ + if (ata_is_host_link(link)) + ata_eh_thaw_port(ap); + + /* postreset() should clear hardware SError. Although SError + * is cleared during link resume, clearing SError here is + * necessary as some PHYs raise hotplug events after SRST. + * This introduces race condition where hotplug occurs between + * reset and here. This race is mediated by cross checking + * link onlineness and classification result later. + */ if (postreset) postreset(link, classes); + /* clear cached SError */ + spin_lock_irqsave(link->ap->lock, flags); + link->eh_info.serror = 0; + spin_unlock_irqrestore(link->ap->lock, flags); + + /* Make sure onlineness and classification result correspond. + * Hotplug could have happened during reset and some + * controllers fail to wait while a drive is spinning up after + * being hotplugged causing misdetection. By cross checking + * link onlineness and classification result, those conditions + * can be reliably detected and retried. + */ + nr_known = 0; + ata_link_for_each_dev(dev, link) { + /* convert all ATA_DEV_UNKNOWN to ATA_DEV_NONE */ + if (classes[dev->devno] == ATA_DEV_UNKNOWN) + classes[dev->devno] = ATA_DEV_NONE; + else + nr_known++; + } + + if (classify && !nr_known && ata_link_online(link)) { + if (try < max_tries) { + ata_link_printk(link, KERN_WARNING, "link online but " + "device misclassified, retrying\n"); + rc = -EAGAIN; + goto fail; + } + ata_link_printk(link, KERN_WARNING, + "link online but device misclassified, " + "device detection might fail\n"); + } + /* reset successful, schedule revalidation */ ata_eh_done(link, NULL, ATA_EH_RESET); ehc->i.action |= ATA_EH_REVALIDATE; @@ -2587,7 +2623,7 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, struct ata_link *link; struct ata_device *dev; int nr_failed_devs, nr_disabled_devs; - int reset, rc; + int rc; unsigned long flags; DPRINTK("ENTER\n"); @@ -2630,7 +2666,6 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, rc = 0; nr_failed_devs = 0; nr_disabled_devs = 0; - reset = 0; /* if UNLOADING, finish immediately */ if (ap->pflags & ATA_PFLAG_UNLOADING) @@ -2644,40 +2679,24 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, if (ata_eh_skip_recovery(link)) ehc->i.action = 0; - /* do we need to reset? */ - if (ehc->i.action & ATA_EH_RESET) - reset = 1; - ata_link_for_each_dev(dev, link) ehc->classes[dev->devno] = ATA_DEV_UNKNOWN; } /* reset */ - if (reset) { - /* if PMP is attached, this function only deals with - * downstream links, port should stay thawed. - */ - if (!sata_pmp_attached(ap)) - ata_eh_freeze_port(ap); - - ata_port_for_each_link(link, ap) { - struct ata_eh_context *ehc = &link->eh_context; + ata_port_for_each_link(link, ap) { + struct ata_eh_context *ehc = &link->eh_context; - if (!(ehc->i.action & ATA_EH_RESET)) - continue; + if (!(ehc->i.action & ATA_EH_RESET)) + continue; - rc = ata_eh_reset(link, ata_link_nr_vacant(link), - prereset, softreset, hardreset, - postreset); - if (rc) { - ata_link_printk(link, KERN_ERR, - "reset failed, giving up\n"); - goto out; - } + rc = ata_eh_reset(link, ata_link_nr_vacant(link), + prereset, softreset, hardreset, postreset); + if (rc) { + ata_link_printk(link, KERN_ERR, + "reset failed, giving up\n"); + goto out; } - - if (!sata_pmp_attached(ap)) - ata_eh_thaw_port(ap); } /* the rest */ diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c index ff1822a7da38941b4c4cc2051f2bdd4ec80e37a2..0f9386d4a5a06e080bc32cf921744e38d9207f4d 100644 --- a/drivers/ata/libata-pmp.c +++ b/drivers/ata/libata-pmp.c @@ -48,7 +48,7 @@ static unsigned int sata_pmp_read(struct ata_link *link, int reg, u32 *r_val) tf.device = link->pmp; err_mask = ata_exec_internal(pmp_dev, &tf, NULL, DMA_NONE, NULL, 0, - SATA_PMP_SCR_TIMEOUT); + SATA_PMP_RW_TIMEOUT); if (err_mask) return err_mask; @@ -88,7 +88,7 @@ static unsigned int sata_pmp_write(struct ata_link *link, int reg, u32 val) tf.lbah = (val >> 24) & 0xff; return ata_exec_internal(pmp_dev, &tf, NULL, DMA_NONE, NULL, 0, - SATA_PMP_SCR_TIMEOUT); + SATA_PMP_RW_TIMEOUT); } /** @@ -257,19 +257,6 @@ static int sata_pmp_configure(struct ata_device *dev, int print_info) goto fail; } - /* turn off notification till fan-out ports are reset and configured */ - if (gscr[SATA_PMP_GSCR_FEAT_EN] & SATA_PMP_FEAT_NOTIFY) { - gscr[SATA_PMP_GSCR_FEAT_EN] &= ~SATA_PMP_FEAT_NOTIFY; - - err_mask = sata_pmp_write(dev->link, SATA_PMP_GSCR_FEAT_EN, - gscr[SATA_PMP_GSCR_FEAT_EN]); - if (err_mask) { - rc = -EIO; - reason = "failed to write GSCR_FEAT_EN"; - goto fail; - } - } - if (print_info) { ata_dev_printk(dev, KERN_INFO, "Port Multiplier %s, " "0x%04x:0x%04x r%d, %d ports, feat 0x%x/0x%x\n", @@ -700,8 +687,6 @@ static int sata_pmp_eh_recover_pmp(struct ata_port *ap, if (ehc->i.action & ATA_EH_RESET) { struct ata_link *tlink; - ata_eh_freeze_port(ap); - /* reset */ rc = ata_eh_reset(link, 0, prereset, softreset, hardreset, postreset); @@ -711,8 +696,6 @@ static int sata_pmp_eh_recover_pmp(struct ata_port *ap, goto fail; } - ata_eh_thaw_port(ap); - /* PMP is reset, SErrors cannot be trusted, scan all */ ata_port_for_each_link(tlink, ap) { struct ata_eh_context *ehc = &tlink->eh_context; @@ -864,6 +847,7 @@ static int sata_pmp_eh_recover(struct ata_port *ap) struct ata_link *pmp_link = &ap->link; struct ata_device *pmp_dev = pmp_link->device; struct ata_eh_context *pmp_ehc = &pmp_link->eh_context; + u32 *gscr = pmp_dev->gscr; struct ata_link *link; struct ata_device *dev; unsigned int err_mask; @@ -901,6 +885,22 @@ static int sata_pmp_eh_recover(struct ata_port *ap) if (rc) goto pmp_fail; + /* PHY event notification can disturb reset and other recovery + * operations. Turn it off. + */ + if (gscr[SATA_PMP_GSCR_FEAT_EN] & SATA_PMP_FEAT_NOTIFY) { + gscr[SATA_PMP_GSCR_FEAT_EN] &= ~SATA_PMP_FEAT_NOTIFY; + + err_mask = sata_pmp_write(pmp_link, SATA_PMP_GSCR_FEAT_EN, + gscr[SATA_PMP_GSCR_FEAT_EN]); + if (err_mask) { + ata_link_printk(pmp_link, KERN_WARNING, + "failed to disable NOTIFY (err_mask=0x%x)\n", + err_mask); + goto pmp_fail; + } + } + /* handle disabled links */ rc = sata_pmp_eh_handle_disabled_links(ap); if (rc) @@ -923,10 +923,10 @@ static int sata_pmp_eh_recover(struct ata_port *ap) /* enable notification */ if (pmp_dev->flags & ATA_DFLAG_AN) { - pmp_dev->gscr[SATA_PMP_GSCR_FEAT_EN] |= SATA_PMP_FEAT_NOTIFY; + gscr[SATA_PMP_GSCR_FEAT_EN] |= SATA_PMP_FEAT_NOTIFY; - err_mask = sata_pmp_write(pmp_dev->link, SATA_PMP_GSCR_FEAT_EN, - pmp_dev->gscr[SATA_PMP_GSCR_FEAT_EN]); + err_mask = sata_pmp_write(pmp_link, SATA_PMP_GSCR_FEAT_EN, + gscr[SATA_PMP_GSCR_FEAT_EN]); if (err_mask) { ata_dev_printk(pmp_dev, KERN_ERR, "failed to write " "PMP_FEAT_EN (Emask=0x%x)\n", err_mask); diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 3ce43920e459b037d685239ec1315ed11097df6a..aeb6e01d82ce3ae839d094a2c1a48f90b4c6a388 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1082,12 +1082,6 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc) if (((cdb[4] >> 4) & 0xf) != 0) goto invalid_fld; /* power conditions not supported */ - if (qc->dev->horkage & ATA_HORKAGE_SKIP_PM) { - /* the device lacks PM support, finish without doing anything */ - scmd->result = SAM_STAT_GOOD; - return 1; - } - if (cdb[4] & 0x1) { tf->nsect = 1; /* 1 sector, lba=0 */ diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 2ec65a8fda79ecc46986ed0da6de7d886c71ccf5..3c2d2289f85ee3233c259a4508fdb134e969053d 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -314,11 +314,7 @@ static int ata_sff_check_ready(struct ata_link *link) { u8 status = link->ap->ops->sff_check_status(link->ap); - if (!(status & ATA_BUSY)) - return 1; - if (status == 0xff) - return -ENODEV; - return 0; + return ata_check_ready(status); } /** diff --git a/drivers/ata/pata_acpi.c b/drivers/ata/pata_acpi.c index c5f91e629945040130f53a28bd6bc7b920f87b36..fbe605711554a24dd1ae23be66d02128c8193b18 100644 --- a/drivers/ata/pata_acpi.c +++ b/drivers/ata/pata_acpi.c @@ -259,6 +259,12 @@ static int pacpi_init_one (struct pci_dev *pdev, const struct pci_device_id *id) .port_ops = &pacpi_ops, }; const struct ata_port_info *ppi[] = { &info, NULL }; + if (pdev->vendor == PCI_VENDOR_ID_ATI) { + int rc = pcim_enable_device(pdev); + if (rc < 0) + return rc; + pcim_pin_device(pdev); + } return ata_pci_sff_init_one(pdev, ppi, &pacpi_sht, NULL); } diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c index fcabe46f262bc9049505c5f124e1e343589ed2e9..0f3e659db99a029a4392f843a2cca441bcac553c 100644 --- a/drivers/ata/pata_ali.c +++ b/drivers/ata/pata_ali.c @@ -177,11 +177,11 @@ static void ali_program_modes(struct ata_port *ap, struct ata_device *adev, stru u8 udma; if (t != NULL) { - t->setup = FIT(t->setup, 1, 8) & 7; - t->act8b = FIT(t->act8b, 1, 8) & 7; - t->rec8b = FIT(t->rec8b, 1, 16) & 15; - t->active = FIT(t->active, 1, 8) & 7; - t->recover = FIT(t->recover, 1, 16) & 15; + t->setup = clamp_val(t->setup, 1, 8) & 7; + t->act8b = clamp_val(t->act8b, 1, 8) & 7; + t->rec8b = clamp_val(t->rec8b, 1, 16) & 15; + t->active = clamp_val(t->active, 1, 8) & 7; + t->recover = clamp_val(t->recover, 1, 16) & 15; pci_write_config_byte(pdev, cas, t->setup); pci_write_config_byte(pdev, cbt, (t->act8b << 4) | t->rec8b); diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c index 26665c396485898b6785140ba38e8f913760439a..57dd00f463d3367a33f24cf5f1808cc1c1f294ec 100644 --- a/drivers/ata/pata_amd.c +++ b/drivers/ata/pata_amd.c @@ -84,32 +84,32 @@ static void timing_setup(struct ata_port *ap, struct ata_device *adev, int offse /* Configure the address set up timing */ pci_read_config_byte(pdev, offset + 0x0C, &t); - t = (t & ~(3 << ((3 - dn) << 1))) | ((FIT(at.setup, 1, 4) - 1) << ((3 - dn) << 1)); + t = (t & ~(3 << ((3 - dn) << 1))) | ((clamp_val(at.setup, 1, 4) - 1) << ((3 - dn) << 1)); pci_write_config_byte(pdev, offset + 0x0C , t); /* Configure the 8bit I/O timing */ pci_write_config_byte(pdev, offset + 0x0E + (1 - (dn >> 1)), - ((FIT(at.act8b, 1, 16) - 1) << 4) | (FIT(at.rec8b, 1, 16) - 1)); + ((clamp_val(at.act8b, 1, 16) - 1) << 4) | (clamp_val(at.rec8b, 1, 16) - 1)); /* Drive timing */ pci_write_config_byte(pdev, offset + 0x08 + (3 - dn), - ((FIT(at.active, 1, 16) - 1) << 4) | (FIT(at.recover, 1, 16) - 1)); + ((clamp_val(at.active, 1, 16) - 1) << 4) | (clamp_val(at.recover, 1, 16) - 1)); switch (clock) { case 1: - t = at.udma ? (0xc0 | (FIT(at.udma, 2, 5) - 2)) : 0x03; + t = at.udma ? (0xc0 | (clamp_val(at.udma, 2, 5) - 2)) : 0x03; break; case 2: - t = at.udma ? (0xc0 | amd_cyc2udma[FIT(at.udma, 2, 10)]) : 0x03; + t = at.udma ? (0xc0 | amd_cyc2udma[clamp_val(at.udma, 2, 10)]) : 0x03; break; case 3: - t = at.udma ? (0xc0 | amd_cyc2udma[FIT(at.udma, 1, 10)]) : 0x03; + t = at.udma ? (0xc0 | amd_cyc2udma[clamp_val(at.udma, 1, 10)]) : 0x03; break; case 4: - t = at.udma ? (0xc0 | amd_cyc2udma[FIT(at.udma, 1, 15)]) : 0x03; + t = at.udma ? (0xc0 | amd_cyc2udma[clamp_val(at.udma, 1, 15)]) : 0x03; break; default: diff --git a/drivers/ata/pata_at32.c b/drivers/ata/pata_at32.c index 5e104385d6a374336d529dad852087e19df78770..82fb6e2731690f11194fd286810c807b14795c3b 100644 --- a/drivers/ata/pata_at32.c +++ b/drivers/ata/pata_at32.c @@ -291,8 +291,6 @@ static int __init pata_at32_probe(struct platform_device *pdev) if (!info) return -ENOMEM; - memset(info, 0, sizeof(struct at32_ide_info)); - info->irq = irq; info->cs = board->cs; diff --git a/drivers/ata/pata_bf54x.c b/drivers/ata/pata_bf54x.c index 9ab89732cf9474f1fa34458717bb9bd7da755d88..55516103626a7e7616c545ed64b3a0b54a750b1c 100644 --- a/drivers/ata/pata_bf54x.c +++ b/drivers/ata/pata_bf54x.c @@ -911,7 +911,10 @@ static void bfin_bmdma_start(struct ata_queued_cmd *qc) /* Reset all transfer count */ ATAPI_SET_CONTROL(base, ATAPI_GET_CONTROL(base) | TFRCNT_RST); - /* Set transfer length to buffer len */ + /* Set ATAPI state machine contorl in terminate sequence */ + ATAPI_SET_CONTROL(base, ATAPI_GET_CONTROL(base) | END_ON_TERM); + + /* Set transfer length to buffer len */ for_each_sg(qc->sg, sg, qc->n_elem, si) { ATAPI_SET_XFER_LEN(base, (sg_dma_len(sg) >> 1)); } diff --git a/drivers/ata/pata_cypress.c b/drivers/ata/pata_cypress.c index a9c3218e22fd9a1b069d5065a48c337fd77f8508..2ff62608ae37e82069a94dfca757fb0accd09fec 100644 --- a/drivers/ata/pata_cypress.c +++ b/drivers/ata/pata_cypress.c @@ -62,14 +62,14 @@ static void cy82c693_set_piomode(struct ata_port *ap, struct ata_device *adev) return; } - time_16 = FIT(t.recover, 0, 15) | (FIT(t.active, 0, 15) << 4); - time_8 = FIT(t.act8b, 0, 15) | (FIT(t.rec8b, 0, 15) << 4); + time_16 = clamp_val(t.recover, 0, 15) | (clamp_val(t.active, 0, 15) << 4); + time_8 = clamp_val(t.act8b, 0, 15) | (clamp_val(t.rec8b, 0, 15) << 4); if (adev->devno == 0) { pci_read_config_dword(pdev, CY82_IDE_ADDRSETUP, &addr); addr &= ~0x0F; /* Mask bits */ - addr |= FIT(t.setup, 0, 15); + addr |= clamp_val(t.setup, 0, 15); pci_write_config_dword(pdev, CY82_IDE_ADDRSETUP, addr); pci_write_config_byte(pdev, CY82_IDE_MASTER_IOR, time_16); @@ -79,7 +79,7 @@ static void cy82c693_set_piomode(struct ata_port *ap, struct ata_device *adev) pci_read_config_dword(pdev, CY82_IDE_ADDRSETUP, &addr); addr &= ~0xF0; /* Mask bits */ - addr |= (FIT(t.setup, 0, 15) << 4); + addr |= (clamp_val(t.setup, 0, 15) << 4); pci_write_config_dword(pdev, CY82_IDE_ADDRSETUP, addr); pci_write_config_byte(pdev, CY82_IDE_SLAVE_IOR, time_16); diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c index 7af4b29cc4220af1aecef92e1bfd9b0c9d079cc9..fe7cc8ed4ea4261c2c08ebd6b2454e983e4f5b0c 100644 --- a/drivers/ata/pata_legacy.c +++ b/drivers/ata/pata_legacy.c @@ -343,8 +343,8 @@ static void ht6560a_set_piomode(struct ata_port *ap, struct ata_device *adev) /* Get the timing data in cycles. For now play safe at 50Mhz */ ata_timing_compute(adev, adev->pio_mode, &t, 20000, 1000); - active = FIT(t.active, 2, 15); - recover = FIT(t.recover, 4, 15); + active = clamp_val(t.active, 2, 15); + recover = clamp_val(t.recover, 4, 15); inb(0x3E6); inb(0x3E6); @@ -377,8 +377,8 @@ static void ht6560b_set_piomode(struct ata_port *ap, struct ata_device *adev) /* Get the timing data in cycles. For now play safe at 50Mhz */ ata_timing_compute(adev, adev->pio_mode, &t, 20000, 1000); - active = FIT(t.active, 2, 15); - recover = FIT(t.recover, 2, 16); + active = clamp_val(t.active, 2, 15); + recover = clamp_val(t.recover, 2, 16); recover &= 0x15; inb(0x3E6); @@ -462,9 +462,9 @@ static void opti82c611a_set_piomode(struct ata_port *ap, ata_timing_merge(&t, &tp, &t, ATA_TIMING_SETUP); } - active = FIT(t.active, 2, 17) - 2; - recover = FIT(t.recover, 1, 16) - 1; - setup = FIT(t.setup, 1, 4) - 1; + active = clamp_val(t.active, 2, 17) - 2; + recover = clamp_val(t.recover, 1, 16) - 1; + setup = clamp_val(t.setup, 1, 4) - 1; /* Select the right timing bank for write timing */ rc = ioread8(ap->ioaddr.lbal_addr); @@ -541,9 +541,9 @@ static void opti82c46x_set_piomode(struct ata_port *ap, struct ata_device *adev) ata_timing_merge(&t, &tp, &t, ATA_TIMING_SETUP); } - active = FIT(t.active, 2, 17) - 2; - recover = FIT(t.recover, 1, 16) - 1; - setup = FIT(t.setup, 1, 4) - 1; + active = clamp_val(t.active, 2, 17) - 2; + recover = clamp_val(t.recover, 1, 16) - 1; + setup = clamp_val(t.setup, 1, 4) - 1; /* Select the right timing bank for write timing */ rc = ioread8(ap->ioaddr.lbal_addr); @@ -624,11 +624,11 @@ static void qdi6500_set_piomode(struct ata_port *ap, struct ata_device *adev) ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); if (ld_qdi->fast) { - active = 8 - FIT(t.active, 1, 8); - recovery = 18 - FIT(t.recover, 3, 18); + active = 8 - clamp_val(t.active, 1, 8); + recovery = 18 - clamp_val(t.recover, 3, 18); } else { - active = 9 - FIT(t.active, 2, 9); - recovery = 15 - FIT(t.recover, 0, 15); + active = 9 - clamp_val(t.active, 2, 9); + recovery = 15 - clamp_val(t.recover, 0, 15); } timing = (recovery << 4) | active | 0x08; @@ -658,11 +658,11 @@ static void qdi6580dp_set_piomode(struct ata_port *ap, struct ata_device *adev) ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); if (ld_qdi->fast) { - active = 8 - FIT(t.active, 1, 8); - recovery = 18 - FIT(t.recover, 3, 18); + active = 8 - clamp_val(t.active, 1, 8); + recovery = 18 - clamp_val(t.recover, 3, 18); } else { - active = 9 - FIT(t.active, 2, 9); - recovery = 15 - FIT(t.recover, 0, 15); + active = 9 - clamp_val(t.active, 2, 9); + recovery = 15 - clamp_val(t.recover, 0, 15); } timing = (recovery << 4) | active | 0x08; @@ -695,11 +695,11 @@ static void qdi6580_set_piomode(struct ata_port *ap, struct ata_device *adev) ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); if (ld_qdi->fast) { - active = 8 - FIT(t.active, 1, 8); - recovery = 18 - FIT(t.recover, 3, 18); + active = 8 - clamp_val(t.active, 1, 8); + recovery = 18 - clamp_val(t.recover, 3, 18); } else { - active = 9 - FIT(t.active, 2, 9); - recovery = 15 - FIT(t.recover, 0, 15); + active = 9 - clamp_val(t.active, 2, 9); + recovery = 15 - clamp_val(t.recover, 0, 15); } timing = (recovery << 4) | active | 0x08; ld_qdi->clock[adev->devno] = timing; @@ -830,8 +830,8 @@ static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev) else ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); - active = (FIT(t.active, 3, 17) - 1) & 0x0F; - recovery = (FIT(t.recover, 1, 15) + 1) & 0x0F; + active = (clamp_val(t.active, 3, 17) - 1) & 0x0F; + recovery = (clamp_val(t.recover, 1, 15) + 1) & 0x0F; timing = (active << 4) | recovery; winbond_writecfg(ld_winbond->timing, timing, reg); @@ -842,7 +842,7 @@ static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev) reg |= 0x08; /* FIFO off */ if (!ata_pio_need_iordy(adev)) reg |= 0x02; /* IORDY off */ - reg |= (FIT(t.setup, 0, 3) << 6); + reg |= (clamp_val(t.setup, 0, 3) << 6); winbond_writecfg(ld_winbond->timing, timing + 1, reg); } diff --git a/drivers/ata/pata_ns87410.c b/drivers/ata/pata_ns87410.c index 76d2455bc453de3d446a13c329e115411bbd56c4..be756b7ef07e9a27d795e4b55731a1621940cd04 100644 --- a/drivers/ata/pata_ns87410.c +++ b/drivers/ata/pata_ns87410.c @@ -91,9 +91,9 @@ static void ns87410_set_piomode(struct ata_port *ap, struct ata_device *adev) return; } - at.active = FIT(at.active, 2, 16) - 2; - at.setup = FIT(at.setup, 1, 4) - 1; - at.recover = FIT(at.recover, 1, 12) - 1; + at.active = clamp_val(at.active, 2, 16) - 2; + at.setup = clamp_val(at.setup, 1, 4) - 1; + at.recover = clamp_val(at.recover, 1, 12) - 1; idetcr = (at.setup << 6) | (recoverbits[at.recover] << 3) | activebits[at.active]; diff --git a/drivers/ata/pata_ns87415.c b/drivers/ata/pata_ns87415.c index ae92b0049bd55bb6b571e5569987498bc14bb87f..e0aa7eaaee0a4bf86b9174c8ee05b16e8bbff9fa 100644 --- a/drivers/ata/pata_ns87415.c +++ b/drivers/ata/pata_ns87415.c @@ -66,8 +66,8 @@ static void ns87415_set_mode(struct ata_port *ap, struct ata_device *adev, u8 mo ata_timing_compute(adev, adev->pio_mode, &t, T, 0); - clocking = 17 - FIT(t.active, 2, 17); - clocking |= (16 - FIT(t.recover, 1, 16)) << 4; + clocking = 17 - clamp_val(t.active, 2, 17); + clocking |= (16 - clamp_val(t.recover, 1, 16)) << 4; /* Use the same timing for read and write bytes */ clocking |= (clocking << 8); pci_write_config_word(dev, timing, clocking); diff --git a/drivers/ata/pata_qdi.c b/drivers/ata/pata_qdi.c index bf45cf0177539392ee8bef61e45c3b20b70a394a..97e5b090d7c2cdc5233791d3ea5eb07280bef8fc 100644 --- a/drivers/ata/pata_qdi.c +++ b/drivers/ata/pata_qdi.c @@ -60,11 +60,11 @@ static void qdi6500_set_piomode(struct ata_port *ap, struct ata_device *adev) ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); if (qdi->fast) { - active = 8 - FIT(t.active, 1, 8); - recovery = 18 - FIT(t.recover, 3, 18); + active = 8 - clamp_val(t.active, 1, 8); + recovery = 18 - clamp_val(t.recover, 3, 18); } else { - active = 9 - FIT(t.active, 2, 9); - recovery = 15 - FIT(t.recover, 0, 15); + active = 9 - clamp_val(t.active, 2, 9); + recovery = 15 - clamp_val(t.recover, 0, 15); } timing = (recovery << 4) | active | 0x08; @@ -84,11 +84,11 @@ static void qdi6580_set_piomode(struct ata_port *ap, struct ata_device *adev) ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); if (qdi->fast) { - active = 8 - FIT(t.active, 1, 8); - recovery = 18 - FIT(t.recover, 3, 18); + active = 8 - clamp_val(t.active, 1, 8); + recovery = 18 - clamp_val(t.recover, 3, 18); } else { - active = 9 - FIT(t.active, 2, 9); - recovery = 15 - FIT(t.recover, 0, 15); + active = 9 - clamp_val(t.active, 2, 9); + recovery = 15 - clamp_val(t.recover, 0, 15); } timing = (recovery << 4) | active | 0x08; diff --git a/drivers/ata/pata_sch.c b/drivers/ata/pata_sch.c new file mode 100644 index 0000000000000000000000000000000000000000..c8cc027789fec7bacc7bbcdb6f0f5baa2ebf45a5 --- /dev/null +++ b/drivers/ata/pata_sch.c @@ -0,0 +1,206 @@ +/* + * pata_sch.c - Intel SCH PATA controllers + * + * Copyright (c) 2008 Alek Du + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License 2 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +/* + * Supports: + * Intel SCH (AF82US15W, AF82US15L, AF82UL11L) chipsets -- see spec at: + * http://download.intel.com/design/chipsets/embedded/datashts/319537.pdf + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRV_NAME "pata_sch" +#define DRV_VERSION "0.2" + +/* see SCH datasheet page 351 */ +enum { + D0TIM = 0x80, /* Device 0 Timing Register */ + D1TIM = 0x84, /* Device 1 Timing Register */ + PM = 0x07, /* PIO Mode Bit Mask */ + MDM = (0x03 << 8), /* Multi-word DMA Mode Bit Mask */ + UDM = (0x07 << 16), /* Ultra DMA Mode Bit Mask */ + PPE = (1 << 30), /* Prefetch/Post Enable */ + USD = (1 << 31), /* Use Synchronous DMA */ +}; + +static int sch_init_one(struct pci_dev *pdev, + const struct pci_device_id *ent); +static void sch_set_piomode(struct ata_port *ap, struct ata_device *adev); +static void sch_set_dmamode(struct ata_port *ap, struct ata_device *adev); + +static const struct pci_device_id sch_pci_tbl[] = { + /* Intel SCH PATA Controller */ + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_SCH_IDE), 0 }, + { } /* terminate list */ +}; + +static struct pci_driver sch_pci_driver = { + .name = DRV_NAME, + .id_table = sch_pci_tbl, + .probe = sch_init_one, + .remove = ata_pci_remove_one, +#ifdef CONFIG_PM + .suspend = ata_pci_device_suspend, + .resume = ata_pci_device_resume, +#endif +}; + +static struct scsi_host_template sch_sht = { + ATA_BMDMA_SHT(DRV_NAME), +}; + +static struct ata_port_operations sch_pata_ops = { + .inherits = &ata_bmdma_port_ops, + .cable_detect = ata_cable_unknown, + .set_piomode = sch_set_piomode, + .set_dmamode = sch_set_dmamode, +}; + +static struct ata_port_info sch_port_info = { + .flags = 0, + .pio_mask = ATA_PIO4, /* pio0-4 */ + .mwdma_mask = ATA_MWDMA2, /* mwdma0-2 */ + .udma_mask = ATA_UDMA5, /* udma0-5 */ + .port_ops = &sch_pata_ops, +}; + +MODULE_AUTHOR("Alek Du "); +MODULE_DESCRIPTION("SCSI low-level driver for Intel SCH PATA controllers"); +MODULE_LICENSE("GPL"); +MODULE_DEVICE_TABLE(pci, sch_pci_tbl); +MODULE_VERSION(DRV_VERSION); + +/** + * sch_set_piomode - Initialize host controller PATA PIO timings + * @ap: Port whose timings we are configuring + * @adev: ATA device + * + * Set PIO mode for device, in host controller PCI config space. + * + * LOCKING: + * None (inherited from caller). + */ + +static void sch_set_piomode(struct ata_port *ap, struct ata_device *adev) +{ + unsigned int pio = adev->pio_mode - XFER_PIO_0; + struct pci_dev *dev = to_pci_dev(ap->host->dev); + unsigned int port = adev->devno ? D1TIM : D0TIM; + unsigned int data; + + pci_read_config_dword(dev, port, &data); + /* see SCH datasheet page 351 */ + /* set PIO mode */ + data &= ~(PM | PPE); + data |= pio; + /* enable PPE for block device */ + if (adev->class == ATA_DEV_ATA) + data |= PPE; + pci_write_config_dword(dev, port, data); +} + +/** + * sch_set_dmamode - Initialize host controller PATA DMA timings + * @ap: Port whose timings we are configuring + * @adev: ATA device + * + * Set MW/UDMA mode for device, in host controller PCI config space. + * + * LOCKING: + * None (inherited from caller). + */ + +static void sch_set_dmamode(struct ata_port *ap, struct ata_device *adev) +{ + unsigned int dma_mode = adev->dma_mode; + struct pci_dev *dev = to_pci_dev(ap->host->dev); + unsigned int port = adev->devno ? D1TIM : D0TIM; + unsigned int data; + + pci_read_config_dword(dev, port, &data); + /* see SCH datasheet page 351 */ + if (dma_mode >= XFER_UDMA_0) { + /* enable Synchronous DMA mode */ + data |= USD; + data &= ~UDM; + data |= (dma_mode - XFER_UDMA_0) << 16; + } else { /* must be MWDMA mode, since we masked SWDMA already */ + data &= ~(USD | MDM); + data |= (dma_mode - XFER_MW_DMA_0) << 8; + } + pci_write_config_dword(dev, port, data); +} + +/** + * sch_init_one - Register SCH ATA PCI device with kernel services + * @pdev: PCI device to register + * @ent: Entry in sch_pci_tbl matching with @pdev + * + * LOCKING: + * Inherited from PCI layer (may sleep). + * + * RETURNS: + * Zero on success, or -ERRNO value. + */ + +static int __devinit sch_init_one(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + static int printed_version; + const struct ata_port_info *ppi[] = { &sch_port_info, NULL }; + struct ata_host *host; + int rc; + + if (!printed_version++) + dev_printk(KERN_DEBUG, &pdev->dev, + "version " DRV_VERSION "\n"); + + /* enable device and prepare host */ + rc = pcim_enable_device(pdev); + if (rc) + return rc; + rc = ata_pci_sff_prepare_host(pdev, ppi, &host); + if (rc) + return rc; + pci_set_master(pdev); + return ata_pci_sff_activate_host(host, ata_sff_interrupt, &sch_sht); +} + +static int __init sch_init(void) +{ + return pci_register_driver(&sch_pci_driver); +} + +static void __exit sch_exit(void) +{ + pci_unregister_driver(&sch_pci_driver); +} + +module_init(sch_init); +module_exit(sch_exit); diff --git a/drivers/ata/pata_sl82c105.c b/drivers/ata/pata_sl82c105.c index 70d94fb28a5fa2070dbe461c715094377b2c3be0..69877bd81815f4a1a288da7e99447ec7e7afa4a2 100644 --- a/drivers/ata/pata_sl82c105.c +++ b/drivers/ata/pata_sl82c105.c @@ -216,7 +216,7 @@ static int sl82c105_qc_defer(struct ata_queued_cmd *qc) struct ata_port *alt = host->ports[1 ^ qc->ap->port_no]; int rc; - /* First apply the usual rules */ + /* First apply the usual rules */ rc = ata_std_qc_defer(qc); if (rc != 0) return rc; diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c index 2fea6cbe7755853b73331d09c1de61ccbba28a35..708ed144ede9175219a93f6acc499f6cd7421952 100644 --- a/drivers/ata/pata_via.c +++ b/drivers/ata/pata_via.c @@ -259,15 +259,15 @@ static void via_do_set_mode(struct ata_port *ap, struct ata_device *adev, int mo pci_read_config_byte(pdev, 0x4C, &setup); setup &= ~(3 << shift); - setup |= FIT(t.setup, 1, 4) << shift; /* 1,4 or 1,4 - 1 FIXME */ + setup |= clamp_val(t.setup, 1, 4) << shift; /* 1,4 or 1,4 - 1 FIXME */ pci_write_config_byte(pdev, 0x4C, setup); } /* Load the PIO mode bits */ pci_write_config_byte(pdev, 0x4F - ap->port_no, - ((FIT(t.act8b, 1, 16) - 1) << 4) | (FIT(t.rec8b, 1, 16) - 1)); + ((clamp_val(t.act8b, 1, 16) - 1) << 4) | (clamp_val(t.rec8b, 1, 16) - 1)); pci_write_config_byte(pdev, 0x48 + offset, - ((FIT(t.active, 1, 16) - 1) << 4) | (FIT(t.recover, 1, 16) - 1)); + ((clamp_val(t.active, 1, 16) - 1) << 4) | (clamp_val(t.recover, 1, 16) - 1)); /* Load the UDMA bits according to type */ switch(udma_type) { @@ -275,16 +275,16 @@ static void via_do_set_mode(struct ata_port *ap, struct ata_device *adev, int mo /* BUG() ? */ /* fall through */ case 33: - ut = t.udma ? (0xe0 | (FIT(t.udma, 2, 5) - 2)) : 0x03; + ut = t.udma ? (0xe0 | (clamp_val(t.udma, 2, 5) - 2)) : 0x03; break; case 66: - ut = t.udma ? (0xe8 | (FIT(t.udma, 2, 9) - 2)) : 0x0f; + ut = t.udma ? (0xe8 | (clamp_val(t.udma, 2, 9) - 2)) : 0x0f; break; case 100: - ut = t.udma ? (0xe0 | (FIT(t.udma, 2, 9) - 2)) : 0x07; + ut = t.udma ? (0xe0 | (clamp_val(t.udma, 2, 9) - 2)) : 0x07; break; case 133: - ut = t.udma ? (0xe0 | (FIT(t.udma, 2, 9) - 2)) : 0x07; + ut = t.udma ? (0xe0 | (clamp_val(t.udma, 2, 9) - 2)) : 0x07; break; } diff --git a/drivers/ata/pata_winbond.c b/drivers/ata/pata_winbond.c index 6e52a3573fbfd105361b673b99f2012bc9d4219d..474528f8fe3de769dacca40a5dcbaf9ec8a3ccc1 100644 --- a/drivers/ata/pata_winbond.c +++ b/drivers/ata/pata_winbond.c @@ -75,8 +75,8 @@ static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev) else ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); - active = (FIT(t.active, 3, 17) - 1) & 0x0F; - recovery = (FIT(t.recover, 1, 15) + 1) & 0x0F; + active = (clamp_val(t.active, 3, 17) - 1) & 0x0F; + recovery = (clamp_val(t.recover, 1, 15) + 1) & 0x0F; timing = (active << 4) | recovery; winbond_writecfg(winbond->config, timing, reg); @@ -87,7 +87,7 @@ static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev) reg |= 0x08; /* FIFO off */ if (!ata_pio_need_iordy(adev)) reg |= 0x02; /* IORDY off */ - reg |= (FIT(t.setup, 0, 3) << 6); + reg |= (clamp_val(t.setup, 0, 3) << 6); winbond_writecfg(winbond->config, timing + 1, reg); } diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c index d27bb9a2568f77678e82dfbc032df8045daa4b94..3ead02fe379e26ca1dac0130a323e06888ba7f35 100644 --- a/drivers/ata/sata_inic162x.c +++ b/drivers/ata/sata_inic162x.c @@ -10,13 +10,33 @@ * right. Documentation is available at initio's website but it only * documents registers (not programming model). * - * - ATA disks work. - * - Hotplug works. - * - ATAPI read works but burning doesn't. This thing is really - * peculiar about ATAPI and I couldn't figure out how ATAPI PIO and - * ATAPI DMA WRITE should be programmed. If you've got a clue, be - * my guest. - * - Both STR and STD work. + * This driver has interesting history. The first version was written + * from the documentation and a 2.4 IDE driver posted on a Taiwan + * company, which didn't use any IDMA features and couldn't handle + * LBA48. The resulting driver couldn't handle LBA48 devices either + * making it pretty useless. + * + * After a while, initio picked the driver up, renamed it to + * sata_initio162x, updated it to use IDMA for ATA DMA commands and + * posted it on their website. It only used ATA_PROT_DMA for IDMA and + * attaching both devices and issuing IDMA and !IDMA commands + * simultaneously broke it due to PIRQ masking interaction but it did + * show how to use the IDMA (ADMA + some initio specific twists) + * engine. + * + * Then, I picked up their changes again and here's the usable driver + * which uses IDMA for everything. Everything works now including + * LBA48, CD/DVD burning, suspend/resume and hotplug. There are some + * issues tho. Result Tf is not resported properly, NCQ isn't + * supported yet and CD/DVD writing works with DMA assisted PIO + * protocol (which, for native SATA devices, shouldn't cause any + * noticeable difference). + * + * Anyways, so, here's finally a working driver for inic162x. Enjoy! + * + * initio: If you guys wanna improve the driver regarding result TF + * access and other stuff, please feel free to contact me. I'll be + * happy to assist. */ #include @@ -28,13 +48,19 @@ #include #define DRV_NAME "sata_inic162x" -#define DRV_VERSION "0.3" +#define DRV_VERSION "0.4" enum { - MMIO_BAR = 5, + MMIO_BAR_PCI = 5, + MMIO_BAR_CARDBUS = 1, NR_PORTS = 2, + IDMA_CPB_TBL_SIZE = 4 * 32, + + INIC_DMA_BOUNDARY = 0xffffff, + + HOST_ACTRL = 0x08, HOST_CTL = 0x7c, HOST_STAT = 0x7e, HOST_IRQ_STAT = 0xbc, @@ -43,22 +69,37 @@ enum { PORT_SIZE = 0x40, /* registers for ATA TF operation */ - PORT_TF = 0x00, - PORT_ALT_STAT = 0x08, + PORT_TF_DATA = 0x00, + PORT_TF_FEATURE = 0x01, + PORT_TF_NSECT = 0x02, + PORT_TF_LBAL = 0x03, + PORT_TF_LBAM = 0x04, + PORT_TF_LBAH = 0x05, + PORT_TF_DEVICE = 0x06, + PORT_TF_COMMAND = 0x07, + PORT_TF_ALT_STAT = 0x08, PORT_IRQ_STAT = 0x09, PORT_IRQ_MASK = 0x0a, PORT_PRD_CTL = 0x0b, PORT_PRD_ADDR = 0x0c, PORT_PRD_XFERLEN = 0x10, + PORT_CPB_CPBLAR = 0x18, + PORT_CPB_PTQFIFO = 0x1c, /* IDMA register */ PORT_IDMA_CTL = 0x14, + PORT_IDMA_STAT = 0x16, + + PORT_RPQ_FIFO = 0x1e, + PORT_RPQ_CNT = 0x1f, PORT_SCR = 0x20, /* HOST_CTL bits */ HCTL_IRQOFF = (1 << 8), /* global IRQ off */ - HCTL_PWRDWN = (1 << 13), /* power down PHYs */ + HCTL_FTHD0 = (1 << 10), /* fifo threshold 0 */ + HCTL_FTHD1 = (1 << 11), /* fifo threshold 1*/ + HCTL_PWRDWN = (1 << 12), /* power down PHYs */ HCTL_SOFTRST = (1 << 13), /* global reset (no phy reset) */ HCTL_RPGSEL = (1 << 15), /* register page select */ @@ -81,9 +122,7 @@ enum { PIRQ_PENDING = (1 << 7), /* port IRQ pending (STAT only) */ PIRQ_ERR = PIRQ_OFFLINE | PIRQ_ONLINE | PIRQ_FATAL, - - PIRQ_MASK_DMA_READ = PIRQ_REPLY | PIRQ_ATA, - PIRQ_MASK_OTHER = PIRQ_REPLY | PIRQ_COMPLETE, + PIRQ_MASK_DEFAULT = PIRQ_REPLY | PIRQ_ATA, PIRQ_MASK_FREEZE = 0xff, /* PORT_PRD_CTL bits */ @@ -96,20 +135,104 @@ enum { IDMA_CTL_RST_IDMA = (1 << 5), /* reset IDMA machinary */ IDMA_CTL_GO = (1 << 7), /* IDMA mode go */ IDMA_CTL_ATA_NIEN = (1 << 8), /* ATA IRQ disable */ + + /* PORT_IDMA_STAT bits */ + IDMA_STAT_PERR = (1 << 0), /* PCI ERROR MODE */ + IDMA_STAT_CPBERR = (1 << 1), /* ADMA CPB error */ + IDMA_STAT_LGCY = (1 << 3), /* ADMA legacy */ + IDMA_STAT_UIRQ = (1 << 4), /* ADMA unsolicited irq */ + IDMA_STAT_STPD = (1 << 5), /* ADMA stopped */ + IDMA_STAT_PSD = (1 << 6), /* ADMA pause */ + IDMA_STAT_DONE = (1 << 7), /* ADMA done */ + + IDMA_STAT_ERR = IDMA_STAT_PERR | IDMA_STAT_CPBERR, + + /* CPB Control Flags*/ + CPB_CTL_VALID = (1 << 0), /* CPB valid */ + CPB_CTL_QUEUED = (1 << 1), /* queued command */ + CPB_CTL_DATA = (1 << 2), /* data, rsvd in datasheet */ + CPB_CTL_IEN = (1 << 3), /* PCI interrupt enable */ + CPB_CTL_DEVDIR = (1 << 4), /* device direction control */ + + /* CPB Response Flags */ + CPB_RESP_DONE = (1 << 0), /* ATA command complete */ + CPB_RESP_REL = (1 << 1), /* ATA release */ + CPB_RESP_IGNORED = (1 << 2), /* CPB ignored */ + CPB_RESP_ATA_ERR = (1 << 3), /* ATA command error */ + CPB_RESP_SPURIOUS = (1 << 4), /* ATA spurious interrupt error */ + CPB_RESP_UNDERFLOW = (1 << 5), /* APRD deficiency length error */ + CPB_RESP_OVERFLOW = (1 << 6), /* APRD exccess length error */ + CPB_RESP_CPB_ERR = (1 << 7), /* CPB error flag */ + + /* PRD Control Flags */ + PRD_DRAIN = (1 << 1), /* ignore data excess */ + PRD_CDB = (1 << 2), /* atapi packet command pointer */ + PRD_DIRECT_INTR = (1 << 3), /* direct interrupt */ + PRD_DMA = (1 << 4), /* data transfer method */ + PRD_WRITE = (1 << 5), /* data dir, rsvd in datasheet */ + PRD_IOM = (1 << 6), /* io/memory transfer */ + PRD_END = (1 << 7), /* APRD chain end */ }; +/* Comman Parameter Block */ +struct inic_cpb { + u8 resp_flags; /* Response Flags */ + u8 error; /* ATA Error */ + u8 status; /* ATA Status */ + u8 ctl_flags; /* Control Flags */ + __le32 len; /* Total Transfer Length */ + __le32 prd; /* First PRD pointer */ + u8 rsvd[4]; + /* 16 bytes */ + u8 feature; /* ATA Feature */ + u8 hob_feature; /* ATA Ex. Feature */ + u8 device; /* ATA Device/Head */ + u8 mirctl; /* Mirror Control */ + u8 nsect; /* ATA Sector Count */ + u8 hob_nsect; /* ATA Ex. Sector Count */ + u8 lbal; /* ATA Sector Number */ + u8 hob_lbal; /* ATA Ex. Sector Number */ + u8 lbam; /* ATA Cylinder Low */ + u8 hob_lbam; /* ATA Ex. Cylinder Low */ + u8 lbah; /* ATA Cylinder High */ + u8 hob_lbah; /* ATA Ex. Cylinder High */ + u8 command; /* ATA Command */ + u8 ctl; /* ATA Control */ + u8 slave_error; /* Slave ATA Error */ + u8 slave_status; /* Slave ATA Status */ + /* 32 bytes */ +} __packed; + +/* Physical Region Descriptor */ +struct inic_prd { + __le32 mad; /* Physical Memory Address */ + __le16 len; /* Transfer Length */ + u8 rsvd; + u8 flags; /* Control Flags */ +} __packed; + +struct inic_pkt { + struct inic_cpb cpb; + struct inic_prd prd[LIBATA_MAX_PRD + 1]; /* + 1 for cdb */ + u8 cdb[ATAPI_CDB_LEN]; +} __packed; + struct inic_host_priv { - u16 cached_hctl; + void __iomem *mmio_base; + u16 cached_hctl; }; struct inic_port_priv { - u8 dfl_prdctl; - u8 cached_prdctl; - u8 cached_pirq_mask; + struct inic_pkt *pkt; + dma_addr_t pkt_dma; + u32 *cpb_tbl; + dma_addr_t cpb_tbl_dma; }; static struct scsi_host_template inic_sht = { - ATA_BMDMA_SHT(DRV_NAME), + ATA_BASE_SHT(DRV_NAME), + .sg_tablesize = LIBATA_MAX_PRD, /* maybe it can be larger? */ + .dma_boundary = INIC_DMA_BOUNDARY, }; static const int scr_map[] = { @@ -120,54 +243,34 @@ static const int scr_map[] = { static void __iomem *inic_port_base(struct ata_port *ap) { - return ap->host->iomap[MMIO_BAR] + ap->port_no * PORT_SIZE; -} - -static void __inic_set_pirq_mask(struct ata_port *ap, u8 mask) -{ - void __iomem *port_base = inic_port_base(ap); - struct inic_port_priv *pp = ap->private_data; + struct inic_host_priv *hpriv = ap->host->private_data; - writeb(mask, port_base + PORT_IRQ_MASK); - pp->cached_pirq_mask = mask; -} - -static void inic_set_pirq_mask(struct ata_port *ap, u8 mask) -{ - struct inic_port_priv *pp = ap->private_data; - - if (pp->cached_pirq_mask != mask) - __inic_set_pirq_mask(ap, mask); + return hpriv->mmio_base + ap->port_no * PORT_SIZE; } static void inic_reset_port(void __iomem *port_base) { void __iomem *idma_ctl = port_base + PORT_IDMA_CTL; - u16 ctl; - ctl = readw(idma_ctl); - ctl &= ~(IDMA_CTL_RST_IDMA | IDMA_CTL_ATA_NIEN | IDMA_CTL_GO); + /* stop IDMA engine */ + readw(idma_ctl); /* flush */ + msleep(1); /* mask IRQ and assert reset */ - writew(ctl | IDMA_CTL_RST_IDMA | IDMA_CTL_ATA_NIEN, idma_ctl); + writew(IDMA_CTL_RST_IDMA, idma_ctl); readw(idma_ctl); /* flush */ - - /* give it some time */ msleep(1); /* release reset */ - writew(ctl | IDMA_CTL_ATA_NIEN, idma_ctl); + writew(0, idma_ctl); /* clear irq */ writeb(0xff, port_base + PORT_IRQ_STAT); - - /* reenable ATA IRQ, turn off IDMA mode */ - writew(ctl, idma_ctl); } static int inic_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val) { - void __iomem *scr_addr = ap->ioaddr.scr_addr; + void __iomem *scr_addr = inic_port_base(ap) + PORT_SCR; void __iomem *addr; if (unlikely(sc_reg >= ARRAY_SIZE(scr_map))) @@ -184,120 +287,126 @@ static int inic_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val) static int inic_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val) { - void __iomem *scr_addr = ap->ioaddr.scr_addr; - void __iomem *addr; + void __iomem *scr_addr = inic_port_base(ap) + PORT_SCR; if (unlikely(sc_reg >= ARRAY_SIZE(scr_map))) return -EINVAL; - addr = scr_addr + scr_map[sc_reg] * 4; writel(val, scr_addr + scr_map[sc_reg] * 4); return 0; } -/* - * In TF mode, inic162x is very similar to SFF device. TF registers - * function the same. DMA engine behaves similary using the same PRD - * format as BMDMA but different command register, interrupt and event - * notification methods are used. The following inic_bmdma_*() - * functions do the impedance matching. - */ -static void inic_bmdma_setup(struct ata_queued_cmd *qc) +static void inic_stop_idma(struct ata_port *ap) { - struct ata_port *ap = qc->ap; - struct inic_port_priv *pp = ap->private_data; void __iomem *port_base = inic_port_base(ap); - int rw = qc->tf.flags & ATA_TFLAG_WRITE; - - /* make sure device sees PRD table writes */ - wmb(); - - /* load transfer length */ - writel(qc->nbytes, port_base + PORT_PRD_XFERLEN); - - /* turn on DMA and specify data direction */ - pp->cached_prdctl = pp->dfl_prdctl | PRD_CTL_DMAEN; - if (!rw) - pp->cached_prdctl |= PRD_CTL_WR; - writeb(pp->cached_prdctl, port_base + PORT_PRD_CTL); - /* issue r/w command */ - ap->ops->sff_exec_command(ap, &qc->tf); + readb(port_base + PORT_RPQ_FIFO); + readb(port_base + PORT_RPQ_CNT); + writew(0, port_base + PORT_IDMA_CTL); } -static void inic_bmdma_start(struct ata_queued_cmd *qc) +static void inic_host_err_intr(struct ata_port *ap, u8 irq_stat, u16 idma_stat) { - struct ata_port *ap = qc->ap; + struct ata_eh_info *ehi = &ap->link.eh_info; struct inic_port_priv *pp = ap->private_data; - void __iomem *port_base = inic_port_base(ap); + struct inic_cpb *cpb = &pp->pkt->cpb; + bool freeze = false; - /* start host DMA transaction */ - pp->cached_prdctl |= PRD_CTL_START; - writeb(pp->cached_prdctl, port_base + PORT_PRD_CTL); -} + ata_ehi_clear_desc(ehi); + ata_ehi_push_desc(ehi, "irq_stat=0x%x idma_stat=0x%x", + irq_stat, idma_stat); -static void inic_bmdma_stop(struct ata_queued_cmd *qc) -{ - struct ata_port *ap = qc->ap; - struct inic_port_priv *pp = ap->private_data; - void __iomem *port_base = inic_port_base(ap); + inic_stop_idma(ap); - /* stop DMA engine */ - writeb(pp->dfl_prdctl, port_base + PORT_PRD_CTL); -} + if (irq_stat & (PIRQ_OFFLINE | PIRQ_ONLINE)) { + ata_ehi_push_desc(ehi, "hotplug"); + ata_ehi_hotplugged(ehi); + freeze = true; + } -static u8 inic_bmdma_status(struct ata_port *ap) -{ - /* event is already verified by the interrupt handler */ - return ATA_DMA_INTR; + if (idma_stat & IDMA_STAT_PERR) { + ata_ehi_push_desc(ehi, "PCI error"); + freeze = true; + } + + if (idma_stat & IDMA_STAT_CPBERR) { + ata_ehi_push_desc(ehi, "CPB error"); + + if (cpb->resp_flags & CPB_RESP_IGNORED) { + __ata_ehi_push_desc(ehi, " ignored"); + ehi->err_mask |= AC_ERR_INVALID; + freeze = true; + } + + if (cpb->resp_flags & CPB_RESP_ATA_ERR) + ehi->err_mask |= AC_ERR_DEV; + + if (cpb->resp_flags & CPB_RESP_SPURIOUS) { + __ata_ehi_push_desc(ehi, " spurious-intr"); + ehi->err_mask |= AC_ERR_HSM; + freeze = true; + } + + if (cpb->resp_flags & + (CPB_RESP_UNDERFLOW | CPB_RESP_OVERFLOW)) { + __ata_ehi_push_desc(ehi, " data-over/underflow"); + ehi->err_mask |= AC_ERR_HSM; + freeze = true; + } + } + + if (freeze) + ata_port_freeze(ap); + else + ata_port_abort(ap); } static void inic_host_intr(struct ata_port *ap) { void __iomem *port_base = inic_port_base(ap); - struct ata_eh_info *ehi = &ap->link.eh_info; + struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->link.active_tag); u8 irq_stat; + u16 idma_stat; - /* fetch and clear irq */ + /* read and clear IRQ status */ irq_stat = readb(port_base + PORT_IRQ_STAT); writeb(irq_stat, port_base + PORT_IRQ_STAT); + idma_stat = readw(port_base + PORT_IDMA_STAT); - if (likely(!(irq_stat & PIRQ_ERR))) { - struct ata_queued_cmd *qc = - ata_qc_from_tag(ap, ap->link.active_tag); + if (unlikely((irq_stat & PIRQ_ERR) || (idma_stat & IDMA_STAT_ERR))) + inic_host_err_intr(ap, irq_stat, idma_stat); - if (unlikely(!qc || (qc->tf.flags & ATA_TFLAG_POLLING))) { - ap->ops->sff_check_status(ap); /* clear ATA interrupt */ - return; - } + if (unlikely(!qc)) + goto spurious; - if (likely(ata_sff_host_intr(ap, qc))) - return; + if (likely(idma_stat & IDMA_STAT_DONE)) { + inic_stop_idma(ap); - ap->ops->sff_check_status(ap); /* clear ATA interrupt */ - ata_port_printk(ap, KERN_WARNING, "unhandled " - "interrupt, irq_stat=%x\n", irq_stat); + /* Depending on circumstances, device error + * isn't reported by IDMA, check it explicitly. + */ + if (unlikely(readb(port_base + PORT_TF_COMMAND) & + (ATA_DF | ATA_ERR))) + qc->err_mask |= AC_ERR_DEV; + + ata_qc_complete(qc); return; } - /* error */ - ata_ehi_push_desc(ehi, "irq_stat=0x%x", irq_stat); - - if (irq_stat & (PIRQ_OFFLINE | PIRQ_ONLINE)) { - ata_ehi_hotplugged(ehi); - ata_port_freeze(ap); - } else - ata_port_abort(ap); + spurious: + ata_port_printk(ap, KERN_WARNING, "unhandled interrupt: " + "cmd=0x%x irq_stat=0x%x idma_stat=0x%x\n", + qc ? qc->tf.command : 0xff, irq_stat, idma_stat); } static irqreturn_t inic_interrupt(int irq, void *dev_instance) { struct ata_host *host = dev_instance; - void __iomem *mmio_base = host->iomap[MMIO_BAR]; + struct inic_host_priv *hpriv = host->private_data; u16 host_irq_stat; int i, handled = 0;; - host_irq_stat = readw(mmio_base + HOST_IRQ_STAT); + host_irq_stat = readw(hpriv->mmio_base + HOST_IRQ_STAT); if (unlikely(!(host_irq_stat & HIRQ_GLOBAL))) goto out; @@ -327,60 +436,173 @@ static irqreturn_t inic_interrupt(int irq, void *dev_instance) return IRQ_RETVAL(handled); } +static int inic_check_atapi_dma(struct ata_queued_cmd *qc) +{ + /* For some reason ATAPI_PROT_DMA doesn't work for some + * commands including writes and other misc ops. Use PIO + * protocol instead, which BTW is driven by the DMA engine + * anyway, so it shouldn't make much difference for native + * SATA devices. + */ + if (atapi_cmd_type(qc->cdb[0]) == READ) + return 0; + return 1; +} + +static void inic_fill_sg(struct inic_prd *prd, struct ata_queued_cmd *qc) +{ + struct scatterlist *sg; + unsigned int si; + u8 flags = 0; + + if (qc->tf.flags & ATA_TFLAG_WRITE) + flags |= PRD_WRITE; + + if (ata_is_dma(qc->tf.protocol)) + flags |= PRD_DMA; + + for_each_sg(qc->sg, sg, qc->n_elem, si) { + prd->mad = cpu_to_le32(sg_dma_address(sg)); + prd->len = cpu_to_le16(sg_dma_len(sg)); + prd->flags = flags; + prd++; + } + + WARN_ON(!si); + prd[-1].flags |= PRD_END; +} + +static void inic_qc_prep(struct ata_queued_cmd *qc) +{ + struct inic_port_priv *pp = qc->ap->private_data; + struct inic_pkt *pkt = pp->pkt; + struct inic_cpb *cpb = &pkt->cpb; + struct inic_prd *prd = pkt->prd; + bool is_atapi = ata_is_atapi(qc->tf.protocol); + bool is_data = ata_is_data(qc->tf.protocol); + unsigned int cdb_len = 0; + + VPRINTK("ENTER\n"); + + if (is_atapi) + cdb_len = qc->dev->cdb_len; + + /* prepare packet, based on initio driver */ + memset(pkt, 0, sizeof(struct inic_pkt)); + + cpb->ctl_flags = CPB_CTL_VALID | CPB_CTL_IEN; + if (is_atapi || is_data) + cpb->ctl_flags |= CPB_CTL_DATA; + + cpb->len = cpu_to_le32(qc->nbytes + cdb_len); + cpb->prd = cpu_to_le32(pp->pkt_dma + offsetof(struct inic_pkt, prd)); + + cpb->device = qc->tf.device; + cpb->feature = qc->tf.feature; + cpb->nsect = qc->tf.nsect; + cpb->lbal = qc->tf.lbal; + cpb->lbam = qc->tf.lbam; + cpb->lbah = qc->tf.lbah; + + if (qc->tf.flags & ATA_TFLAG_LBA48) { + cpb->hob_feature = qc->tf.hob_feature; + cpb->hob_nsect = qc->tf.hob_nsect; + cpb->hob_lbal = qc->tf.hob_lbal; + cpb->hob_lbam = qc->tf.hob_lbam; + cpb->hob_lbah = qc->tf.hob_lbah; + } + + cpb->command = qc->tf.command; + /* don't load ctl - dunno why. it's like that in the initio driver */ + + /* setup PRD for CDB */ + if (is_atapi) { + memcpy(pkt->cdb, qc->cdb, ATAPI_CDB_LEN); + prd->mad = cpu_to_le32(pp->pkt_dma + + offsetof(struct inic_pkt, cdb)); + prd->len = cpu_to_le16(cdb_len); + prd->flags = PRD_CDB | PRD_WRITE; + if (!is_data) + prd->flags |= PRD_END; + prd++; + } + + /* setup sg table */ + if (is_data) + inic_fill_sg(prd, qc); + + pp->cpb_tbl[0] = pp->pkt_dma; +} + static unsigned int inic_qc_issue(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; + void __iomem *port_base = inic_port_base(ap); - /* ATA IRQ doesn't wait for DMA transfer completion and vice - * versa. Mask IRQ selectively to detect command completion. - * Without it, ATA DMA read command can cause data corruption. - * - * Something similar might be needed for ATAPI writes. I - * tried a lot of combinations but couldn't find the solution. - */ - if (qc->tf.protocol == ATA_PROT_DMA && - !(qc->tf.flags & ATA_TFLAG_WRITE)) - inic_set_pirq_mask(ap, PIRQ_MASK_DMA_READ); - else - inic_set_pirq_mask(ap, PIRQ_MASK_OTHER); + /* fire up the ADMA engine */ + writew(HCTL_FTHD0, port_base + HOST_CTL); + writew(IDMA_CTL_GO, port_base + PORT_IDMA_CTL); + writeb(0, port_base + PORT_CPB_PTQFIFO); + + return 0; +} + +static void inic_tf_read(struct ata_port *ap, struct ata_taskfile *tf) +{ + void __iomem *port_base = inic_port_base(ap); + + tf->feature = readb(port_base + PORT_TF_FEATURE); + tf->nsect = readb(port_base + PORT_TF_NSECT); + tf->lbal = readb(port_base + PORT_TF_LBAL); + tf->lbam = readb(port_base + PORT_TF_LBAM); + tf->lbah = readb(port_base + PORT_TF_LBAH); + tf->device = readb(port_base + PORT_TF_DEVICE); + tf->command = readb(port_base + PORT_TF_COMMAND); +} - /* Issuing a command to yet uninitialized port locks up the - * controller. Most of the time, this happens for the first - * command after reset which are ATA and ATAPI IDENTIFYs. - * Fast fail if stat is 0x7f or 0xff for those commands. +static bool inic_qc_fill_rtf(struct ata_queued_cmd *qc) +{ + struct ata_taskfile *rtf = &qc->result_tf; + struct ata_taskfile tf; + + /* FIXME: Except for status and error, result TF access + * doesn't work. I tried reading from BAR0/2, CPB and BAR5. + * None works regardless of which command interface is used. + * For now return true iff status indicates device error. + * This means that we're reporting bogus sector for RW + * failures. Eeekk.... */ - if (unlikely(qc->tf.command == ATA_CMD_ID_ATA || - qc->tf.command == ATA_CMD_ID_ATAPI)) { - u8 stat = ap->ops->sff_check_status(ap); - if (stat == 0x7f || stat == 0xff) - return AC_ERR_HSM; - } + inic_tf_read(qc->ap, &tf); - return ata_sff_qc_issue(qc); + if (!(tf.command & ATA_ERR)) + return false; + + rtf->command = tf.command; + rtf->feature = tf.feature; + return true; } static void inic_freeze(struct ata_port *ap) { void __iomem *port_base = inic_port_base(ap); - __inic_set_pirq_mask(ap, PIRQ_MASK_FREEZE); - - ap->ops->sff_check_status(ap); + writeb(PIRQ_MASK_FREEZE, port_base + PORT_IRQ_MASK); writeb(0xff, port_base + PORT_IRQ_STAT); - - readb(port_base + PORT_IRQ_STAT); /* flush */ } static void inic_thaw(struct ata_port *ap) { void __iomem *port_base = inic_port_base(ap); - ap->ops->sff_check_status(ap); writeb(0xff, port_base + PORT_IRQ_STAT); + writeb(PIRQ_MASK_DEFAULT, port_base + PORT_IRQ_MASK); +} - __inic_set_pirq_mask(ap, PIRQ_MASK_OTHER); +static int inic_check_ready(struct ata_link *link) +{ + void __iomem *port_base = inic_port_base(link->ap); - readb(port_base + PORT_IRQ_STAT); /* flush */ + return ata_check_ready(readb(port_base + PORT_TF_COMMAND)); } /* @@ -394,17 +616,15 @@ static int inic_hardreset(struct ata_link *link, unsigned int *class, void __iomem *port_base = inic_port_base(ap); void __iomem *idma_ctl = port_base + PORT_IDMA_CTL; const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context); - u16 val; int rc; /* hammer it into sane state */ inic_reset_port(port_base); - val = readw(idma_ctl); - writew(val | IDMA_CTL_RST_ATA, idma_ctl); + writew(IDMA_CTL_RST_ATA, idma_ctl); readw(idma_ctl); /* flush */ msleep(1); - writew(val & ~IDMA_CTL_RST_ATA, idma_ctl); + writew(0, idma_ctl); rc = sata_link_resume(link, timing, deadline); if (rc) { @@ -418,7 +638,7 @@ static int inic_hardreset(struct ata_link *link, unsigned int *class, struct ata_taskfile tf; /* wait for link to become ready */ - rc = ata_sff_wait_after_reset(link, 1, deadline); + rc = ata_wait_after_reset(link, deadline, inic_check_ready); /* link occupied, -ENODEV too is an error */ if (rc) { ata_link_printk(link, KERN_WARNING, "device not ready " @@ -426,7 +646,7 @@ static int inic_hardreset(struct ata_link *link, unsigned int *class, return rc; } - ata_sff_tf_read(ap, &tf); + inic_tf_read(ap, &tf); *class = ata_dev_classify(&tf); } @@ -436,18 +656,8 @@ static int inic_hardreset(struct ata_link *link, unsigned int *class, static void inic_error_handler(struct ata_port *ap) { void __iomem *port_base = inic_port_base(ap); - struct inic_port_priv *pp = ap->private_data; - unsigned long flags; - /* reset PIO HSM and stop DMA engine */ inic_reset_port(port_base); - - spin_lock_irqsave(ap->lock, flags); - ap->hsm_task_state = HSM_ST_IDLE; - writeb(pp->dfl_prdctl, port_base + PORT_PRD_CTL); - spin_unlock_irqrestore(ap->lock, flags); - - /* PIO and DMA engines have been stopped, perform recovery */ ata_std_error_handler(ap); } @@ -458,26 +668,18 @@ static void inic_post_internal_cmd(struct ata_queued_cmd *qc) inic_reset_port(inic_port_base(qc->ap)); } -static void inic_dev_config(struct ata_device *dev) -{ - /* inic can only handle upto LBA28 max sectors */ - if (dev->max_sectors > ATA_MAX_SECTORS) - dev->max_sectors = ATA_MAX_SECTORS; - - if (dev->n_sectors >= 1 << 28) { - ata_dev_printk(dev, KERN_ERR, - "ERROR: This driver doesn't support LBA48 yet and may cause\n" - " data corruption on such devices. Disabling.\n"); - ata_dev_disable(dev); - } -} - static void init_port(struct ata_port *ap) { void __iomem *port_base = inic_port_base(ap); + struct inic_port_priv *pp = ap->private_data; - /* Setup PRD address */ + /* clear packet and CPB table */ + memset(pp->pkt, 0, sizeof(struct inic_pkt)); + memset(pp->cpb_tbl, 0, IDMA_CPB_TBL_SIZE); + + /* setup PRD and CPB lookup table addresses */ writel(ap->prd_dma, port_base + PORT_PRD_ADDR); + writel(pp->cpb_tbl_dma, port_base + PORT_CPB_CPBLAR); } static int inic_port_resume(struct ata_port *ap) @@ -488,28 +690,30 @@ static int inic_port_resume(struct ata_port *ap) static int inic_port_start(struct ata_port *ap) { - void __iomem *port_base = inic_port_base(ap); + struct device *dev = ap->host->dev; struct inic_port_priv *pp; - u8 tmp; int rc; /* alloc and initialize private data */ - pp = devm_kzalloc(ap->host->dev, sizeof(*pp), GFP_KERNEL); + pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL); if (!pp) return -ENOMEM; ap->private_data = pp; - /* default PRD_CTL value, DMAEN, WR and START off */ - tmp = readb(port_base + PORT_PRD_CTL); - tmp &= ~(PRD_CTL_DMAEN | PRD_CTL_WR | PRD_CTL_START); - pp->dfl_prdctl = tmp; - /* Alloc resources */ rc = ata_port_start(ap); - if (rc) { - kfree(pp); + if (rc) return rc; - } + + pp->pkt = dmam_alloc_coherent(dev, sizeof(struct inic_pkt), + &pp->pkt_dma, GFP_KERNEL); + if (!pp->pkt) + return -ENOMEM; + + pp->cpb_tbl = dmam_alloc_coherent(dev, IDMA_CPB_TBL_SIZE, + &pp->cpb_tbl_dma, GFP_KERNEL); + if (!pp->cpb_tbl) + return -ENOMEM; init_port(ap); @@ -517,21 +721,18 @@ static int inic_port_start(struct ata_port *ap) } static struct ata_port_operations inic_port_ops = { - .inherits = &ata_sff_port_ops, + .inherits = &sata_port_ops, - .bmdma_setup = inic_bmdma_setup, - .bmdma_start = inic_bmdma_start, - .bmdma_stop = inic_bmdma_stop, - .bmdma_status = inic_bmdma_status, + .check_atapi_dma = inic_check_atapi_dma, + .qc_prep = inic_qc_prep, .qc_issue = inic_qc_issue, + .qc_fill_rtf = inic_qc_fill_rtf, .freeze = inic_freeze, .thaw = inic_thaw, - .softreset = ATA_OP_NULL, /* softreset is broken */ .hardreset = inic_hardreset, .error_handler = inic_error_handler, .post_internal_cmd = inic_post_internal_cmd, - .dev_config = inic_dev_config, .scr_read = inic_scr_read, .scr_write = inic_scr_write, @@ -541,12 +742,6 @@ static struct ata_port_operations inic_port_ops = { }; static struct ata_port_info inic_port_info = { - /* For some reason, ATAPI_PROT_PIO is broken on this - * controller, and no, PIO_POLLING does't fix it. It somehow - * manages to report the wrong ireason and ignoring ireason - * results in machine lock up. Tell libata to always prefer - * DMA. - */ .flags = ATA_FLAG_SATA | ATA_FLAG_PIO_DMA, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ @@ -599,7 +794,6 @@ static int inic_pci_device_resume(struct pci_dev *pdev) { struct ata_host *host = dev_get_drvdata(&pdev->dev); struct inic_host_priv *hpriv = host->private_data; - void __iomem *mmio_base = host->iomap[MMIO_BAR]; int rc; rc = ata_pci_device_do_resume(pdev); @@ -607,7 +801,7 @@ static int inic_pci_device_resume(struct pci_dev *pdev) return rc; if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) { - rc = init_controller(mmio_base, hpriv->cached_hctl); + rc = init_controller(hpriv->mmio_base, hpriv->cached_hctl); if (rc) return rc; } @@ -625,6 +819,7 @@ static int inic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) struct ata_host *host; struct inic_host_priv *hpriv; void __iomem * const *iomap; + int mmio_bar; int i, rc; if (!printed_version++) @@ -638,38 +833,31 @@ static int inic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) host->private_data = hpriv; - /* acquire resources and fill host */ + /* Acquire resources and fill host. Note that PCI and cardbus + * use different BARs. + */ rc = pcim_enable_device(pdev); if (rc) return rc; - rc = pcim_iomap_regions(pdev, 0x3f, DRV_NAME); + if (pci_resource_flags(pdev, MMIO_BAR_PCI) & IORESOURCE_MEM) + mmio_bar = MMIO_BAR_PCI; + else + mmio_bar = MMIO_BAR_CARDBUS; + + rc = pcim_iomap_regions(pdev, 1 << mmio_bar, DRV_NAME); if (rc) return rc; host->iomap = iomap = pcim_iomap_table(pdev); + hpriv->mmio_base = iomap[mmio_bar]; + hpriv->cached_hctl = readw(hpriv->mmio_base + HOST_CTL); for (i = 0; i < NR_PORTS; i++) { struct ata_port *ap = host->ports[i]; - struct ata_ioports *port = &ap->ioaddr; - unsigned int offset = i * PORT_SIZE; - - port->cmd_addr = iomap[2 * i]; - port->altstatus_addr = - port->ctl_addr = (void __iomem *) - ((unsigned long)iomap[2 * i + 1] | ATA_PCI_CTL_OFS); - port->scr_addr = iomap[MMIO_BAR] + offset + PORT_SCR; - - ata_sff_std_ports(port); - - ata_port_pbar_desc(ap, MMIO_BAR, -1, "mmio"); - ata_port_pbar_desc(ap, MMIO_BAR, offset, "port"); - ata_port_desc(ap, "cmd 0x%llx ctl 0x%llx", - (unsigned long long)pci_resource_start(pdev, 2 * i), - (unsigned long long)pci_resource_start(pdev, (2 * i + 1)) | - ATA_PCI_CTL_OFS); - } - hpriv->cached_hctl = readw(iomap[MMIO_BAR] + HOST_CTL); + ata_port_pbar_desc(ap, mmio_bar, -1, "mmio"); + ata_port_pbar_desc(ap, mmio_bar, i * PORT_SIZE, "port"); + } /* Set dma_mask. This devices doesn't support 64bit addressing. */ rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK); @@ -698,7 +886,7 @@ static int inic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) return rc; } - rc = init_controller(iomap[MMIO_BAR], hpriv->cached_hctl); + rc = init_controller(hpriv->mmio_base, hpriv->cached_hctl); if (rc) { dev_printk(KERN_ERR, &pdev->dev, "failed to initialize controller\n"); diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 842b1a15b78cadfafb5e031a8fe57245e6045380..fb81f0c7a8c2555d6e015c930a3373563f24cabc 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -65,13 +65,14 @@ #include #include #include +#include #include #include #include #include #define DRV_NAME "sata_mv" -#define DRV_VERSION "1.20" +#define DRV_VERSION "1.21" enum { /* BAR's are enumerated in terms of pci_resource_start() terms */ @@ -91,9 +92,9 @@ enum { MV_IRQ_COAL_TIME_THRESHOLD = (MV_IRQ_COAL_REG_BASE + 0xd0), MV_SATAHC0_REG_BASE = 0x20000, - MV_FLASH_CTL = 0x1046c, - MV_GPIO_PORT_CTL = 0x104f0, - MV_RESET_CFG = 0x180d8, + MV_FLASH_CTL_OFS = 0x1046c, + MV_GPIO_PORT_CTL_OFS = 0x104f0, + MV_RESET_CFG_OFS = 0x180d8, MV_PCI_REG_SZ = MV_MAJOR_REG_AREA_SZ, MV_SATAHC_REG_SZ = MV_MAJOR_REG_AREA_SZ, @@ -127,8 +128,13 @@ enum { MV_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO | ATA_FLAG_NO_ATAPI | ATA_FLAG_PIO_POLLING, + MV_6XXX_FLAGS = MV_FLAG_IRQ_COALESCE, + MV_GENIIE_FLAGS = MV_COMMON_FLAGS | MV_6XXX_FLAGS | + ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA | + ATA_FLAG_NCQ | ATA_FLAG_AN, + CRQB_FLAG_READ = (1 << 0), CRQB_TAG_SHIFT = 1, CRQB_IOID_SHIFT = 6, /* CRQB Gen-II/IIE IO Id shift */ @@ -147,18 +153,21 @@ enum { /* PCI interface registers */ PCI_COMMAND_OFS = 0xc00, + PCI_COMMAND_MRDTRIG = (1 << 7), /* PCI Master Read Trigger */ PCI_MAIN_CMD_STS_OFS = 0xd30, STOP_PCI_MASTER = (1 << 2), PCI_MASTER_EMPTY = (1 << 3), GLOB_SFT_RST = (1 << 4), - MV_PCI_MODE = 0xd00, + MV_PCI_MODE_OFS = 0xd00, + MV_PCI_MODE_MASK = 0x30, + MV_PCI_EXP_ROM_BAR_CTL = 0xd2c, MV_PCI_DISC_TIMER = 0xd04, MV_PCI_MSI_TRIGGER = 0xc38, MV_PCI_SERR_MASK = 0xc28, - MV_PCI_XBAR_TMOUT = 0x1d04, + MV_PCI_XBAR_TMOUT_OFS = 0x1d04, MV_PCI_ERR_LOW_ADDRESS = 0x1d40, MV_PCI_ERR_HIGH_ADDRESS = 0x1d44, MV_PCI_ERR_ATTRIBUTE = 0x1d48, @@ -193,13 +202,6 @@ enum { HC_MAIN_RSVD = (0x7f << 25), /* bits 31-25 */ HC_MAIN_RSVD_5 = (0x1fff << 19), /* bits 31-19 */ HC_MAIN_RSVD_SOC = (0x3fffffb << 6), /* bits 31-9, 7-6 */ - HC_MAIN_MASKED_IRQS = (TRAN_LO_DONE | TRAN_HI_DONE | - PORTS_0_3_COAL_DONE | PORTS_4_7_COAL_DONE | - PORTS_0_7_COAL_DONE | GPIO_INT | TWSI_INT | - HC_MAIN_RSVD), - HC_MAIN_MASKED_IRQS_5 = (PORTS_0_3_COAL_DONE | PORTS_4_7_COAL_DONE | - HC_MAIN_RSVD_5), - HC_MAIN_MASKED_IRQS_SOC = (PORTS_0_3_COAL_DONE | HC_MAIN_RSVD_SOC), /* SATAHC registers */ HC_CFG_OFS = 0, @@ -217,6 +219,7 @@ enum { SATA_STATUS_OFS = 0x300, /* ctrl, err regs follow status */ SATA_ACTIVE_OFS = 0x350, SATA_FIS_IRQ_CAUSE_OFS = 0x364, + SATA_FIS_IRQ_AN = (1 << 9), /* async notification */ LTMODE_OFS = 0x30c, LTMODE_BIT8 = (1 << 8), /* unknown, but necessary */ @@ -225,16 +228,18 @@ enum { PHY_MODE4 = 0x314, PHY_MODE2 = 0x330, SATA_IFCTL_OFS = 0x344, + SATA_TESTCTL_OFS = 0x348, SATA_IFSTAT_OFS = 0x34c, VENDOR_UNIQUE_FIS_OFS = 0x35c, - FIS_CFG_OFS = 0x360, - FIS_CFG_SINGLE_SYNC = (1 << 16), /* SYNC on DMA activation */ + FISCFG_OFS = 0x360, + FISCFG_WAIT_DEV_ERR = (1 << 8), /* wait for host on DevErr */ + FISCFG_SINGLE_SYNC = (1 << 16), /* SYNC on DMA activation */ MV5_PHY_MODE = 0x74, - MV5_LT_MODE = 0x30, - MV5_PHY_CTL = 0x0C, - SATA_INTERFACE_CFG = 0x050, + MV5_LTMODE_OFS = 0x30, + MV5_PHY_CTL_OFS = 0x0C, + SATA_INTERFACE_CFG_OFS = 0x050, MV_M2_PREAMP_MASK = 0x7e0, @@ -332,10 +337,16 @@ enum { EDMA_CMD_OFS = 0x28, /* EDMA command register */ EDMA_EN = (1 << 0), /* enable EDMA */ EDMA_DS = (1 << 1), /* disable EDMA; self-negated */ - ATA_RST = (1 << 2), /* reset trans/link/phy */ + EDMA_RESET = (1 << 2), /* reset eng/trans/link/phy */ - EDMA_IORDY_TMOUT = 0x34, - EDMA_ARB_CFG = 0x38, + EDMA_STATUS_OFS = 0x30, /* EDMA engine status */ + EDMA_STATUS_CACHE_EMPTY = (1 << 6), /* GenIIe command cache empty */ + EDMA_STATUS_IDLE = (1 << 7), /* GenIIe EDMA enabled/idle */ + + EDMA_IORDY_TMOUT_OFS = 0x34, + EDMA_ARB_CFG_OFS = 0x38, + + EDMA_HALTCOND_OFS = 0x60, /* GenIIe halt conditions */ GEN_II_NCQ_MAX_SECTORS = 256, /* max sects/io on Gen2 w/NCQ */ @@ -350,15 +361,19 @@ enum { MV_HP_GEN_II = (1 << 7), /* Generation II: 60xx */ MV_HP_GEN_IIE = (1 << 8), /* Generation IIE: 6042/7042 */ MV_HP_PCIE = (1 << 9), /* PCIe bus/regs: 7042 */ + MV_HP_CUT_THROUGH = (1 << 10), /* can use EDMA cut-through */ /* Port private flags (pp_flags) */ MV_PP_FLAG_EDMA_EN = (1 << 0), /* is EDMA engine enabled? */ MV_PP_FLAG_NCQ_EN = (1 << 1), /* is EDMA set up for NCQ? */ + MV_PP_FLAG_FBS_EN = (1 << 2), /* is EDMA set up for FBS? */ + MV_PP_FLAG_DELAYED_EH = (1 << 3), /* delayed dev err handling */ }; #define IS_GEN_I(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_I) #define IS_GEN_II(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_II) #define IS_GEN_IIE(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_IIE) +#define IS_PCIE(hpriv) ((hpriv)->hp_flags & MV_HP_PCIE) #define HAS_PCI(host) (!((host)->ports[0]->flags & MV_FLAG_SOC)) #define WINDOW_CTRL(i) (0x20030 + ((i) << 4)) @@ -433,6 +448,7 @@ struct mv_port_priv { unsigned int resp_idx; u32 pp_flags; + unsigned int delayed_eh_pmp_map; }; struct mv_port_signal { @@ -442,6 +458,7 @@ struct mv_port_signal { struct mv_host_priv { u32 hp_flags; + u32 main_irq_mask; struct mv_port_signal signal[8]; const struct mv_hw_ops *ops; int n_ports; @@ -479,6 +496,7 @@ static int mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val); static int mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val); static int mv_port_start(struct ata_port *ap); static void mv_port_stop(struct ata_port *ap); +static int mv_qc_defer(struct ata_queued_cmd *qc); static void mv_qc_prep(struct ata_queued_cmd *qc); static void mv_qc_prep_iie(struct ata_queued_cmd *qc); static unsigned int mv_qc_issue(struct ata_queued_cmd *qc); @@ -527,6 +545,9 @@ static int mv_pmp_hardreset(struct ata_link *link, unsigned int *class, unsigned long deadline); static int mv_softreset(struct ata_link *link, unsigned int *class, unsigned long deadline); +static void mv_pmp_error_handler(struct ata_port *ap); +static void mv_process_crpb_entries(struct ata_port *ap, + struct mv_port_priv *pp); /* .sg_tablesize is (MV_MAX_SG_CT / 2) in the structures below * because we have to allow room for worst case splitting of @@ -548,6 +569,7 @@ static struct scsi_host_template mv6_sht = { static struct ata_port_operations mv5_ops = { .inherits = &ata_sff_port_ops, + .qc_defer = mv_qc_defer, .qc_prep = mv_qc_prep, .qc_issue = mv_qc_issue, @@ -566,7 +588,6 @@ static struct ata_port_operations mv5_ops = { static struct ata_port_operations mv6_ops = { .inherits = &mv5_ops, - .qc_defer = sata_pmp_qc_defer_cmd_switch, .dev_config = mv6_dev_config, .scr_read = mv_scr_read, .scr_write = mv_scr_write, @@ -574,12 +595,11 @@ static struct ata_port_operations mv6_ops = { .pmp_hardreset = mv_pmp_hardreset, .pmp_softreset = mv_softreset, .softreset = mv_softreset, - .error_handler = sata_pmp_error_handler, + .error_handler = mv_pmp_error_handler, }; static struct ata_port_operations mv_iie_ops = { .inherits = &mv6_ops, - .qc_defer = ata_std_qc_defer, /* FIS-based switching */ .dev_config = ATA_OP_NULL, .qc_prep = mv_qc_prep_iie, }; @@ -620,25 +640,19 @@ static const struct ata_port_info mv_port_info[] = { .port_ops = &mv6_ops, }, { /* chip_6042 */ - .flags = MV_COMMON_FLAGS | MV_6XXX_FLAGS | - ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA | - ATA_FLAG_NCQ, + .flags = MV_GENIIE_FLAGS, .pio_mask = 0x1f, /* pio0-4 */ .udma_mask = ATA_UDMA6, .port_ops = &mv_iie_ops, }, { /* chip_7042 */ - .flags = MV_COMMON_FLAGS | MV_6XXX_FLAGS | - ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA | - ATA_FLAG_NCQ, + .flags = MV_GENIIE_FLAGS, .pio_mask = 0x1f, /* pio0-4 */ .udma_mask = ATA_UDMA6, .port_ops = &mv_iie_ops, }, { /* chip_soc */ - .flags = MV_COMMON_FLAGS | MV_6XXX_FLAGS | - ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA | - ATA_FLAG_NCQ | MV_FLAG_SOC, + .flags = MV_GENIIE_FLAGS | MV_FLAG_SOC, .pio_mask = 0x1f, /* pio0-4 */ .udma_mask = ATA_UDMA6, .port_ops = &mv_iie_ops, @@ -824,6 +838,33 @@ static void mv_set_edma_ptrs(void __iomem *port_mmio, port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); } +static void mv_set_main_irq_mask(struct ata_host *host, + u32 disable_bits, u32 enable_bits) +{ + struct mv_host_priv *hpriv = host->private_data; + u32 old_mask, new_mask; + + old_mask = hpriv->main_irq_mask; + new_mask = (old_mask & ~disable_bits) | enable_bits; + if (new_mask != old_mask) { + hpriv->main_irq_mask = new_mask; + writelfl(new_mask, hpriv->main_irq_mask_addr); + } +} + +static void mv_enable_port_irqs(struct ata_port *ap, + unsigned int port_bits) +{ + unsigned int shift, hardport, port = ap->port_no; + u32 disable_bits, enable_bits; + + MV_PORT_TO_SHIFT_AND_HARDPORT(port, shift, hardport); + + disable_bits = (DONE_IRQ | ERR_IRQ) << shift; + enable_bits = port_bits << shift; + mv_set_main_irq_mask(ap->host, disable_bits, enable_bits); +} + /** * mv_start_dma - Enable eDMA engine * @base: port base address @@ -866,15 +907,40 @@ static void mv_start_dma(struct ata_port *ap, void __iomem *port_mmio, mv_edma_cfg(ap, want_ncq); /* clear FIS IRQ Cause */ - writelfl(0, port_mmio + SATA_FIS_IRQ_CAUSE_OFS); + if (IS_GEN_IIE(hpriv)) + writelfl(0, port_mmio + SATA_FIS_IRQ_CAUSE_OFS); mv_set_edma_ptrs(port_mmio, hpriv, pp); + mv_enable_port_irqs(ap, DONE_IRQ|ERR_IRQ); writelfl(EDMA_EN, port_mmio + EDMA_CMD_OFS); pp->pp_flags |= MV_PP_FLAG_EDMA_EN; } } +static void mv_wait_for_edma_empty_idle(struct ata_port *ap) +{ + void __iomem *port_mmio = mv_ap_base(ap); + const u32 empty_idle = (EDMA_STATUS_CACHE_EMPTY | EDMA_STATUS_IDLE); + const int per_loop = 5, timeout = (15 * 1000 / per_loop); + int i; + + /* + * Wait for the EDMA engine to finish transactions in progress. + * No idea what a good "timeout" value might be, but measurements + * indicate that it often requires hundreds of microseconds + * with two drives in-use. So we use the 15msec value above + * as a rough guess at what even more drives might require. + */ + for (i = 0; i < timeout; ++i) { + u32 edma_stat = readl(port_mmio + EDMA_STATUS_OFS); + if ((edma_stat & empty_idle) == empty_idle) + break; + udelay(per_loop); + } + /* ata_port_printk(ap, KERN_INFO, "%s: %u+ usecs\n", __func__, i); */ +} + /** * mv_stop_edma_engine - Disable eDMA engine * @port_mmio: io base address @@ -907,6 +973,7 @@ static int mv_stop_edma(struct ata_port *ap) if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN)) return 0; pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN; + mv_wait_for_edma_empty_idle(ap); if (mv_stop_edma_engine(port_mmio)) { ata_port_printk(ap, KERN_ERR, "Unable to stop eDMA\n"); return -EIO; @@ -1057,26 +1124,95 @@ static void mv6_dev_config(struct ata_device *adev) } } -static void mv_config_fbs(void __iomem *port_mmio, int enable_fbs) +static int mv_qc_defer(struct ata_queued_cmd *qc) { - u32 old_fcfg, new_fcfg, old_ltmode, new_ltmode; + struct ata_link *link = qc->dev->link; + struct ata_port *ap = link->ap; + struct mv_port_priv *pp = ap->private_data; + /* - * Various bit settings required for operation - * in FIS-based switching (fbs) mode on GenIIe: + * Don't allow new commands if we're in a delayed EH state + * for NCQ and/or FIS-based switching. */ - old_fcfg = readl(port_mmio + FIS_CFG_OFS); - old_ltmode = readl(port_mmio + LTMODE_OFS); - if (enable_fbs) { - new_fcfg = old_fcfg | FIS_CFG_SINGLE_SYNC; - new_ltmode = old_ltmode | LTMODE_BIT8; - } else { /* disable fbs */ - new_fcfg = old_fcfg & ~FIS_CFG_SINGLE_SYNC; - new_ltmode = old_ltmode & ~LTMODE_BIT8; - } - if (new_fcfg != old_fcfg) - writelfl(new_fcfg, port_mmio + FIS_CFG_OFS); + if (pp->pp_flags & MV_PP_FLAG_DELAYED_EH) + return ATA_DEFER_PORT; + /* + * If the port is completely idle, then allow the new qc. + */ + if (ap->nr_active_links == 0) + return 0; + + if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) { + /* + * The port is operating in host queuing mode (EDMA). + * It can accomodate a new qc if the qc protocol + * is compatible with the current host queue mode. + */ + if (pp->pp_flags & MV_PP_FLAG_NCQ_EN) { + /* + * The host queue (EDMA) is in NCQ mode. + * If the new qc is also an NCQ command, + * then allow the new qc. + */ + if (qc->tf.protocol == ATA_PROT_NCQ) + return 0; + } else { + /* + * The host queue (EDMA) is in non-NCQ, DMA mode. + * If the new qc is also a non-NCQ, DMA command, + * then allow the new qc. + */ + if (qc->tf.protocol == ATA_PROT_DMA) + return 0; + } + } + return ATA_DEFER_PORT; +} + +static void mv_config_fbs(void __iomem *port_mmio, int want_ncq, int want_fbs) +{ + u32 new_fiscfg, old_fiscfg; + u32 new_ltmode, old_ltmode; + u32 new_haltcond, old_haltcond; + + old_fiscfg = readl(port_mmio + FISCFG_OFS); + old_ltmode = readl(port_mmio + LTMODE_OFS); + old_haltcond = readl(port_mmio + EDMA_HALTCOND_OFS); + + new_fiscfg = old_fiscfg & ~(FISCFG_SINGLE_SYNC | FISCFG_WAIT_DEV_ERR); + new_ltmode = old_ltmode & ~LTMODE_BIT8; + new_haltcond = old_haltcond | EDMA_ERR_DEV; + + if (want_fbs) { + new_fiscfg = old_fiscfg | FISCFG_SINGLE_SYNC; + new_ltmode = old_ltmode | LTMODE_BIT8; + if (want_ncq) + new_haltcond &= ~EDMA_ERR_DEV; + else + new_fiscfg |= FISCFG_WAIT_DEV_ERR; + } + + if (new_fiscfg != old_fiscfg) + writelfl(new_fiscfg, port_mmio + FISCFG_OFS); if (new_ltmode != old_ltmode) writelfl(new_ltmode, port_mmio + LTMODE_OFS); + if (new_haltcond != old_haltcond) + writelfl(new_haltcond, port_mmio + EDMA_HALTCOND_OFS); +} + +static void mv_60x1_errata_sata25(struct ata_port *ap, int want_ncq) +{ + struct mv_host_priv *hpriv = ap->host->private_data; + u32 old, new; + + /* workaround for 88SX60x1 FEr SATA#25 (part 1) */ + old = readl(hpriv->base + MV_GPIO_PORT_CTL_OFS); + if (want_ncq) + new = old | (1 << 22); + else + new = old & ~(1 << 22); + if (new != old) + writel(new, hpriv->base + MV_GPIO_PORT_CTL_OFS); } static void mv_edma_cfg(struct ata_port *ap, int want_ncq) @@ -1088,25 +1224,40 @@ static void mv_edma_cfg(struct ata_port *ap, int want_ncq) /* set up non-NCQ EDMA configuration */ cfg = EDMA_CFG_Q_DEPTH; /* always 0x1f for *all* chips */ + pp->pp_flags &= ~MV_PP_FLAG_FBS_EN; if (IS_GEN_I(hpriv)) cfg |= (1 << 8); /* enab config burst size mask */ - else if (IS_GEN_II(hpriv)) + else if (IS_GEN_II(hpriv)) { cfg |= EDMA_CFG_RD_BRST_EXT | EDMA_CFG_WR_BUFF_LEN; + mv_60x1_errata_sata25(ap, want_ncq); - else if (IS_GEN_IIE(hpriv)) { - cfg |= (1 << 23); /* do not mask PM field in rx'd FIS */ - cfg |= (1 << 22); /* enab 4-entry host queue cache */ - cfg |= (1 << 18); /* enab early completion */ - cfg |= (1 << 17); /* enab cut-through (dis stor&forwrd) */ + } else if (IS_GEN_IIE(hpriv)) { + int want_fbs = sata_pmp_attached(ap); + /* + * Possible future enhancement: + * + * The chip can use FBS with non-NCQ, if we allow it, + * But first we need to have the error handling in place + * for this mode (datasheet section 7.3.15.4.2.3). + * So disallow non-NCQ FBS for now. + */ + want_fbs &= want_ncq; + + mv_config_fbs(port_mmio, want_ncq, want_fbs); - if (want_ncq && sata_pmp_attached(ap)) { + if (want_fbs) { + pp->pp_flags |= MV_PP_FLAG_FBS_EN; cfg |= EDMA_CFG_EDMA_FBS; /* FIS-based switching */ - mv_config_fbs(port_mmio, 1); - } else { - mv_config_fbs(port_mmio, 0); } + + cfg |= (1 << 23); /* do not mask PM field in rx'd FIS */ + cfg |= (1 << 22); /* enab 4-entry host queue cache */ + if (HAS_PCI(ap->host)) + cfg |= (1 << 18); /* enab early completion */ + if (hpriv->hp_flags & MV_HP_CUT_THROUGH) + cfg |= (1 << 17); /* enab cut-thru (dis stor&forwrd) */ } if (want_ncq) { @@ -1213,6 +1364,7 @@ out_port_free_dma_mem: static void mv_port_stop(struct ata_port *ap) { mv_stop_edma(ap); + mv_enable_port_irqs(ap, 0); mv_port_free_dma_mem(ap); } @@ -1454,6 +1606,7 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc) * shadow block, etc registers. */ mv_stop_edma(ap); + mv_enable_port_irqs(ap, ERR_IRQ); mv_pmp_select(ap, qc->dev->link->pmp); return ata_sff_qc_issue(qc); } @@ -1483,25 +1636,198 @@ static struct ata_queued_cmd *mv_get_active_qc(struct ata_port *ap) return qc; } -static void mv_unexpected_intr(struct ata_port *ap) +static void mv_pmp_error_handler(struct ata_port *ap) { + unsigned int pmp, pmp_map; struct mv_port_priv *pp = ap->private_data; - struct ata_eh_info *ehi = &ap->link.eh_info; - char *when = ""; + if (pp->pp_flags & MV_PP_FLAG_DELAYED_EH) { + /* + * Perform NCQ error analysis on failed PMPs + * before we freeze the port entirely. + * + * The failed PMPs are marked earlier by mv_pmp_eh_prep(). + */ + pmp_map = pp->delayed_eh_pmp_map; + pp->pp_flags &= ~MV_PP_FLAG_DELAYED_EH; + for (pmp = 0; pmp_map != 0; pmp++) { + unsigned int this_pmp = (1 << pmp); + if (pmp_map & this_pmp) { + struct ata_link *link = &ap->pmp_link[pmp]; + pmp_map &= ~this_pmp; + ata_eh_analyze_ncq_error(link); + } + } + ata_port_freeze(ap); + } + sata_pmp_error_handler(ap); +} + +static unsigned int mv_get_err_pmp_map(struct ata_port *ap) +{ + void __iomem *port_mmio = mv_ap_base(ap); + + return readl(port_mmio + SATA_TESTCTL_OFS) >> 16; +} + +static void mv_pmp_eh_prep(struct ata_port *ap, unsigned int pmp_map) +{ + struct ata_eh_info *ehi; + unsigned int pmp; + + /* + * Initialize EH info for PMPs which saw device errors + */ + ehi = &ap->link.eh_info; + for (pmp = 0; pmp_map != 0; pmp++) { + unsigned int this_pmp = (1 << pmp); + if (pmp_map & this_pmp) { + struct ata_link *link = &ap->pmp_link[pmp]; + + pmp_map &= ~this_pmp; + ehi = &link->eh_info; + ata_ehi_clear_desc(ehi); + ata_ehi_push_desc(ehi, "dev err"); + ehi->err_mask |= AC_ERR_DEV; + ehi->action |= ATA_EH_RESET; + ata_link_abort(link); + } + } +} + +static int mv_req_q_empty(struct ata_port *ap) +{ + void __iomem *port_mmio = mv_ap_base(ap); + u32 in_ptr, out_ptr; + + in_ptr = (readl(port_mmio + EDMA_REQ_Q_IN_PTR_OFS) + >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK; + out_ptr = (readl(port_mmio + EDMA_REQ_Q_OUT_PTR_OFS) + >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK; + return (in_ptr == out_ptr); /* 1 == queue_is_empty */ +} + +static int mv_handle_fbs_ncq_dev_err(struct ata_port *ap) +{ + struct mv_port_priv *pp = ap->private_data; + int failed_links; + unsigned int old_map, new_map; + + /* + * Device error during FBS+NCQ operation: + * + * Set a port flag to prevent further I/O being enqueued. + * Leave the EDMA running to drain outstanding commands from this port. + * Perform the post-mortem/EH only when all responses are complete. + * Follow recovery sequence from 6042/7042 datasheet (7.3.15.4.2.2). + */ + if (!(pp->pp_flags & MV_PP_FLAG_DELAYED_EH)) { + pp->pp_flags |= MV_PP_FLAG_DELAYED_EH; + pp->delayed_eh_pmp_map = 0; + } + old_map = pp->delayed_eh_pmp_map; + new_map = old_map | mv_get_err_pmp_map(ap); + + if (old_map != new_map) { + pp->delayed_eh_pmp_map = new_map; + mv_pmp_eh_prep(ap, new_map & ~old_map); + } + failed_links = hweight16(new_map); + + ata_port_printk(ap, KERN_INFO, "%s: pmp_map=%04x qc_map=%04x " + "failed_links=%d nr_active_links=%d\n", + __func__, pp->delayed_eh_pmp_map, + ap->qc_active, failed_links, + ap->nr_active_links); + + if (ap->nr_active_links <= failed_links && mv_req_q_empty(ap)) { + mv_process_crpb_entries(ap, pp); + mv_stop_edma(ap); + mv_eh_freeze(ap); + ata_port_printk(ap, KERN_INFO, "%s: done\n", __func__); + return 1; /* handled */ + } + ata_port_printk(ap, KERN_INFO, "%s: waiting\n", __func__); + return 1; /* handled */ +} + +static int mv_handle_fbs_non_ncq_dev_err(struct ata_port *ap) +{ /* - * We got a device interrupt from something that - * was supposed to be using EDMA or polling. + * Possible future enhancement: + * + * FBS+non-NCQ operation is not yet implemented. + * See related notes in mv_edma_cfg(). + * + * Device error during FBS+non-NCQ operation: + * + * We need to snapshot the shadow registers for each failed command. + * Follow recovery sequence from 6042/7042 datasheet (7.3.15.4.2.3). */ + return 0; /* not handled */ +} + +static int mv_handle_dev_err(struct ata_port *ap, u32 edma_err_cause) +{ + struct mv_port_priv *pp = ap->private_data; + + if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN)) + return 0; /* EDMA was not active: not handled */ + if (!(pp->pp_flags & MV_PP_FLAG_FBS_EN)) + return 0; /* FBS was not active: not handled */ + + if (!(edma_err_cause & EDMA_ERR_DEV)) + return 0; /* non DEV error: not handled */ + edma_err_cause &= ~EDMA_ERR_IRQ_TRANSIENT; + if (edma_err_cause & ~(EDMA_ERR_DEV | EDMA_ERR_SELF_DIS)) + return 0; /* other problems: not handled */ + + if (pp->pp_flags & MV_PP_FLAG_NCQ_EN) { + /* + * EDMA should NOT have self-disabled for this case. + * If it did, then something is wrong elsewhere, + * and we cannot handle it here. + */ + if (edma_err_cause & EDMA_ERR_SELF_DIS) { + ata_port_printk(ap, KERN_WARNING, + "%s: err_cause=0x%x pp_flags=0x%x\n", + __func__, edma_err_cause, pp->pp_flags); + return 0; /* not handled */ + } + return mv_handle_fbs_ncq_dev_err(ap); + } else { + /* + * EDMA should have self-disabled for this case. + * If it did not, then something is wrong elsewhere, + * and we cannot handle it here. + */ + if (!(edma_err_cause & EDMA_ERR_SELF_DIS)) { + ata_port_printk(ap, KERN_WARNING, + "%s: err_cause=0x%x pp_flags=0x%x\n", + __func__, edma_err_cause, pp->pp_flags); + return 0; /* not handled */ + } + return mv_handle_fbs_non_ncq_dev_err(ap); + } + return 0; /* not handled */ +} + +static void mv_unexpected_intr(struct ata_port *ap, int edma_was_enabled) +{ + struct ata_eh_info *ehi = &ap->link.eh_info; + char *when = "idle"; + ata_ehi_clear_desc(ehi); - if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) { - when = " while EDMA enabled"; + if (!ap || (ap->flags & ATA_FLAG_DISABLED)) { + when = "disabled"; + } else if (edma_was_enabled) { + when = "EDMA enabled"; } else { struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->link.active_tag); if (qc && (qc->tf.flags & ATA_TFLAG_POLLING)) - when = " while polling"; + when = "polling"; } - ata_ehi_push_desc(ehi, "unexpected device interrupt%s", when); + ata_ehi_push_desc(ehi, "unexpected device interrupt while %s", when); ehi->err_mask |= AC_ERR_OTHER; ehi->action |= ATA_EH_RESET; ata_port_freeze(ap); @@ -1519,32 +1845,66 @@ static void mv_unexpected_intr(struct ata_port *ap) * LOCKING: * Inherited from caller. */ -static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc) +static void mv_err_intr(struct ata_port *ap) { void __iomem *port_mmio = mv_ap_base(ap); u32 edma_err_cause, eh_freeze_mask, serr = 0; + u32 fis_cause = 0; struct mv_port_priv *pp = ap->private_data; struct mv_host_priv *hpriv = ap->host->private_data; unsigned int action = 0, err_mask = 0; struct ata_eh_info *ehi = &ap->link.eh_info; - - ata_ehi_clear_desc(ehi); + struct ata_queued_cmd *qc; + int abort = 0; /* - * Read and clear the err_cause bits. This won't actually - * clear for some errors (eg. SError), but we will be doing - * a hard reset in those cases regardless, which *will* clear it. + * Read and clear the SError and err_cause bits. + * For GenIIe, if EDMA_ERR_TRANS_IRQ_7 is set, we also must read/clear + * the FIS_IRQ_CAUSE register before clearing edma_err_cause. */ + sata_scr_read(&ap->link, SCR_ERROR, &serr); + sata_scr_write_flush(&ap->link, SCR_ERROR, serr); + edma_err_cause = readl(port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); + if (IS_GEN_IIE(hpriv) && (edma_err_cause & EDMA_ERR_TRANS_IRQ_7)) { + fis_cause = readl(port_mmio + SATA_FIS_IRQ_CAUSE_OFS); + writelfl(~fis_cause, port_mmio + SATA_FIS_IRQ_CAUSE_OFS); + } writelfl(~edma_err_cause, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); - ata_ehi_push_desc(ehi, "edma_err_cause=%08x", edma_err_cause); + if (edma_err_cause & EDMA_ERR_DEV) { + /* + * Device errors during FIS-based switching operation + * require special handling. + */ + if (mv_handle_dev_err(ap, edma_err_cause)) + return; + } + qc = mv_get_active_qc(ap); + ata_ehi_clear_desc(ehi); + ata_ehi_push_desc(ehi, "edma_err_cause=%08x pp_flags=%08x", + edma_err_cause, pp->pp_flags); + + if (IS_GEN_IIE(hpriv) && (edma_err_cause & EDMA_ERR_TRANS_IRQ_7)) { + ata_ehi_push_desc(ehi, "fis_cause=%08x", fis_cause); + if (fis_cause & SATA_FIS_IRQ_AN) { + u32 ec = edma_err_cause & + ~(EDMA_ERR_TRANS_IRQ_7 | EDMA_ERR_IRQ_TRANSIENT); + sata_async_notification(ap); + if (!ec) + return; /* Just an AN; no need for the nukes */ + ata_ehi_push_desc(ehi, "SDB notify"); + } + } /* * All generations share these EDMA error cause bits: */ - if (edma_err_cause & EDMA_ERR_DEV) + if (edma_err_cause & EDMA_ERR_DEV) { err_mask |= AC_ERR_DEV; + action |= ATA_EH_RESET; + ata_ehi_push_desc(ehi, "dev error"); + } if (edma_err_cause & (EDMA_ERR_D_PAR | EDMA_ERR_PRD_PAR | EDMA_ERR_CRQB_PAR | EDMA_ERR_CRPB_PAR | EDMA_ERR_INTRL_PAR)) { @@ -1576,13 +1936,6 @@ static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc) ata_ehi_push_desc(ehi, "EDMA self-disable"); } if (edma_err_cause & EDMA_ERR_SERR) { - /* - * Ensure that we read our own SCR, not a pmp link SCR: - */ - ap->ops->scr_read(ap, SCR_ERROR, &serr); - /* - * Don't clear SError here; leave it for libata-eh: - */ ata_ehi_push_desc(ehi, "SError=%08x", serr); err_mask |= AC_ERR_ATA_BUS; action |= ATA_EH_RESET; @@ -1602,10 +1955,29 @@ static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc) else ehi->err_mask |= err_mask; - if (edma_err_cause & eh_freeze_mask) + if (err_mask == AC_ERR_DEV) { + /* + * Cannot do ata_port_freeze() here, + * because it would kill PIO access, + * which is needed for further diagnosis. + */ + mv_eh_freeze(ap); + abort = 1; + } else if (edma_err_cause & eh_freeze_mask) { + /* + * Note to self: ata_port_freeze() calls ata_port_abort() + */ ata_port_freeze(ap); - else - ata_port_abort(ap); + } else { + abort = 1; + } + + if (abort) { + if (qc) + ata_link_abort(qc->dev->link); + else + ata_port_abort(ap); + } } static void mv_process_crpb_response(struct ata_port *ap, @@ -1632,8 +2004,9 @@ static void mv_process_crpb_response(struct ata_port *ap, } } ata_status = edma_status >> CRPB_FLAG_STATUS_SHIFT; - qc->err_mask |= ac_err_mask(ata_status); - ata_qc_complete(qc); + if (!ac_err_mask(ata_status)) + ata_qc_complete(qc); + /* else: leave it for mv_err_intr() */ } else { ata_port_printk(ap, KERN_ERR, "%s: no qc for tag=%d\n", __func__, tag); @@ -1677,6 +2050,44 @@ static void mv_process_crpb_entries(struct ata_port *ap, struct mv_port_priv *pp port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); } +static void mv_port_intr(struct ata_port *ap, u32 port_cause) +{ + struct mv_port_priv *pp; + int edma_was_enabled; + + if (!ap || (ap->flags & ATA_FLAG_DISABLED)) { + mv_unexpected_intr(ap, 0); + return; + } + /* + * Grab a snapshot of the EDMA_EN flag setting, + * so that we have a consistent view for this port, + * even if something we call of our routines changes it. + */ + pp = ap->private_data; + edma_was_enabled = (pp->pp_flags & MV_PP_FLAG_EDMA_EN); + /* + * Process completed CRPB response(s) before other events. + */ + if (edma_was_enabled && (port_cause & DONE_IRQ)) { + mv_process_crpb_entries(ap, pp); + if (pp->pp_flags & MV_PP_FLAG_DELAYED_EH) + mv_handle_fbs_ncq_dev_err(ap); + } + /* + * Handle chip-reported errors, or continue on to handle PIO. + */ + if (unlikely(port_cause & ERR_IRQ)) { + mv_err_intr(ap); + } else if (!edma_was_enabled) { + struct ata_queued_cmd *qc = mv_get_active_qc(ap); + if (qc) + ata_sff_host_intr(ap, qc); + else + mv_unexpected_intr(ap, edma_was_enabled); + } +} + /** * mv_host_intr - Handle all interrupts on the given host controller * @host: host specific structure @@ -1688,66 +2099,58 @@ static void mv_process_crpb_entries(struct ata_port *ap, struct mv_port_priv *pp static int mv_host_intr(struct ata_host *host, u32 main_irq_cause) { struct mv_host_priv *hpriv = host->private_data; - void __iomem *mmio = hpriv->base, *hc_mmio = NULL; - u32 hc_irq_cause = 0; + void __iomem *mmio = hpriv->base, *hc_mmio; unsigned int handled = 0, port; for (port = 0; port < hpriv->n_ports; port++) { struct ata_port *ap = host->ports[port]; - struct mv_port_priv *pp; - unsigned int shift, hardport, port_cause; - /* - * When we move to the second hc, flag our cached - * copies of hc_mmio (and hc_irq_cause) as invalid again. - */ - if (port == MV_PORTS_PER_HC) - hc_mmio = NULL; - /* - * Do nothing if port is not interrupting or is disabled: - */ + unsigned int p, shift, hardport, port_cause; + MV_PORT_TO_SHIFT_AND_HARDPORT(port, shift, hardport); - port_cause = (main_irq_cause >> shift) & (DONE_IRQ | ERR_IRQ); - if (!port_cause || !ap || (ap->flags & ATA_FLAG_DISABLED)) - continue; /* - * Each hc within the host has its own hc_irq_cause register. - * We defer reading it until we know we need it, right now: - * - * FIXME later: we don't really need to read this register - * (some logic changes required below if we go that way), - * because it doesn't tell us anything new. But we do need - * to write to it, outside the top of this loop, - * to reset the interrupt triggers for next time. + * Each hc within the host has its own hc_irq_cause register, + * where the interrupting ports bits get ack'd. */ - if (!hc_mmio) { + if (hardport == 0) { /* first port on this hc ? */ + u32 hc_cause = (main_irq_cause >> shift) & HC0_IRQ_PEND; + u32 port_mask, ack_irqs; + /* + * Skip this entire hc if nothing pending for any ports + */ + if (!hc_cause) { + port += MV_PORTS_PER_HC - 1; + continue; + } + /* + * We don't need/want to read the hc_irq_cause register, + * because doing so hurts performance, and + * main_irq_cause already gives us everything we need. + * + * But we do have to *write* to the hc_irq_cause to ack + * the ports that we are handling this time through. + * + * This requires that we create a bitmap for those + * ports which interrupted us, and use that bitmap + * to ack (only) those ports via hc_irq_cause. + */ + ack_irqs = 0; + for (p = 0; p < MV_PORTS_PER_HC; ++p) { + if ((port + p) >= hpriv->n_ports) + break; + port_mask = (DONE_IRQ | ERR_IRQ) << (p * 2); + if (hc_cause & port_mask) + ack_irqs |= (DMA_IRQ | DEV_IRQ) << p; + } hc_mmio = mv_hc_base_from_port(mmio, port); - hc_irq_cause = readl(hc_mmio + HC_IRQ_CAUSE_OFS); - writelfl(~hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS); + writelfl(~ack_irqs, hc_mmio + HC_IRQ_CAUSE_OFS); handled = 1; } /* - * Process completed CRPB response(s) before other events. - */ - pp = ap->private_data; - if (hc_irq_cause & (DMA_IRQ << hardport)) { - if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) - mv_process_crpb_entries(ap, pp); - } - /* - * Handle chip-reported errors, or continue on to handle PIO. + * Handle interrupts signalled for this port: */ - if (unlikely(port_cause & ERR_IRQ)) { - mv_err_intr(ap, mv_get_active_qc(ap)); - } else if (hc_irq_cause & (DEV_IRQ << hardport)) { - if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN)) { - struct ata_queued_cmd *qc = mv_get_active_qc(ap); - if (qc) { - ata_sff_host_intr(ap, qc); - continue; - } - } - mv_unexpected_intr(ap); - } + port_cause = (main_irq_cause >> shift) & (DONE_IRQ | ERR_IRQ); + if (port_cause) + mv_port_intr(ap, port_cause); } return handled; } @@ -1812,20 +2215,20 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance) struct ata_host *host = dev_instance; struct mv_host_priv *hpriv = host->private_data; unsigned int handled = 0; - u32 main_irq_cause, main_irq_mask; + u32 main_irq_cause, pending_irqs; spin_lock(&host->lock); main_irq_cause = readl(hpriv->main_irq_cause_addr); - main_irq_mask = readl(hpriv->main_irq_mask_addr); + pending_irqs = main_irq_cause & hpriv->main_irq_mask; /* * Deal with cases where we either have nothing pending, or have read * a bogus register value which can indicate HW removal or PCI fault. */ - if ((main_irq_cause & main_irq_mask) && (main_irq_cause != 0xffffffffU)) { - if (unlikely((main_irq_cause & PCI_ERR) && HAS_PCI(host))) + if (pending_irqs && main_irq_cause != 0xffffffffU) { + if (unlikely((pending_irqs & PCI_ERR) && HAS_PCI(host))) handled = mv_pci_error(host, hpriv->base); else - handled = mv_host_intr(host, main_irq_cause); + handled = mv_host_intr(host, pending_irqs); } spin_unlock(&host->lock); return IRQ_RETVAL(handled); @@ -1894,7 +2297,7 @@ static void mv5_reset_bus(struct ata_host *host, void __iomem *mmio) static void mv5_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio) { - writel(0x0fcfffff, mmio + MV_FLASH_CTL); + writel(0x0fcfffff, mmio + MV_FLASH_CTL_OFS); } static void mv5_read_preamp(struct mv_host_priv *hpriv, int idx, @@ -1913,7 +2316,7 @@ static void mv5_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio) { u32 tmp; - writel(0, mmio + MV_GPIO_PORT_CTL); + writel(0, mmio + MV_GPIO_PORT_CTL_OFS); /* FIXME: handle MV_HP_ERRATA_50XXB2 errata */ @@ -1931,14 +2334,14 @@ static void mv5_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio, int fix_apm_sq = (hpriv->hp_flags & MV_HP_ERRATA_50XXB0); if (fix_apm_sq) { - tmp = readl(phy_mmio + MV5_LT_MODE); + tmp = readl(phy_mmio + MV5_LTMODE_OFS); tmp |= (1 << 19); - writel(tmp, phy_mmio + MV5_LT_MODE); + writel(tmp, phy_mmio + MV5_LTMODE_OFS); - tmp = readl(phy_mmio + MV5_PHY_CTL); + tmp = readl(phy_mmio + MV5_PHY_CTL_OFS); tmp &= ~0x3; tmp |= 0x1; - writel(tmp, phy_mmio + MV5_PHY_CTL); + writel(tmp, phy_mmio + MV5_PHY_CTL_OFS); } tmp = readl(phy_mmio + MV5_PHY_MODE); @@ -1956,11 +2359,6 @@ static void mv5_reset_hc_port(struct mv_host_priv *hpriv, void __iomem *mmio, { void __iomem *port_mmio = mv_port_base(mmio, port); - /* - * The datasheet warns against setting ATA_RST when EDMA is active - * (but doesn't say what the problem might be). So we first try - * to disable the EDMA engine before doing the ATA_RST operation. - */ mv_reset_channel(hpriv, mmio, port); ZERO(0x028); /* command */ @@ -1975,7 +2373,7 @@ static void mv5_reset_hc_port(struct mv_host_priv *hpriv, void __iomem *mmio, ZERO(0x024); /* respq outp */ ZERO(0x020); /* respq inp */ ZERO(0x02c); /* test control */ - writel(0xbc, port_mmio + EDMA_IORDY_TMOUT); + writel(0xbc, port_mmio + EDMA_IORDY_TMOUT_OFS); } #undef ZERO @@ -2021,14 +2419,13 @@ static void mv_reset_pci_bus(struct ata_host *host, void __iomem *mmio) struct mv_host_priv *hpriv = host->private_data; u32 tmp; - tmp = readl(mmio + MV_PCI_MODE); + tmp = readl(mmio + MV_PCI_MODE_OFS); tmp &= 0xff00ffff; - writel(tmp, mmio + MV_PCI_MODE); + writel(tmp, mmio + MV_PCI_MODE_OFS); ZERO(MV_PCI_DISC_TIMER); ZERO(MV_PCI_MSI_TRIGGER); - writel(0x000100ff, mmio + MV_PCI_XBAR_TMOUT); - ZERO(PCI_HC_MAIN_IRQ_MASK_OFS); + writel(0x000100ff, mmio + MV_PCI_XBAR_TMOUT_OFS); ZERO(MV_PCI_SERR_MASK); ZERO(hpriv->irq_cause_ofs); ZERO(hpriv->irq_mask_ofs); @@ -2045,10 +2442,10 @@ static void mv6_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio) mv5_reset_flash(hpriv, mmio); - tmp = readl(mmio + MV_GPIO_PORT_CTL); + tmp = readl(mmio + MV_GPIO_PORT_CTL_OFS); tmp &= 0x3; tmp |= (1 << 5) | (1 << 6); - writel(tmp, mmio + MV_GPIO_PORT_CTL); + writel(tmp, mmio + MV_GPIO_PORT_CTL_OFS); } /** @@ -2121,7 +2518,7 @@ static void mv6_read_preamp(struct mv_host_priv *hpriv, int idx, void __iomem *port_mmio; u32 tmp; - tmp = readl(mmio + MV_RESET_CFG); + tmp = readl(mmio + MV_RESET_CFG_OFS); if ((tmp & (1 << 0)) == 0) { hpriv->signal[idx].amps = 0x7 << 8; hpriv->signal[idx].pre = 0x1 << 5; @@ -2137,7 +2534,7 @@ static void mv6_read_preamp(struct mv_host_priv *hpriv, int idx, static void mv6_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio) { - writel(0x00000060, mmio + MV_GPIO_PORT_CTL); + writel(0x00000060, mmio + MV_GPIO_PORT_CTL_OFS); } static void mv6_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio, @@ -2235,11 +2632,6 @@ static void mv_soc_reset_hc_port(struct mv_host_priv *hpriv, { void __iomem *port_mmio = mv_port_base(mmio, port); - /* - * The datasheet warns against setting ATA_RST when EDMA is active - * (but doesn't say what the problem might be). So we first try - * to disable the EDMA engine before doing the ATA_RST operation. - */ mv_reset_channel(hpriv, mmio, port); ZERO(0x028); /* command */ @@ -2254,7 +2646,7 @@ static void mv_soc_reset_hc_port(struct mv_host_priv *hpriv, ZERO(0x024); /* respq outp */ ZERO(0x020); /* respq inp */ ZERO(0x02c); /* test control */ - writel(0xbc, port_mmio + EDMA_IORDY_TMOUT); + writel(0xbc, port_mmio + EDMA_IORDY_TMOUT_OFS); } #undef ZERO @@ -2297,38 +2689,39 @@ static void mv_soc_reset_bus(struct ata_host *host, void __iomem *mmio) return; } -static void mv_setup_ifctl(void __iomem *port_mmio, int want_gen2i) +static void mv_setup_ifcfg(void __iomem *port_mmio, int want_gen2i) { - u32 ifctl = readl(port_mmio + SATA_INTERFACE_CFG); + u32 ifcfg = readl(port_mmio + SATA_INTERFACE_CFG_OFS); - ifctl = (ifctl & 0xf7f) | 0x9b1000; /* from chip spec */ + ifcfg = (ifcfg & 0xf7f) | 0x9b1000; /* from chip spec */ if (want_gen2i) - ifctl |= (1 << 7); /* enable gen2i speed */ - writelfl(ifctl, port_mmio + SATA_INTERFACE_CFG); + ifcfg |= (1 << 7); /* enable gen2i speed */ + writelfl(ifcfg, port_mmio + SATA_INTERFACE_CFG_OFS); } -/* - * Caller must ensure that EDMA is not active, - * by first doing mv_stop_edma() where needed. - */ static void mv_reset_channel(struct mv_host_priv *hpriv, void __iomem *mmio, unsigned int port_no) { void __iomem *port_mmio = mv_port_base(mmio, port_no); + /* + * The datasheet warns against setting EDMA_RESET when EDMA is active + * (but doesn't say what the problem might be). So we first try + * to disable the EDMA engine before doing the EDMA_RESET operation. + */ mv_stop_edma_engine(port_mmio); - writelfl(ATA_RST, port_mmio + EDMA_CMD_OFS); + writelfl(EDMA_RESET, port_mmio + EDMA_CMD_OFS); if (!IS_GEN_I(hpriv)) { - /* Enable 3.0gb/s link speed */ - mv_setup_ifctl(port_mmio, 1); + /* Enable 3.0gb/s link speed: this survives EDMA_RESET */ + mv_setup_ifcfg(port_mmio, 1); } /* - * Strobing ATA_RST here causes a hard reset of the SATA transport, + * Strobing EDMA_RESET here causes a hard reset of the SATA transport, * link, and physical layers. It resets all SATA interface registers * (except for SATA_INTERFACE_CFG), and issues a COMRESET to the dev. */ - writelfl(ATA_RST, port_mmio + EDMA_CMD_OFS); + writelfl(EDMA_RESET, port_mmio + EDMA_CMD_OFS); udelay(25); /* allow reset propagation */ writelfl(0, port_mmio + EDMA_CMD_OFS); @@ -2387,12 +2780,13 @@ static int mv_hardreset(struct ata_link *link, unsigned int *class, rc = sata_link_hardreset(link, timing, deadline + extra, &online, NULL); + rc = online ? -EAGAIN : rc; if (rc) return rc; sata_scr_read(link, SCR_STATUS, &sstatus); if (!IS_GEN_I(hpriv) && ++attempts >= 5 && sstatus == 0x121) { /* Force 1.5gb/s link speed and try again */ - mv_setup_ifctl(mv_ap_base(ap), 0); + mv_setup_ifcfg(mv_ap_base(ap), 0); if (time_after(jiffies + HZ, deadline)) extra = HZ; /* only extend it once, max */ } @@ -2403,32 +2797,18 @@ static int mv_hardreset(struct ata_link *link, unsigned int *class, static void mv_eh_freeze(struct ata_port *ap) { - struct mv_host_priv *hpriv = ap->host->private_data; - unsigned int shift, hardport, port = ap->port_no; - u32 main_irq_mask; - - /* FIXME: handle coalescing completion events properly */ - mv_stop_edma(ap); - MV_PORT_TO_SHIFT_AND_HARDPORT(port, shift, hardport); - - /* disable assertion of portN err, done events */ - main_irq_mask = readl(hpriv->main_irq_mask_addr); - main_irq_mask &= ~((DONE_IRQ | ERR_IRQ) << shift); - writelfl(main_irq_mask, hpriv->main_irq_mask_addr); + mv_enable_port_irqs(ap, 0); } static void mv_eh_thaw(struct ata_port *ap) { struct mv_host_priv *hpriv = ap->host->private_data; - unsigned int shift, hardport, port = ap->port_no; + unsigned int port = ap->port_no; + unsigned int hardport = mv_hardport_from_port(port); void __iomem *hc_mmio = mv_hc_base_from_port(hpriv->base, port); void __iomem *port_mmio = mv_ap_base(ap); - u32 main_irq_mask, hc_irq_cause; - - /* FIXME: handle coalescing completion events properly */ - - MV_PORT_TO_SHIFT_AND_HARDPORT(port, shift, hardport); + u32 hc_irq_cause; /* clear EDMA errors on this port */ writel(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); @@ -2438,10 +2818,7 @@ static void mv_eh_thaw(struct ata_port *ap) hc_irq_cause &= ~((DEV_IRQ | DMA_IRQ) << hardport); writelfl(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS); - /* enable assertion of portN err, done events */ - main_irq_mask = readl(hpriv->main_irq_mask_addr); - main_irq_mask |= ((DONE_IRQ | ERR_IRQ) << shift); - writelfl(main_irq_mask, hpriv->main_irq_mask_addr); + mv_enable_port_irqs(ap, ERR_IRQ); } /** @@ -2493,6 +2870,34 @@ static void mv_port_init(struct ata_ioports *port, void __iomem *port_mmio) readl(port_mmio + EDMA_ERR_IRQ_MASK_OFS)); } +static unsigned int mv_in_pcix_mode(struct ata_host *host) +{ + struct mv_host_priv *hpriv = host->private_data; + void __iomem *mmio = hpriv->base; + u32 reg; + + if (!HAS_PCI(host) || !IS_PCIE(hpriv)) + return 0; /* not PCI-X capable */ + reg = readl(mmio + MV_PCI_MODE_OFS); + if ((reg & MV_PCI_MODE_MASK) == 0) + return 0; /* conventional PCI mode */ + return 1; /* chip is in PCI-X mode */ +} + +static int mv_pci_cut_through_okay(struct ata_host *host) +{ + struct mv_host_priv *hpriv = host->private_data; + void __iomem *mmio = hpriv->base; + u32 reg; + + if (!mv_in_pcix_mode(host)) { + reg = readl(mmio + PCI_COMMAND_OFS); + if (reg & PCI_COMMAND_MRDTRIG) + return 0; /* not okay */ + } + return 1; /* okay */ +} + static int mv_chip_id(struct ata_host *host, unsigned int board_idx) { struct pci_dev *pdev = to_pci_dev(host->dev); @@ -2560,7 +2965,7 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx) break; case chip_7042: - hp_flags |= MV_HP_PCIE; + hp_flags |= MV_HP_PCIE | MV_HP_CUT_THROUGH; if (pdev->vendor == PCI_VENDOR_ID_TTI && (pdev->device == 0x2300 || pdev->device == 0x2310)) { @@ -2590,9 +2995,12 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx) " and avoid the final two gigabytes on" " all RocketRAID BIOS initialized drives.\n"); } + /* drop through */ case chip_6042: hpriv->ops = &mv6xxx_ops; hp_flags |= MV_HP_GEN_IIE; + if (board_idx == chip_6042 && mv_pci_cut_through_okay(host)) + hp_flags |= MV_HP_CUT_THROUGH; switch (pdev->revision) { case 0x0: @@ -2663,7 +3071,7 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx) } /* global interrupt mask: 0 == mask everything */ - writel(0, hpriv->main_irq_mask_addr); + mv_set_main_irq_mask(host, ~0, 0); n_hc = mv_get_hc_count(host->ports[0]->flags); @@ -2711,25 +3119,12 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx) /* and unmask interrupt generation for host regs */ writelfl(hpriv->unmask_all_irqs, mmio + hpriv->irq_mask_ofs); - if (IS_GEN_I(hpriv)) - writelfl(~HC_MAIN_MASKED_IRQS_5, - hpriv->main_irq_mask_addr); - else - writelfl(~HC_MAIN_MASKED_IRQS, - hpriv->main_irq_mask_addr); - - VPRINTK("HC MAIN IRQ cause/mask=0x%08x/0x%08x " - "PCI int cause/mask=0x%08x/0x%08x\n", - readl(hpriv->main_irq_cause_addr), - readl(hpriv->main_irq_mask_addr), - readl(mmio + hpriv->irq_cause_ofs), - readl(mmio + hpriv->irq_mask_ofs)); - } else { - writelfl(~HC_MAIN_MASKED_IRQS_SOC, - hpriv->main_irq_mask_addr); - VPRINTK("HC MAIN IRQ cause/mask=0x%08x/0x%08x\n", - readl(hpriv->main_irq_cause_addr), - readl(hpriv->main_irq_mask_addr)); + + /* + * enable only global host interrupts for now. + * The per-port interrupts get done later as ports are set up. + */ + mv_set_main_irq_mask(host, 0, PCI_ERR); } done: return rc; diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c index 5a10dc5048ad3f8e88f748775f220b209e584056..030665ba76b73a308fd0e35693742140b761792c 100644 --- a/drivers/ata/sata_promise.c +++ b/drivers/ata/sata_promise.c @@ -53,7 +53,15 @@ enum { PDC_MMIO_BAR = 3, PDC_MAX_PRD = LIBATA_MAX_PRD - 1, /* -1 for ASIC PRD bug workaround */ - /* register offsets */ + /* host register offsets (from host->iomap[PDC_MMIO_BAR]) */ + PDC_INT_SEQMASK = 0x40, /* Mask of asserted SEQ INTs */ + PDC_FLASH_CTL = 0x44, /* Flash control register */ + PDC_SATA_PLUG_CSR = 0x6C, /* SATA Plug control/status reg */ + PDC2_SATA_PLUG_CSR = 0x60, /* SATAII Plug control/status reg */ + PDC_TBG_MODE = 0x41C, /* TBG mode (not SATAII) */ + PDC_SLEW_CTL = 0x470, /* slew rate control reg (not SATAII) */ + + /* per-port ATA register offsets (from ap->ioaddr.cmd_addr) */ PDC_FEATURE = 0x04, /* Feature/Error reg (per port) */ PDC_SECTOR_COUNT = 0x08, /* Sector count reg (per port) */ PDC_SECTOR_NUMBER = 0x0C, /* Sector number reg (per port) */ @@ -63,14 +71,11 @@ enum { PDC_COMMAND = 0x1C, /* Command/status reg (per port) */ PDC_ALTSTATUS = 0x38, /* Alternate-status/device-control reg (per port) */ PDC_PKT_SUBMIT = 0x40, /* Command packet pointer addr */ - PDC_INT_SEQMASK = 0x40, /* Mask of asserted SEQ INTs */ - PDC_FLASH_CTL = 0x44, /* Flash control register */ PDC_GLOBAL_CTL = 0x48, /* Global control/status (per port) */ PDC_CTLSTAT = 0x60, /* IDE control and status (per port) */ - PDC_SATA_PLUG_CSR = 0x6C, /* SATA Plug control/status reg */ - PDC2_SATA_PLUG_CSR = 0x60, /* SATAII Plug control/status reg */ - PDC_TBG_MODE = 0x41C, /* TBG mode (not SATAII) */ - PDC_SLEW_CTL = 0x470, /* slew rate control reg (not SATAII) */ + + /* per-port SATA register offsets (from ap->ioaddr.scr_addr) */ + PDC_PHYMODE4 = 0x14, /* PDC_GLOBAL_CTL bit definitions */ PDC_PH_ERR = (1 << 8), /* PCI error while loading packet */ @@ -134,7 +139,7 @@ struct pdc_port_priv { static int pdc_sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val); static int pdc_sata_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val); -static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); +static int pdc_ata_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); static int pdc_common_port_start(struct ata_port *ap); static int pdc_sata_port_start(struct ata_port *ap); static void pdc_qc_prep(struct ata_queued_cmd *qc); @@ -332,12 +337,12 @@ static int pdc_sata_port_start(struct ata_port *ap) /* fix up PHYMODE4 align timing */ if (ap->flags & PDC_FLAG_GEN_II) { - void __iomem *mmio = ap->ioaddr.scr_addr; + void __iomem *sata_mmio = ap->ioaddr.scr_addr; unsigned int tmp; - tmp = readl(mmio + 0x014); + tmp = readl(sata_mmio + PDC_PHYMODE4); tmp = (tmp & ~3) | 1; /* set bits 1:0 = 0:1 */ - writel(tmp, mmio + 0x014); + writel(tmp, sata_mmio + PDC_PHYMODE4); } return 0; @@ -345,32 +350,32 @@ static int pdc_sata_port_start(struct ata_port *ap) static void pdc_reset_port(struct ata_port *ap) { - void __iomem *mmio = ap->ioaddr.cmd_addr + PDC_CTLSTAT; + void __iomem *ata_ctlstat_mmio = ap->ioaddr.cmd_addr + PDC_CTLSTAT; unsigned int i; u32 tmp; for (i = 11; i > 0; i--) { - tmp = readl(mmio); + tmp = readl(ata_ctlstat_mmio); if (tmp & PDC_RESET) break; udelay(100); tmp |= PDC_RESET; - writel(tmp, mmio); + writel(tmp, ata_ctlstat_mmio); } tmp &= ~PDC_RESET; - writel(tmp, mmio); - readl(mmio); /* flush */ + writel(tmp, ata_ctlstat_mmio); + readl(ata_ctlstat_mmio); /* flush */ } static int pdc_pata_cable_detect(struct ata_port *ap) { u8 tmp; - void __iomem *mmio = ap->ioaddr.cmd_addr + PDC_CTLSTAT + 0x03; + void __iomem *ata_mmio = ap->ioaddr.cmd_addr; - tmp = readb(mmio); + tmp = readb(ata_mmio + PDC_CTLSTAT + 3); if (tmp & 0x01) return ATA_CBL_PATA40; return ATA_CBL_PATA80; @@ -557,31 +562,25 @@ static void pdc_qc_prep(struct ata_queued_cmd *qc) switch (qc->tf.protocol) { case ATA_PROT_DMA: pdc_fill_sg(qc); - /* fall through */ - + /*FALLTHROUGH*/ case ATA_PROT_NODATA: i = pdc_pkt_header(&qc->tf, qc->ap->prd_dma, qc->dev->devno, pp->pkt); - if (qc->tf.flags & ATA_TFLAG_LBA48) i = pdc_prep_lba48(&qc->tf, pp->pkt, i); else i = pdc_prep_lba28(&qc->tf, pp->pkt, i); - pdc_pkt_footer(&qc->tf, pp->pkt, i); break; - case ATAPI_PROT_PIO: pdc_fill_sg(qc); break; - case ATAPI_PROT_DMA: pdc_fill_sg(qc); /*FALLTHROUGH*/ case ATAPI_PROT_NODATA: pdc_atapi_pkt(qc); break; - default: break; } @@ -611,7 +610,7 @@ static unsigned int pdc_sata_ata_port_to_ata_no(const struct ata_port *ap) unsigned int nr_ports = pdc_sata_nr_ports(ap); unsigned int i; - for(i = 0; i < nr_ports && host->ports[i] != ap; ++i) + for (i = 0; i < nr_ports && host->ports[i] != ap; ++i) ; BUG_ON(i >= nr_ports); return pdc_port_no_to_ata_no(i, pdc_is_sataii_tx4(ap->flags)); @@ -624,14 +623,14 @@ static unsigned int pdc_sata_hotplug_offset(const struct ata_port *ap) static void pdc_freeze(struct ata_port *ap) { - void __iomem *mmio = ap->ioaddr.cmd_addr; + void __iomem *ata_mmio = ap->ioaddr.cmd_addr; u32 tmp; - tmp = readl(mmio + PDC_CTLSTAT); + tmp = readl(ata_mmio + PDC_CTLSTAT); tmp |= PDC_IRQ_DISABLE; tmp &= ~PDC_DMA_ENABLE; - writel(tmp, mmio + PDC_CTLSTAT); - readl(mmio + PDC_CTLSTAT); /* flush */ + writel(tmp, ata_mmio + PDC_CTLSTAT); + readl(ata_mmio + PDC_CTLSTAT); /* flush */ } static void pdc_sata_freeze(struct ata_port *ap) @@ -659,17 +658,17 @@ static void pdc_sata_freeze(struct ata_port *ap) static void pdc_thaw(struct ata_port *ap) { - void __iomem *mmio = ap->ioaddr.cmd_addr; + void __iomem *ata_mmio = ap->ioaddr.cmd_addr; u32 tmp; /* clear IRQ */ - readl(mmio + PDC_INT_SEQMASK); + readl(ata_mmio + PDC_COMMAND); /* turn IRQ back on */ - tmp = readl(mmio + PDC_CTLSTAT); + tmp = readl(ata_mmio + PDC_CTLSTAT); tmp &= ~PDC_IRQ_DISABLE; - writel(tmp, mmio + PDC_CTLSTAT); - readl(mmio + PDC_CTLSTAT); /* flush */ + writel(tmp, ata_mmio + PDC_CTLSTAT); + readl(ata_mmio + PDC_CTLSTAT); /* flush */ } static void pdc_sata_thaw(struct ata_port *ap) @@ -743,11 +742,11 @@ static void pdc_error_intr(struct ata_port *ap, struct ata_queued_cmd *qc, ata_port_abort(ap); } -static inline unsigned int pdc_host_intr(struct ata_port *ap, - struct ata_queued_cmd *qc) +static unsigned int pdc_host_intr(struct ata_port *ap, + struct ata_queued_cmd *qc) { unsigned int handled = 0; - void __iomem *port_mmio = ap->ioaddr.cmd_addr; + void __iomem *ata_mmio = ap->ioaddr.cmd_addr; u32 port_status, err_mask; err_mask = PDC_ERR_MASK; @@ -755,7 +754,7 @@ static inline unsigned int pdc_host_intr(struct ata_port *ap, err_mask &= ~PDC1_ERR_MASK; else err_mask &= ~PDC2_ERR_MASK; - port_status = readl(port_mmio + PDC_GLOBAL_CTL); + port_status = readl(ata_mmio + PDC_GLOBAL_CTL); if (unlikely(port_status & err_mask)) { pdc_error_intr(ap, qc, port_status, err_mask); return 1; @@ -770,7 +769,6 @@ static inline unsigned int pdc_host_intr(struct ata_port *ap, ata_qc_complete(qc); handled = 1; break; - default: ap->stats.idle_irq++; break; @@ -781,10 +779,9 @@ static inline unsigned int pdc_host_intr(struct ata_port *ap, static void pdc_irq_clear(struct ata_port *ap) { - struct ata_host *host = ap->host; - void __iomem *mmio = host->iomap[PDC_MMIO_BAR]; + void __iomem *ata_mmio = ap->ioaddr.cmd_addr; - readl(mmio + PDC_INT_SEQMASK); + readl(ata_mmio + PDC_COMMAND); } static irqreturn_t pdc_interrupt(int irq, void *dev_instance) @@ -794,7 +791,7 @@ static irqreturn_t pdc_interrupt(int irq, void *dev_instance) u32 mask = 0; unsigned int i, tmp; unsigned int handled = 0; - void __iomem *mmio_base; + void __iomem *host_mmio; unsigned int hotplug_offset, ata_no; u32 hotplug_status; int is_sataii_tx4; @@ -806,7 +803,7 @@ static irqreturn_t pdc_interrupt(int irq, void *dev_instance) return IRQ_NONE; } - mmio_base = host->iomap[PDC_MMIO_BAR]; + host_mmio = host->iomap[PDC_MMIO_BAR]; spin_lock(&host->lock); @@ -815,26 +812,26 @@ static irqreturn_t pdc_interrupt(int irq, void *dev_instance) hotplug_offset = PDC2_SATA_PLUG_CSR; else hotplug_offset = PDC_SATA_PLUG_CSR; - hotplug_status = readl(mmio_base + hotplug_offset); + hotplug_status = readl(host_mmio + hotplug_offset); if (hotplug_status & 0xff) - writel(hotplug_status | 0xff, mmio_base + hotplug_offset); + writel(hotplug_status | 0xff, host_mmio + hotplug_offset); hotplug_status &= 0xff; /* clear uninteresting bits */ /* reading should also clear interrupts */ - mask = readl(mmio_base + PDC_INT_SEQMASK); + mask = readl(host_mmio + PDC_INT_SEQMASK); if (mask == 0xffffffff && hotplug_status == 0) { VPRINTK("QUICK EXIT 2\n"); goto done_irq; } - mask &= 0xffff; /* only 16 tags possible */ + mask &= 0xffff; /* only 16 SEQIDs possible */ if (mask == 0 && hotplug_status == 0) { VPRINTK("QUICK EXIT 3\n"); goto done_irq; } - writel(mask, mmio_base + PDC_INT_SEQMASK); + writel(mask, host_mmio + PDC_INT_SEQMASK); is_sataii_tx4 = pdc_is_sataii_tx4(host->ports[0]->flags); @@ -875,23 +872,24 @@ done_irq: return IRQ_RETVAL(handled); } -static inline void pdc_packet_start(struct ata_queued_cmd *qc) +static void pdc_packet_start(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; struct pdc_port_priv *pp = ap->private_data; - void __iomem *mmio = ap->host->iomap[PDC_MMIO_BAR]; + void __iomem *host_mmio = ap->host->iomap[PDC_MMIO_BAR]; + void __iomem *ata_mmio = ap->ioaddr.cmd_addr; unsigned int port_no = ap->port_no; u8 seq = (u8) (port_no + 1); VPRINTK("ENTER, ap %p\n", ap); - writel(0x00000001, mmio + (seq * 4)); - readl(mmio + (seq * 4)); /* flush */ + writel(0x00000001, host_mmio + (seq * 4)); + readl(host_mmio + (seq * 4)); /* flush */ pp->pkt[2] = seq; wmb(); /* flush PRD, pkt writes */ - writel(pp->pkt_dma, ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT); - readl(ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT); /* flush */ + writel(pp->pkt_dma, ata_mmio + PDC_PKT_SUBMIT); + readl(ata_mmio + PDC_PKT_SUBMIT); /* flush */ } static unsigned int pdc_qc_issue(struct ata_queued_cmd *qc) @@ -909,11 +907,9 @@ static unsigned int pdc_qc_issue(struct ata_queued_cmd *qc) case ATA_PROT_DMA: pdc_packet_start(qc); return 0; - default: break; } - return ata_sff_qc_issue(qc); } @@ -987,7 +983,7 @@ static void pdc_ata_setup_port(struct ata_port *ap, static void pdc_host_init(struct ata_host *host) { - void __iomem *mmio = host->iomap[PDC_MMIO_BAR]; + void __iomem *host_mmio = host->iomap[PDC_MMIO_BAR]; int is_gen2 = host->ports[0]->flags & PDC_FLAG_GEN_II; int hotplug_offset; u32 tmp; @@ -1004,38 +1000,38 @@ static void pdc_host_init(struct ata_host *host) */ /* enable BMR_BURST, maybe change FIFO_SHD to 8 dwords */ - tmp = readl(mmio + PDC_FLASH_CTL); + tmp = readl(host_mmio + PDC_FLASH_CTL); tmp |= 0x02000; /* bit 13 (enable bmr burst) */ if (!is_gen2) tmp |= 0x10000; /* bit 16 (fifo threshold at 8 dw) */ - writel(tmp, mmio + PDC_FLASH_CTL); + writel(tmp, host_mmio + PDC_FLASH_CTL); /* clear plug/unplug flags for all ports */ - tmp = readl(mmio + hotplug_offset); - writel(tmp | 0xff, mmio + hotplug_offset); + tmp = readl(host_mmio + hotplug_offset); + writel(tmp | 0xff, host_mmio + hotplug_offset); /* unmask plug/unplug ints */ - tmp = readl(mmio + hotplug_offset); - writel(tmp & ~0xff0000, mmio + hotplug_offset); + tmp = readl(host_mmio + hotplug_offset); + writel(tmp & ~0xff0000, host_mmio + hotplug_offset); /* don't initialise TBG or SLEW on 2nd generation chips */ if (is_gen2) return; /* reduce TBG clock to 133 Mhz. */ - tmp = readl(mmio + PDC_TBG_MODE); + tmp = readl(host_mmio + PDC_TBG_MODE); tmp &= ~0x30000; /* clear bit 17, 16*/ tmp |= 0x10000; /* set bit 17:16 = 0:1 */ - writel(tmp, mmio + PDC_TBG_MODE); + writel(tmp, host_mmio + PDC_TBG_MODE); - readl(mmio + PDC_TBG_MODE); /* flush */ + readl(host_mmio + PDC_TBG_MODE); /* flush */ msleep(10); /* adjust slew rate control register. */ - tmp = readl(mmio + PDC_SLEW_CTL); + tmp = readl(host_mmio + PDC_SLEW_CTL); tmp &= 0xFFFFF03F; /* clear bit 11 ~ 6 */ tmp |= 0x00000900; /* set bit 11-9 = 100b , bit 8-6 = 100 */ - writel(tmp, mmio + PDC_SLEW_CTL); + writel(tmp, host_mmio + PDC_SLEW_CTL); } static int pdc_ata_init_one(struct pci_dev *pdev, @@ -1045,7 +1041,7 @@ static int pdc_ata_init_one(struct pci_dev *pdev, const struct ata_port_info *pi = &pdc_port_info[ent->driver_data]; const struct ata_port_info *ppi[PDC_MAX_PORTS]; struct ata_host *host; - void __iomem *base; + void __iomem *host_mmio; int n_ports, i, rc; int is_sataii_tx4; @@ -1062,7 +1058,7 @@ static int pdc_ata_init_one(struct pci_dev *pdev, pcim_pin_device(pdev); if (rc) return rc; - base = pcim_iomap_table(pdev)[PDC_MMIO_BAR]; + host_mmio = pcim_iomap_table(pdev)[PDC_MMIO_BAR]; /* determine port configuration and setup host */ n_ports = 2; @@ -1072,7 +1068,7 @@ static int pdc_ata_init_one(struct pci_dev *pdev, ppi[i] = pi; if (pi->flags & PDC_FLAG_SATA_PATA) { - u8 tmp = readb(base + PDC_FLASH_CTL+1); + u8 tmp = readb(host_mmio + PDC_FLASH_CTL + 1); if (!(tmp & 0x80)) ppi[n_ports++] = pi + 1; } @@ -1088,13 +1084,13 @@ static int pdc_ata_init_one(struct pci_dev *pdev, for (i = 0; i < host->n_ports; i++) { struct ata_port *ap = host->ports[i]; unsigned int ata_no = pdc_port_no_to_ata_no(i, is_sataii_tx4); - unsigned int port_offset = 0x200 + ata_no * 0x80; + unsigned int ata_offset = 0x200 + ata_no * 0x80; unsigned int scr_offset = 0x400 + ata_no * 0x100; - pdc_ata_setup_port(ap, base + port_offset, base + scr_offset); + pdc_ata_setup_port(ap, host_mmio + ata_offset, host_mmio + scr_offset); ata_port_pbar_desc(ap, PDC_MMIO_BAR, -1, "mmio"); - ata_port_pbar_desc(ap, PDC_MMIO_BAR, port_offset, "port"); + ata_port_pbar_desc(ap, PDC_MMIO_BAR, ata_offset, "ata"); } /* initialize adapter */ diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c index 27a110110077847b65e630cd11896b2e6195f75b..8ee6b5b4ede7bca0940783b37756b8b5f4aba158 100644 --- a/drivers/ata/sata_sil24.c +++ b/drivers/ata/sata_sil24.c @@ -899,14 +899,25 @@ static bool sil24_qc_fill_rtf(struct ata_queued_cmd *qc) static void sil24_pmp_attach(struct ata_port *ap) { + u32 *gscr = ap->link.device->gscr; + sil24_config_pmp(ap, 1); sil24_init_port(ap); + + if (sata_pmp_gscr_vendor(gscr) == 0x11ab && + sata_pmp_gscr_devid(gscr) == 0x4140) { + ata_port_printk(ap, KERN_INFO, + "disabling NCQ support due to sil24-mv4140 quirk\n"); + ap->flags &= ~ATA_FLAG_NCQ; + } } static void sil24_pmp_detach(struct ata_port *ap) { sil24_init_port(ap); sil24_config_pmp(ap, 0); + + ap->flags |= ATA_FLAG_NCQ; } static int sil24_pmp_hardreset(struct ata_link *link, unsigned int *class, diff --git a/drivers/base/class.c b/drivers/base/class.c index 0ef00e8d4153879513bfa2823a7fad0e25e4f6b7..e085af0ff94fb93007e7dce12f98443e4c5daa6d 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c @@ -140,7 +140,6 @@ int class_register(struct class *cls) pr_debug("device class '%s': registering\n", cls->name); - INIT_LIST_HEAD(&cls->children); INIT_LIST_HEAD(&cls->devices); INIT_LIST_HEAD(&cls->interfaces); kset_init(&cls->class_dirs); diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 8ce6de5a7e289f4bcf5138d96d013ba71117d66f..937e8258981db78be0b81303d63a8e7ebc30d692 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -53,11 +53,13 @@ int register_memory_notifier(struct notifier_block *nb) { return blocking_notifier_chain_register(&memory_chain, nb); } +EXPORT_SYMBOL(register_memory_notifier); void unregister_memory_notifier(struct notifier_block *nb) { blocking_notifier_chain_unregister(&memory_chain, nb); } +EXPORT_SYMBOL(unregister_memory_notifier); /* * register_memory - Setup a sysfs device for a memory block diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 7b76fd3b93a41b41b00b0fdac9915ed2bae15ad5..45cc3d9eacb874db52f663fe4cc3dea83b41d92c 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -418,7 +418,7 @@ void __suspend_report_result(const char *function, void *fn, int ret) { if (ret) { printk(KERN_ERR "%s(): ", function); - print_fn_descriptor_symbol("%s() returns ", (unsigned long)fn); + print_fn_descriptor_symbol("%s returns ", fn); printk("%d\n", ret); } } diff --git a/drivers/base/sys.c b/drivers/base/sys.c index 4fbb56bcb1eefbd60b5a189963e1e742ef794865..358bb0be3c0838b9233bae7b1eab1cc2b05ef1e6 100644 --- a/drivers/base/sys.c +++ b/drivers/base/sys.c @@ -175,8 +175,7 @@ int sysdev_driver_register(struct sysdev_class *cls, struct sysdev_driver *drv) } /* Check whether this driver has already been added to a class. */ - if ((drv->entry.next != drv->entry.prev) || - (drv->entry.next != NULL)) { + if (drv->entry.next && !list_empty(&drv->entry)) { printk(KERN_WARNING "sysdev: class %s: driver (%p) has already" " been registered to a class, something is wrong, but " "will forge on!\n", cls->name, drv); diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c index c9751b2b57e63f1ea96e02902ec7a57d7db885ea..7516baff3bb914116742b12a634ba4ab95db361a 100644 --- a/drivers/block/amiflop.c +++ b/drivers/block/amiflop.c @@ -1714,10 +1714,10 @@ static int __init amiga_floppy_init(void) int i, ret; if (!MACH_IS_AMIGA) - return -ENXIO; + return -ENODEV; if (!AMIGAHW_PRESENT(AMI_FLOPPY)) - return -ENXIO; + return -ENODEV; if (register_blkdev(FLOPPY_MAJOR,"fd")) return -EBUSY; @@ -1755,7 +1755,7 @@ static int __init amiga_floppy_init(void) if (!floppy_queue) goto out_queue; - ret = -ENXIO; + ret = -ENODEV; if (fd_probe_drives() < 1) /* No usable drives */ goto out_probe; diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c index 8fc429cf82b6b41d9ddf91d41a339831ac96a778..41f818be2f7ec8c4c737acaa16ecfeddc94f42b4 100644 --- a/drivers/block/aoe/aoecmd.c +++ b/drivers/block/aoe/aoecmd.c @@ -755,11 +755,13 @@ diskstats(struct gendisk *disk, struct bio *bio, ulong duration, sector_t sector { unsigned long n_sect = bio->bi_size >> 9; const int rw = bio_data_dir(bio); + struct hd_struct *part; - all_stat_inc(disk, ios[rw], sector); - all_stat_add(disk, ticks[rw], duration, sector); - all_stat_add(disk, sectors[rw], n_sect, sector); - all_stat_add(disk, io_ticks, duration, sector); + part = get_part(disk, sector); + all_stat_inc(disk, part, ios[rw], sector); + all_stat_add(disk, part, ticks[rw], duration, sector); + all_stat_add(disk, part, sectors[rw], n_sect, sector); + all_stat_add(disk, part, io_ticks, duration, sector); } void diff --git a/drivers/block/z2ram.c b/drivers/block/z2ram.c index 2d5853cbd4b002d4d2281da36b61097106090515..be20a67f1fa8c78397be751954a1d225e511af77 100644 --- a/drivers/block/z2ram.c +++ b/drivers/block/z2ram.c @@ -332,7 +332,7 @@ z2_init(void) int ret; if (!MACH_IS_AMIGA) - return -ENXIO; + return -ENODEV; ret = -EBUSY; if (register_blkdev(Z2RAM_MAJOR, DEVICE_NAME)) diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 5dce3877eee589f8bd680a7c3df8eab74cdd4888..595a925c62a942d1ac11275082fd4a225627d207 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -196,6 +196,7 @@ config ESPSERIAL config MOXA_INTELLIO tristate "Moxa Intellio support" depends on SERIAL_NONSTANDARD && (ISA || EISA || PCI) + select FW_LOADER help Say Y here if you have a Moxa Intellio multiport serial card. diff --git a/drivers/char/drm/drm.h b/drivers/char/drm/drm.h index 6874f31ca8caa329da769f13960bc0f08ae58f01..3a05c6d5ebe1f9306bca6a3e11740d54b9e6e5ef 100644 --- a/drivers/char/drm/drm.h +++ b/drivers/char/drm/drm.h @@ -471,7 +471,6 @@ struct drm_irq_busid { enum drm_vblank_seq_type { _DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */ _DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */ - _DRM_VBLANK_FLIP = 0x8000000, /**< Scheduled buffer swap should flip */ _DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */ _DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */ _DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking */ @@ -504,21 +503,6 @@ union drm_wait_vblank { struct drm_wait_vblank_reply reply; }; -enum drm_modeset_ctl_cmd { - _DRM_PRE_MODESET = 1, - _DRM_POST_MODESET = 2, -}; - -/** - * DRM_IOCTL_MODESET_CTL ioctl argument type - * - * \sa drmModesetCtl(). - */ -struct drm_modeset_ctl { - unsigned long arg; - enum drm_modeset_ctl_cmd cmd; -}; - /** * DRM_IOCTL_AGP_ENABLE ioctl argument type. * @@ -603,7 +587,6 @@ struct drm_set_version { #define DRM_IOCTL_GET_CLIENT DRM_IOWR(0x05, struct drm_client) #define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, struct drm_stats) #define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, struct drm_set_version) -#define DRM_IOCTL_MODESET_CTL DRM_IOW(0x08, struct drm_modeset_ctl) #define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, struct drm_unique) #define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, struct drm_auth) diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h index 213b3ca3468e5bdaf1c80db13a7d8c2c5e44a38a..0764b662b33936a396dea2c50f537ffea5ce31c5 100644 --- a/drivers/char/drm/drmP.h +++ b/drivers/char/drm/drmP.h @@ -100,8 +100,10 @@ struct drm_device; #define DRIVER_HAVE_DMA 0x20 #define DRIVER_HAVE_IRQ 0x40 #define DRIVER_IRQ_SHARED 0x80 +#define DRIVER_IRQ_VBL 0x100 #define DRIVER_DMA_QUEUE 0x200 #define DRIVER_FB_DMA 0x400 +#define DRIVER_IRQ_VBL2 0x800 /***********************************************************************/ /** \name Begin the DRM... */ @@ -577,52 +579,10 @@ struct drm_driver { int (*context_dtor) (struct drm_device *dev, int context); int (*kernel_context_switch) (struct drm_device *dev, int old, int new); - void (*kernel_context_switch_unlock) (struct drm_device * dev); - /** - * get_vblank_counter - get raw hardware vblank counter - * @dev: DRM device - * @crtc: counter to fetch - * - * Driver callback for fetching a raw hardware vblank counter - * for @crtc. If a device doesn't have a hardware counter, the - * driver can simply return the value of drm_vblank_count and - * make the enable_vblank() and disable_vblank() hooks into no-ops, - * leaving interrupts enabled at all times. - * - * Wraparound handling and loss of events due to modesetting is dealt - * with in the DRM core code. - * - * RETURNS - * Raw vblank counter value. - */ - u32 (*get_vblank_counter) (struct drm_device *dev, int crtc); - - /** - * enable_vblank - enable vblank interrupt events - * @dev: DRM device - * @crtc: which irq to enable - * - * Enable vblank interrupts for @crtc. If the device doesn't have - * a hardware vblank counter, this routine should be a no-op, since - * interrupts will have to stay on to keep the count accurate. - * - * RETURNS - * Zero on success, appropriate errno if the given @crtc's vblank - * interrupt cannot be enabled. - */ - int (*enable_vblank) (struct drm_device *dev, int crtc); - - /** - * disable_vblank - disable vblank interrupt events - * @dev: DRM device - * @crtc: which irq to enable - * - * Disable vblank interrupts for @crtc. If the device doesn't have - * a hardware vblank counter, this routine should be a no-op, since - * interrupts will have to stay on to keep the count accurate. - */ - void (*disable_vblank) (struct drm_device *dev, int crtc); - int (*dri_library_name) (struct drm_device *dev, char * buf); + void (*kernel_context_switch_unlock) (struct drm_device *dev); + int (*vblank_wait) (struct drm_device *dev, unsigned int *sequence); + int (*vblank_wait2) (struct drm_device *dev, unsigned int *sequence); + int (*dri_library_name) (struct drm_device *dev, char *buf); /** * Called by \c drm_device_is_agp. Typically used to determine if a @@ -641,7 +601,7 @@ struct drm_driver { irqreturn_t(*irq_handler) (DRM_IRQ_ARGS); void (*irq_preinstall) (struct drm_device *dev); - int (*irq_postinstall) (struct drm_device *dev); + void (*irq_postinstall) (struct drm_device *dev); void (*irq_uninstall) (struct drm_device *dev); void (*reclaim_buffers) (struct drm_device *dev, struct drm_file * file_priv); @@ -770,21 +730,13 @@ struct drm_device { /** \name VBLANK IRQ support */ /*@{ */ - wait_queue_head_t *vbl_queue; /**< VBLANK wait queue */ - atomic_t *_vblank_count; /**< number of VBLANK interrupts (driver must alloc the right number of counters) */ + wait_queue_head_t vbl_queue; /**< VBLANK wait queue */ + atomic_t vbl_received; + atomic_t vbl_received2; /**< number of secondary VBLANK interrupts */ spinlock_t vbl_lock; - struct list_head *vbl_sigs; /**< signal list to send on VBLANK */ - atomic_t vbl_signal_pending; /* number of signals pending on all crtcs*/ - atomic_t *vblank_refcount; /* number of users of vblank interrupts per crtc */ - u32 *last_vblank; /* protected by dev->vbl_lock, used */ - /* for wraparound handling */ - u32 *vblank_offset; /* used to track how many vblanks */ - int *vblank_enabled; /* so we don't call enable more than - once per disable */ - u32 *vblank_premodeset; /* were lost during modeset */ - struct timer_list vblank_disable_timer; - - unsigned long max_vblank_count; /**< size of vblank counter register */ + struct list_head vbl_sigs; /**< signal list to send on VBLANK */ + struct list_head vbl_sigs2; /**< signals to send on secondary VBLANK */ + unsigned int vbl_pending; spinlock_t tasklet_lock; /**< For drm_locked_tasklet */ void (*locked_tasklet_func)(struct drm_device *dev); @@ -804,7 +756,6 @@ struct drm_device { #ifdef __alpha__ struct pci_controller *hose; #endif - int num_crtcs; /**< Number of CRTCs on this device */ struct drm_sg_mem *sg; /**< Scatter gather memory */ void *dev_private; /**< device private data */ struct drm_sigdata sigdata; /**< For block_all_signals */ @@ -1039,19 +990,11 @@ extern void drm_driver_irq_preinstall(struct drm_device *dev); extern void drm_driver_irq_postinstall(struct drm_device *dev); extern void drm_driver_irq_uninstall(struct drm_device *dev); -extern int drm_vblank_init(struct drm_device *dev, int num_crtcs); -extern int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *filp); -extern int drm_vblank_wait(struct drm_device * dev, unsigned int *vbl_seq); -extern void drm_locked_tasklet(struct drm_device *dev, void(*func)(struct drm_device*)); -extern u32 drm_vblank_count(struct drm_device *dev, int crtc); -extern void drm_update_vblank_count(struct drm_device *dev, int crtc); -extern void drm_handle_vblank(struct drm_device *dev, int crtc); -extern int drm_vblank_get(struct drm_device *dev, int crtc); -extern void drm_vblank_put(struct drm_device *dev, int crtc); - - /* Modesetting support */ -extern int drm_modeset_ctl(struct drm_device *dev, void *data, +extern int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int drm_vblank_wait(struct drm_device *dev, unsigned int *vbl_seq); +extern void drm_vbl_send_signals(struct drm_device *dev); +extern void drm_locked_tasklet(struct drm_device *dev, void(*func)(struct drm_device*)); /* AGP/GART support (drm_agpsupport.h) */ extern struct drm_agp_head *drm_agp_init(struct drm_device *dev); diff --git a/drivers/char/drm/drm_fops.c b/drivers/char/drm/drm_fops.c index 68f0da801ed82b579efc5fcc3a94c6b755536f1c..d2e6da85f58ac262b2297b6e8281c943aa009cf1 100644 --- a/drivers/char/drm/drm_fops.c +++ b/drivers/char/drm/drm_fops.c @@ -323,7 +323,6 @@ int drm_release(struct inode *inode, struct file *filp) struct drm_file *file_priv = filp->private_data; struct drm_device *dev = file_priv->minor->dev; int retcode = 0; - unsigned long irqflags; lock_kernel(); @@ -355,11 +354,9 @@ int drm_release(struct inode *inode, struct file *filp) */ do{ - spin_lock_irqsave(&dev->lock.spinlock, - irqflags); + spin_lock_bh(&dev->lock.spinlock); locked = dev->lock.idle_has_lock; - spin_unlock_irqrestore(&dev->lock.spinlock, - irqflags); + spin_unlock_bh(&dev->lock.spinlock); if (locked) break; schedule(); diff --git a/drivers/char/drm/drm_irq.c b/drivers/char/drm/drm_irq.c index 286f9d61e7d5df50e89f05985c20e246cbeacba9..089c015c01d148234fcd24abac9f935c9fd185ef 100644 --- a/drivers/char/drm/drm_irq.c +++ b/drivers/char/drm/drm_irq.c @@ -71,117 +71,6 @@ int drm_irq_by_busid(struct drm_device *dev, void *data, return 0; } -static void vblank_disable_fn(unsigned long arg) -{ - struct drm_device *dev = (struct drm_device *)arg; - unsigned long irqflags; - int i; - - for (i = 0; i < dev->num_crtcs; i++) { - spin_lock_irqsave(&dev->vbl_lock, irqflags); - if (atomic_read(&dev->vblank_refcount[i]) == 0 && - dev->vblank_enabled[i]) { - dev->driver->disable_vblank(dev, i); - dev->vblank_enabled[i] = 0; - } - spin_unlock_irqrestore(&dev->vbl_lock, irqflags); - } -} - -static void drm_vblank_cleanup(struct drm_device *dev) -{ - /* Bail if the driver didn't call drm_vblank_init() */ - if (dev->num_crtcs == 0) - return; - - del_timer(&dev->vblank_disable_timer); - - vblank_disable_fn((unsigned long)dev); - - drm_free(dev->vbl_queue, sizeof(*dev->vbl_queue) * dev->num_crtcs, - DRM_MEM_DRIVER); - drm_free(dev->vbl_sigs, sizeof(*dev->vbl_sigs) * dev->num_crtcs, - DRM_MEM_DRIVER); - drm_free(dev->_vblank_count, sizeof(*dev->_vblank_count) * - dev->num_crtcs, DRM_MEM_DRIVER); - drm_free(dev->vblank_refcount, sizeof(*dev->vblank_refcount) * - dev->num_crtcs, DRM_MEM_DRIVER); - drm_free(dev->vblank_enabled, sizeof(*dev->vblank_enabled) * - dev->num_crtcs, DRM_MEM_DRIVER); - drm_free(dev->last_vblank, sizeof(*dev->last_vblank) * dev->num_crtcs, - DRM_MEM_DRIVER); - drm_free(dev->vblank_premodeset, sizeof(*dev->vblank_premodeset) * - dev->num_crtcs, DRM_MEM_DRIVER); - drm_free(dev->vblank_offset, sizeof(*dev->vblank_offset) * dev->num_crtcs, - DRM_MEM_DRIVER); - - dev->num_crtcs = 0; -} - -int drm_vblank_init(struct drm_device *dev, int num_crtcs) -{ - int i, ret = -ENOMEM; - - setup_timer(&dev->vblank_disable_timer, vblank_disable_fn, - (unsigned long)dev); - spin_lock_init(&dev->vbl_lock); - atomic_set(&dev->vbl_signal_pending, 0); - dev->num_crtcs = num_crtcs; - - dev->vbl_queue = drm_alloc(sizeof(wait_queue_head_t) * num_crtcs, - DRM_MEM_DRIVER); - if (!dev->vbl_queue) - goto err; - - dev->vbl_sigs = drm_alloc(sizeof(struct list_head) * num_crtcs, - DRM_MEM_DRIVER); - if (!dev->vbl_sigs) - goto err; - - dev->_vblank_count = drm_alloc(sizeof(atomic_t) * num_crtcs, - DRM_MEM_DRIVER); - if (!dev->_vblank_count) - goto err; - - dev->vblank_refcount = drm_alloc(sizeof(atomic_t) * num_crtcs, - DRM_MEM_DRIVER); - if (!dev->vblank_refcount) - goto err; - - dev->vblank_enabled = drm_calloc(num_crtcs, sizeof(int), - DRM_MEM_DRIVER); - if (!dev->vblank_enabled) - goto err; - - dev->last_vblank = drm_calloc(num_crtcs, sizeof(u32), DRM_MEM_DRIVER); - if (!dev->last_vblank) - goto err; - - dev->vblank_premodeset = drm_calloc(num_crtcs, sizeof(u32), - DRM_MEM_DRIVER); - if (!dev->vblank_premodeset) - goto err; - - dev->vblank_offset = drm_calloc(num_crtcs, sizeof(u32), DRM_MEM_DRIVER); - if (!dev->vblank_offset) - goto err; - - /* Zero per-crtc vblank stuff */ - for (i = 0; i < num_crtcs; i++) { - init_waitqueue_head(&dev->vbl_queue[i]); - INIT_LIST_HEAD(&dev->vbl_sigs[i]); - atomic_set(&dev->_vblank_count[i], 0); - atomic_set(&dev->vblank_refcount[i], 0); - } - - return 0; - -err: - drm_vblank_cleanup(dev); - return ret; -} -EXPORT_SYMBOL(drm_vblank_init); - /** * Install IRQ handler. * @@ -220,6 +109,17 @@ static int drm_irq_install(struct drm_device * dev) DRM_DEBUG("irq=%d\n", dev->irq); + if (drm_core_check_feature(dev, DRIVER_IRQ_VBL)) { + init_waitqueue_head(&dev->vbl_queue); + + spin_lock_init(&dev->vbl_lock); + + INIT_LIST_HEAD(&dev->vbl_sigs); + INIT_LIST_HEAD(&dev->vbl_sigs2); + + dev->vbl_pending = 0; + } + /* Before installing handler */ dev->driver->irq_preinstall(dev); @@ -237,14 +137,9 @@ static int drm_irq_install(struct drm_device * dev) } /* After installing handler */ - ret = dev->driver->irq_postinstall(dev); - if (ret < 0) { - mutex_lock(&dev->struct_mutex); - dev->irq_enabled = 0; - mutex_unlock(&dev->struct_mutex); - } + dev->driver->irq_postinstall(dev); - return ret; + return 0; } /** @@ -275,8 +170,6 @@ int drm_irq_uninstall(struct drm_device * dev) free_irq(dev->irq, dev); - drm_vblank_cleanup(dev); - dev->locked_tasklet_func = NULL; return 0; @@ -320,148 +213,6 @@ int drm_control(struct drm_device *dev, void *data, } } -/** - * drm_vblank_count - retrieve "cooked" vblank counter value - * @dev: DRM device - * @crtc: which counter to retrieve - * - * Fetches the "cooked" vblank count value that represents the number of - * vblank events since the system was booted, including lost events due to - * modesetting activity. - */ -u32 drm_vblank_count(struct drm_device *dev, int crtc) -{ - return atomic_read(&dev->_vblank_count[crtc]) + - dev->vblank_offset[crtc]; -} -EXPORT_SYMBOL(drm_vblank_count); - -/** - * drm_update_vblank_count - update the master vblank counter - * @dev: DRM device - * @crtc: counter to update - * - * Call back into the driver to update the appropriate vblank counter - * (specified by @crtc). Deal with wraparound, if it occurred, and - * update the last read value so we can deal with wraparound on the next - * call if necessary. - */ -void drm_update_vblank_count(struct drm_device *dev, int crtc) -{ - unsigned long irqflags; - u32 cur_vblank, diff; - - /* - * Interrupts were disabled prior to this call, so deal with counter - * wrap if needed. - * NOTE! It's possible we lost a full dev->max_vblank_count events - * here if the register is small or we had vblank interrupts off for - * a long time. - */ - cur_vblank = dev->driver->get_vblank_counter(dev, crtc); - spin_lock_irqsave(&dev->vbl_lock, irqflags); - if (cur_vblank < dev->last_vblank[crtc]) { - diff = dev->max_vblank_count - - dev->last_vblank[crtc]; - diff += cur_vblank; - } else { - diff = cur_vblank - dev->last_vblank[crtc]; - } - dev->last_vblank[crtc] = cur_vblank; - spin_unlock_irqrestore(&dev->vbl_lock, irqflags); - - atomic_add(diff, &dev->_vblank_count[crtc]); -} -EXPORT_SYMBOL(drm_update_vblank_count); - -/** - * drm_vblank_get - get a reference count on vblank events - * @dev: DRM device - * @crtc: which CRTC to own - * - * Acquire a reference count on vblank events to avoid having them disabled - * while in use. Note callers will probably want to update the master counter - * using drm_update_vblank_count() above before calling this routine so that - * wakeups occur on the right vblank event. - * - * RETURNS - * Zero on success, nonzero on failure. - */ -int drm_vblank_get(struct drm_device *dev, int crtc) -{ - unsigned long irqflags; - int ret = 0; - - spin_lock_irqsave(&dev->vbl_lock, irqflags); - /* Going from 0->1 means we have to enable interrupts again */ - if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1 && - !dev->vblank_enabled[crtc]) { - ret = dev->driver->enable_vblank(dev, crtc); - if (ret) - atomic_dec(&dev->vblank_refcount[crtc]); - else - dev->vblank_enabled[crtc] = 1; - } - spin_unlock_irqrestore(&dev->vbl_lock, irqflags); - - return ret; -} -EXPORT_SYMBOL(drm_vblank_get); - -/** - * drm_vblank_put - give up ownership of vblank events - * @dev: DRM device - * @crtc: which counter to give up - * - * Release ownership of a given vblank counter, turning off interrupts - * if possible. - */ -void drm_vblank_put(struct drm_device *dev, int crtc) -{ - /* Last user schedules interrupt disable */ - if (atomic_dec_and_test(&dev->vblank_refcount[crtc])) - mod_timer(&dev->vblank_disable_timer, jiffies + 5*DRM_HZ); -} -EXPORT_SYMBOL(drm_vblank_put); - -/** - * drm_modeset_ctl - handle vblank event counter changes across mode switch - * @DRM_IOCTL_ARGS: standard ioctl arguments - * - * Applications should call the %_DRM_PRE_MODESET and %_DRM_POST_MODESET - * ioctls around modesetting so that any lost vblank events are accounted for. - */ -int drm_modeset_ctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_modeset_ctl *modeset = data; - int crtc, ret = 0; - u32 new; - - crtc = modeset->arg; - if (crtc >= dev->num_crtcs) { - ret = -EINVAL; - goto out; - } - - switch (modeset->cmd) { - case _DRM_PRE_MODESET: - dev->vblank_premodeset[crtc] = - dev->driver->get_vblank_counter(dev, crtc); - break; - case _DRM_POST_MODESET: - new = dev->driver->get_vblank_counter(dev, crtc); - dev->vblank_offset[crtc] = dev->vblank_premodeset[crtc] - new; - break; - default: - ret = -EINVAL; - break; - } - -out: - return ret; -} - /** * Wait for VBLANK. * @@ -481,13 +232,12 @@ out: * * If a signal is not requested, then calls vblank_wait(). */ -int drm_wait_vblank(struct drm_device *dev, void *data, - struct drm_file *file_priv) +int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_priv) { union drm_wait_vblank *vblwait = data; struct timeval now; int ret = 0; - unsigned int flags, seq, crtc; + unsigned int flags, seq; if ((!dev->irq) || (!dev->irq_enabled)) return -EINVAL; @@ -501,13 +251,13 @@ int drm_wait_vblank(struct drm_device *dev, void *data, } flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK; - crtc = flags & _DRM_VBLANK_SECONDARY ? 1 : 0; - if (crtc >= dev->num_crtcs) + if (!drm_core_check_feature(dev, (flags & _DRM_VBLANK_SECONDARY) ? + DRIVER_IRQ_VBL2 : DRIVER_IRQ_VBL)) return -EINVAL; - drm_update_vblank_count(dev, crtc); - seq = drm_vblank_count(dev, crtc); + seq = atomic_read((flags & _DRM_VBLANK_SECONDARY) ? &dev->vbl_received2 + : &dev->vbl_received); switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) { case _DRM_VBLANK_RELATIVE: @@ -526,7 +276,8 @@ int drm_wait_vblank(struct drm_device *dev, void *data, if (flags & _DRM_VBLANK_SIGNAL) { unsigned long irqflags; - struct list_head *vbl_sigs = &dev->vbl_sigs[crtc]; + struct list_head *vbl_sigs = (flags & _DRM_VBLANK_SECONDARY) + ? &dev->vbl_sigs2 : &dev->vbl_sigs; struct drm_vbl_sig *vbl_sig; spin_lock_irqsave(&dev->vbl_lock, irqflags); @@ -547,26 +298,22 @@ int drm_wait_vblank(struct drm_device *dev, void *data, } } - if (atomic_read(&dev->vbl_signal_pending) >= 100) { + if (dev->vbl_pending >= 100) { spin_unlock_irqrestore(&dev->vbl_lock, irqflags); return -EBUSY; } + dev->vbl_pending++; + spin_unlock_irqrestore(&dev->vbl_lock, irqflags); - vbl_sig = drm_calloc(1, sizeof(struct drm_vbl_sig), - DRM_MEM_DRIVER); - if (!vbl_sig) + if (! + (vbl_sig = + drm_alloc(sizeof(struct drm_vbl_sig), DRM_MEM_DRIVER))) { return -ENOMEM; - - ret = drm_vblank_get(dev, crtc); - if (ret) { - drm_free(vbl_sig, sizeof(struct drm_vbl_sig), - DRM_MEM_DRIVER); - return ret; } - atomic_inc(&dev->vbl_signal_pending); + memset((void *)vbl_sig, 0, sizeof(*vbl_sig)); vbl_sig->sequence = vblwait->request.sequence; vbl_sig->info.si_signo = vblwait->request.signal; @@ -580,20 +327,17 @@ int drm_wait_vblank(struct drm_device *dev, void *data, vblwait->reply.sequence = seq; } else { - unsigned long cur_vblank; - - ret = drm_vblank_get(dev, crtc); - if (ret) - return ret; - DRM_WAIT_ON(ret, dev->vbl_queue[crtc], 3 * DRM_HZ, - (((cur_vblank = drm_vblank_count(dev, crtc)) - - vblwait->request.sequence) <= (1 << 23))); - drm_vblank_put(dev, crtc); - do_gettimeofday(&now); + if (flags & _DRM_VBLANK_SECONDARY) { + if (dev->driver->vblank_wait2) + ret = dev->driver->vblank_wait2(dev, &vblwait->request.sequence); + } else if (dev->driver->vblank_wait) + ret = + dev->driver->vblank_wait(dev, + &vblwait->request.sequence); + do_gettimeofday(&now); vblwait->reply.tval_sec = now.tv_sec; vblwait->reply.tval_usec = now.tv_usec; - vblwait->reply.sequence = cur_vblank; } done: @@ -604,57 +348,44 @@ int drm_wait_vblank(struct drm_device *dev, void *data, * Send the VBLANK signals. * * \param dev DRM device. - * \param crtc CRTC where the vblank event occurred * * Sends a signal for each task in drm_device::vbl_sigs and empties the list. * * If a signal is not requested, then calls vblank_wait(). */ -static void drm_vbl_send_signals(struct drm_device * dev, int crtc) +void drm_vbl_send_signals(struct drm_device * dev) { - struct drm_vbl_sig *vbl_sig, *tmp; - struct list_head *vbl_sigs; - unsigned int vbl_seq; unsigned long flags; + int i; spin_lock_irqsave(&dev->vbl_lock, flags); - vbl_sigs = &dev->vbl_sigs[crtc]; - vbl_seq = drm_vblank_count(dev, crtc); + for (i = 0; i < 2; i++) { + struct drm_vbl_sig *vbl_sig, *tmp; + struct list_head *vbl_sigs = i ? &dev->vbl_sigs2 : &dev->vbl_sigs; + unsigned int vbl_seq = atomic_read(i ? &dev->vbl_received2 : + &dev->vbl_received); - list_for_each_entry_safe(vbl_sig, tmp, vbl_sigs, head) { - if ((vbl_seq - vbl_sig->sequence) <= (1 << 23)) { - vbl_sig->info.si_code = vbl_seq; - send_sig_info(vbl_sig->info.si_signo, - &vbl_sig->info, vbl_sig->task); + list_for_each_entry_safe(vbl_sig, tmp, vbl_sigs, head) { + if ((vbl_seq - vbl_sig->sequence) <= (1 << 23)) { + vbl_sig->info.si_code = vbl_seq; + send_sig_info(vbl_sig->info.si_signo, + &vbl_sig->info, vbl_sig->task); - list_del(&vbl_sig->head); + list_del(&vbl_sig->head); - drm_free(vbl_sig, sizeof(*vbl_sig), - DRM_MEM_DRIVER); - atomic_dec(&dev->vbl_signal_pending); - drm_vblank_put(dev, crtc); - } + drm_free(vbl_sig, sizeof(*vbl_sig), + DRM_MEM_DRIVER); + + dev->vbl_pending--; + } + } } spin_unlock_irqrestore(&dev->vbl_lock, flags); } -/** - * drm_handle_vblank - handle a vblank event - * @dev: DRM device - * @crtc: where this event occurred - * - * Drivers should call this routine in their vblank interrupt handlers to - * update the vblank counter and send any signals that may be pending. - */ -void drm_handle_vblank(struct drm_device *dev, int crtc) -{ - drm_update_vblank_count(dev, crtc); - DRM_WAKEUP(&dev->vbl_queue[crtc]); - drm_vbl_send_signals(dev, crtc); -} -EXPORT_SYMBOL(drm_handle_vblank); +EXPORT_SYMBOL(drm_vbl_send_signals); /** * Tasklet wrapper function. diff --git a/drivers/char/drm/drm_lock.c b/drivers/char/drm/drm_lock.c index 12dcdd1832f080b57574d02ecd4acfc6076ecd88..0998723cde7925b4c9988836b15ddd10e1566820 100644 --- a/drivers/char/drm/drm_lock.c +++ b/drivers/char/drm/drm_lock.c @@ -53,7 +53,6 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv) DECLARE_WAITQUEUE(entry, current); struct drm_lock *lock = data; int ret = 0; - unsigned long irqflags; ++file_priv->lock_count; @@ -72,9 +71,9 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv) return -EINVAL; add_wait_queue(&dev->lock.lock_queue, &entry); - spin_lock_irqsave(&dev->lock.spinlock, irqflags); + spin_lock_bh(&dev->lock.spinlock); dev->lock.user_waiters++; - spin_unlock_irqrestore(&dev->lock.spinlock, irqflags); + spin_unlock_bh(&dev->lock.spinlock); for (;;) { __set_current_state(TASK_INTERRUPTIBLE); if (!dev->lock.hw_lock) { @@ -96,9 +95,9 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv) break; } } - spin_lock_irqsave(&dev->lock.spinlock, irqflags); + spin_lock_bh(&dev->lock.spinlock); dev->lock.user_waiters--; - spin_unlock_irqrestore(&dev->lock.spinlock, irqflags); + spin_unlock_bh(&dev->lock.spinlock); __set_current_state(TASK_RUNNING); remove_wait_queue(&dev->lock.lock_queue, &entry); @@ -199,9 +198,8 @@ int drm_lock_take(struct drm_lock_data *lock_data, { unsigned int old, new, prev; volatile unsigned int *lock = &lock_data->hw_lock->lock; - unsigned long irqflags; - spin_lock_irqsave(&lock_data->spinlock, irqflags); + spin_lock_bh(&lock_data->spinlock); do { old = *lock; if (old & _DRM_LOCK_HELD) @@ -213,7 +211,7 @@ int drm_lock_take(struct drm_lock_data *lock_data, } prev = cmpxchg(lock, old, new); } while (prev != old); - spin_unlock_irqrestore(&lock_data->spinlock, irqflags); + spin_unlock_bh(&lock_data->spinlock); if (_DRM_LOCKING_CONTEXT(old) == context) { if (old & _DRM_LOCK_HELD) { @@ -274,16 +272,15 @@ int drm_lock_free(struct drm_lock_data *lock_data, unsigned int context) { unsigned int old, new, prev; volatile unsigned int *lock = &lock_data->hw_lock->lock; - unsigned long irqflags; - spin_lock_irqsave(&lock_data->spinlock, irqflags); + spin_lock_bh(&lock_data->spinlock); if (lock_data->kernel_waiters != 0) { drm_lock_transfer(lock_data, 0); lock_data->idle_has_lock = 1; - spin_unlock_irqrestore(&lock_data->spinlock, irqflags); + spin_unlock_bh(&lock_data->spinlock); return 1; } - spin_unlock_irqrestore(&lock_data->spinlock, irqflags); + spin_unlock_bh(&lock_data->spinlock); do { old = *lock; @@ -347,20 +344,19 @@ static int drm_notifier(void *priv) void drm_idlelock_take(struct drm_lock_data *lock_data) { int ret = 0; - unsigned long irqflags; - spin_lock_irqsave(&lock_data->spinlock, irqflags); + spin_lock_bh(&lock_data->spinlock); lock_data->kernel_waiters++; if (!lock_data->idle_has_lock) { - spin_unlock_irqrestore(&lock_data->spinlock, irqflags); + spin_unlock_bh(&lock_data->spinlock); ret = drm_lock_take(lock_data, DRM_KERNEL_CONTEXT); - spin_lock_irqsave(&lock_data->spinlock, irqflags); + spin_lock_bh(&lock_data->spinlock); if (ret == 1) lock_data->idle_has_lock = 1; } - spin_unlock_irqrestore(&lock_data->spinlock, irqflags); + spin_unlock_bh(&lock_data->spinlock); } EXPORT_SYMBOL(drm_idlelock_take); @@ -368,9 +364,8 @@ void drm_idlelock_release(struct drm_lock_data *lock_data) { unsigned int old, prev; volatile unsigned int *lock = &lock_data->hw_lock->lock; - unsigned long irqflags; - spin_lock_irqsave(&lock_data->spinlock, irqflags); + spin_lock_bh(&lock_data->spinlock); if (--lock_data->kernel_waiters == 0) { if (lock_data->idle_has_lock) { do { @@ -381,7 +376,7 @@ void drm_idlelock_release(struct drm_lock_data *lock_data) lock_data->idle_has_lock = 0; } } - spin_unlock_irqrestore(&lock_data->spinlock, irqflags); + spin_unlock_bh(&lock_data->spinlock); } EXPORT_SYMBOL(drm_idlelock_release); diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c index f47e46e3529fae1ef0be1049205de3f245210a49..88974342933c62f253d7406c33989b152014b8b8 100644 --- a/drivers/char/drm/i915_dma.c +++ b/drivers/char/drm/i915_dma.c @@ -415,13 +415,10 @@ static void i915_emit_breadcrumb(struct drm_device *dev) drm_i915_private_t *dev_priv = dev->dev_private; RING_LOCALS; - if (++dev_priv->counter > BREADCRUMB_MASK) { - dev_priv->counter = 1; - DRM_DEBUG("Breadcrumb counter wrapped around\n"); - } + dev_priv->sarea_priv->last_enqueue = ++dev_priv->counter; - if (dev_priv->sarea_priv) - dev_priv->sarea_priv->last_enqueue = dev_priv->counter; + if (dev_priv->counter > 0x7FFFFFFFUL) + dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1; BEGIN_LP_RING(4); OUT_RING(CMD_STORE_DWORD_IDX); @@ -431,26 +428,6 @@ static void i915_emit_breadcrumb(struct drm_device *dev) ADVANCE_LP_RING(); } -int i915_emit_mi_flush(struct drm_device *dev, uint32_t flush) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - uint32_t flush_cmd = CMD_MI_FLUSH; - RING_LOCALS; - - flush_cmd |= flush; - - i915_kernel_lost_context(dev); - - BEGIN_LP_RING(4); - OUT_RING(flush_cmd); - OUT_RING(0); - OUT_RING(0); - OUT_RING(0); - ADVANCE_LP_RING(); - - return 0; -} - static int i915_dispatch_cmdbuffer(struct drm_device * dev, drm_i915_cmdbuffer_t * cmd) { @@ -534,74 +511,52 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev, return 0; } -static void i915_do_dispatch_flip(struct drm_device * dev, int plane, int sync) +static int i915_dispatch_flip(struct drm_device * dev) { drm_i915_private_t *dev_priv = dev->dev_private; - u32 num_pages, current_page, next_page, dspbase; - int shift = 2 * plane, x, y; RING_LOCALS; - /* Calculate display base offset */ - num_pages = dev_priv->sarea_priv->third_handle ? 3 : 2; - current_page = (dev_priv->sarea_priv->pf_current_page >> shift) & 0x3; - next_page = (current_page + 1) % num_pages; + DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n", + __FUNCTION__, + dev_priv->current_page, + dev_priv->sarea_priv->pf_current_page); - switch (next_page) { - default: - case 0: - dspbase = dev_priv->sarea_priv->front_offset; - break; - case 1: - dspbase = dev_priv->sarea_priv->back_offset; - break; - case 2: - dspbase = dev_priv->sarea_priv->third_offset; - break; - } + i915_kernel_lost_context(dev); + + BEGIN_LP_RING(2); + OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE); + OUT_RING(0); + ADVANCE_LP_RING(); - if (plane == 0) { - x = dev_priv->sarea_priv->planeA_x; - y = dev_priv->sarea_priv->planeA_y; + BEGIN_LP_RING(6); + OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP); + OUT_RING(0); + if (dev_priv->current_page == 0) { + OUT_RING(dev_priv->back_offset); + dev_priv->current_page = 1; } else { - x = dev_priv->sarea_priv->planeB_x; - y = dev_priv->sarea_priv->planeB_y; + OUT_RING(dev_priv->front_offset); + dev_priv->current_page = 0; } + OUT_RING(0); + ADVANCE_LP_RING(); - dspbase += (y * dev_priv->sarea_priv->pitch + x) * dev_priv->cpp; + BEGIN_LP_RING(2); + OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_A_FLIP); + OUT_RING(0); + ADVANCE_LP_RING(); - DRM_DEBUG("plane=%d current_page=%d dspbase=0x%x\n", plane, current_page, - dspbase); + dev_priv->sarea_priv->last_enqueue = dev_priv->counter++; BEGIN_LP_RING(4); - OUT_RING(sync ? 0 : - (MI_WAIT_FOR_EVENT | (plane ? MI_WAIT_FOR_PLANE_B_FLIP : - MI_WAIT_FOR_PLANE_A_FLIP))); - OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | (sync ? 0 : ASYNC_FLIP) | - (plane ? DISPLAY_PLANE_B : DISPLAY_PLANE_A)); - OUT_RING(dev_priv->sarea_priv->pitch * dev_priv->cpp); - OUT_RING(dspbase); + OUT_RING(CMD_STORE_DWORD_IDX); + OUT_RING(20); + OUT_RING(dev_priv->counter); + OUT_RING(0); ADVANCE_LP_RING(); - dev_priv->sarea_priv->pf_current_page &= ~(0x3 << shift); - dev_priv->sarea_priv->pf_current_page |= next_page << shift; -} - -void i915_dispatch_flip(struct drm_device * dev, int planes, int sync) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - int i; - - DRM_DEBUG("planes=0x%x pfCurrentPage=%d\n", - planes, dev_priv->sarea_priv->pf_current_page); - - i915_emit_mi_flush(dev, MI_READ_FLUSH | MI_EXE_FLUSH); - - for (i = 0; i < 2; i++) - if (planes & (1 << i)) - i915_do_dispatch_flip(dev, i, sync); - - i915_emit_breadcrumb(dev); - + dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; + return 0; } static int i915_quiescent(struct drm_device * dev) @@ -624,6 +579,7 @@ static int i915_batchbuffer(struct drm_device *dev, void *data, struct drm_file *file_priv) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + u32 *hw_status = dev_priv->hw_status_page; drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) dev_priv->sarea_priv; drm_i915_batchbuffer_t *batch = data; @@ -646,7 +602,7 @@ static int i915_batchbuffer(struct drm_device *dev, void *data, ret = i915_dispatch_batchbuffer(dev, batch); - sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); + sarea_priv->last_dispatch = (int)hw_status[5]; return ret; } @@ -654,6 +610,7 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data, struct drm_file *file_priv) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + u32 *hw_status = dev_priv->hw_status_page; drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) dev_priv->sarea_priv; drm_i915_cmdbuffer_t *cmdbuf = data; @@ -678,51 +635,18 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data, return ret; } - sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); - return 0; -} - -static int i915_do_cleanup_pageflip(struct drm_device * dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - int i, planes, num_pages = dev_priv->sarea_priv->third_handle ? 3 : 2; - - DRM_DEBUG("\n"); - - for (i = 0, planes = 0; i < 2; i++) - if (dev_priv->sarea_priv->pf_current_page & (0x3 << (2 * i))) { - dev_priv->sarea_priv->pf_current_page = - (dev_priv->sarea_priv->pf_current_page & - ~(0x3 << (2 * i))) | ((num_pages - 1) << (2 * i)); - - planes |= 1 << i; - } - - if (planes) - i915_dispatch_flip(dev, planes, 0); - + sarea_priv->last_dispatch = (int)hw_status[5]; return 0; } static int i915_flip_bufs(struct drm_device *dev, void *data, struct drm_file *file_priv) { - drm_i915_flip_t *param = data; - - DRM_DEBUG("\n"); + DRM_DEBUG("%s\n", __FUNCTION__); LOCK_TEST_WITH_RETURN(dev, file_priv); - /* This is really planes */ - if (param->pipes & ~0x3) { - DRM_ERROR("Invalid planes 0x%x, only <= 0x3 is valid\n", - param->pipes); - return -EINVAL; - } - - i915_dispatch_flip(dev, param->pipes, 0); - - return 0; + return i915_dispatch_flip(dev); } static int i915_getparam(struct drm_device *dev, void *data, @@ -883,8 +807,6 @@ void i915_driver_lastclose(struct drm_device * dev) if (!dev_priv) return; - if (drm_getsarea(dev) && dev_priv->sarea_priv) - i915_do_cleanup_pageflip(dev); if (dev_priv->agp_heap) i915_mem_takedown(&(dev_priv->agp_heap)); diff --git a/drivers/char/drm/i915_drm.h b/drivers/char/drm/i915_drm.h index 0431c00e2289b6e6fcf03db0c2e8d7c1107e3238..05c66cf03a9eb02a0da22304ab4d07d95209b16b 100644 --- a/drivers/char/drm/i915_drm.h +++ b/drivers/char/drm/i915_drm.h @@ -105,29 +105,14 @@ typedef struct _drm_i915_sarea { unsigned int rotated_tiled; unsigned int rotated2_tiled; - int planeA_x; - int planeA_y; - int planeA_w; - int planeA_h; - int planeB_x; - int planeB_y; - int planeB_w; - int planeB_h; - - /* Triple buffering */ - drm_handle_t third_handle; - int third_offset; - int third_size; - unsigned int third_tiled; - - /* buffer object handles for the static buffers. May change - * over the lifetime of the client, though it doesn't in our current - * implementation. - */ - unsigned int front_bo_handle; - unsigned int back_bo_handle; - unsigned int third_bo_handle; - unsigned int depth_bo_handle; + int pipeA_x; + int pipeA_y; + int pipeA_w; + int pipeA_h; + int pipeB_x; + int pipeB_y; + int pipeB_w; + int pipeB_h; } drm_i915_sarea_t; /* Flags for perf_boxes @@ -161,7 +146,7 @@ typedef struct _drm_i915_sarea { #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) -#define DRM_IOCTL_I915_FLIP DRM_IOW( DRM_COMMAND_BASE + DRM_I915_FLIP, drm_i915_flip_t) +#define DRM_IOCTL_I915_FLIP DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLIP) #define DRM_IOCTL_I915_BATCHBUFFER DRM_IOW( DRM_COMMAND_BASE + DRM_I915_BATCHBUFFER, drm_i915_batchbuffer_t) #define DRM_IOCTL_I915_IRQ_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_IRQ_EMIT, drm_i915_irq_emit_t) #define DRM_IOCTL_I915_IRQ_WAIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_IRQ_WAIT, drm_i915_irq_wait_t) @@ -176,18 +161,6 @@ typedef struct _drm_i915_sarea { #define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t) #define DRM_IOCTL_I915_VBLANK_SWAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t) -/* Asynchronous page flipping: - */ -typedef struct drm_i915_flip { - /* - * This is really talking about planes, and we could rename it - * except for the fact that some of the duplicated i915_drm.h files - * out there check for HAVE_I915_FLIP and so might pick up this - * version. - */ - int pipes; -} drm_i915_flip_t; - /* Allow drivers to submit batchbuffers directly to hardware, relying * on the security mechanisms provided by hardware. */ diff --git a/drivers/char/drm/i915_drv.c b/drivers/char/drm/i915_drv.c index bb8f1b2fb3835588026e00d1f961663e08e6c910..e8f3d682e3b139331c1213a0687c1fc9a2cac40d 100644 --- a/drivers/char/drm/i915_drv.c +++ b/drivers/char/drm/i915_drv.c @@ -147,7 +147,7 @@ static void i915_save_vga(struct drm_device *dev) i915_write_indexed(cr_index, cr_data, 0x11, i915_read_indexed(cr_index, cr_data, 0x11) & (~0x80)); - for (i = 0; i < 0x24; i++) + for (i = 0; i <= 0x24; i++) dev_priv->saveCR[i] = i915_read_indexed(cr_index, cr_data, i); /* Make sure we don't turn off CR group 0 writes */ @@ -156,7 +156,7 @@ static void i915_save_vga(struct drm_device *dev) /* Attribute controller registers */ inb(st01); dev_priv->saveAR_INDEX = inb(VGA_AR_INDEX); - for (i = 0; i < 20; i++) + for (i = 0; i <= 0x14; i++) dev_priv->saveAR[i] = i915_read_ar(st01, i, 0); inb(st01); outb(dev_priv->saveAR_INDEX, VGA_AR_INDEX); @@ -206,7 +206,7 @@ static void i915_restore_vga(struct drm_device *dev) /* CRT controller regs */ /* Enable CR group 0 writes */ i915_write_indexed(cr_index, cr_data, 0x11, dev_priv->saveCR[0x11]); - for (i = 0; i < 0x24; i++) + for (i = 0; i <= 0x24; i++) i915_write_indexed(cr_index, cr_data, i, dev_priv->saveCR[i]); /* Graphics controller regs */ @@ -223,7 +223,7 @@ static void i915_restore_vga(struct drm_device *dev) /* Attribute controller registers */ inb(st01); - for (i = 0; i < 20; i++) + for (i = 0; i <= 0x14; i++) i915_write_ar(st01, i, dev_priv->saveAR[i], 0); inb(st01); /* switch back to index mode */ outb(dev_priv->saveAR_INDEX | 0x20, VGA_AR_INDEX); @@ -256,6 +256,9 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state) pci_save_state(dev->pdev); pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); + /* Display arbitration control */ + dev_priv->saveDSPARB = I915_READ(DSPARB); + /* Pipe & plane A info */ dev_priv->savePIPEACONF = I915_READ(PIPEACONF); dev_priv->savePIPEASRC = I915_READ(PIPEASRC); @@ -349,6 +352,7 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state) dev_priv->saveVGACNTRL = I915_READ(VGACNTRL); /* Clock gating state */ + dev_priv->saveD_STATE = I915_READ(D_STATE); dev_priv->saveDSPCLK_GATE_D = I915_READ(DSPCLK_GATE_D); /* Cache mode state */ @@ -388,6 +392,8 @@ static int i915_resume(struct drm_device *dev) pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB); + I915_WRITE(DSPARB, dev_priv->saveDSPARB); + /* Pipe & plane A info */ /* Prime the clock */ if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { @@ -507,6 +513,7 @@ static int i915_resume(struct drm_device *dev) udelay(150); /* Clock gating state */ + I915_WRITE (D_STATE, dev_priv->saveD_STATE); I915_WRITE (DSPCLK_GATE_D, dev_priv->saveDSPCLK_GATE_D); /* Cache mode state */ @@ -533,7 +540,8 @@ static struct drm_driver driver = { */ .driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/ - DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, + DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL | + DRIVER_IRQ_VBL2, .load = i915_driver_load, .unload = i915_driver_unload, .lastclose = i915_driver_lastclose, @@ -541,9 +549,8 @@ static struct drm_driver driver = { .suspend = i915_suspend, .resume = i915_resume, .device_is_agp = i915_driver_device_is_agp, - .get_vblank_counter = i915_get_vblank_counter, - .enable_vblank = i915_enable_vblank, - .disable_vblank = i915_disable_vblank, + .vblank_wait = i915_driver_vblank_wait, + .vblank_wait2 = i915_driver_vblank_wait2, .irq_preinstall = i915_driver_irq_preinstall, .irq_postinstall = i915_driver_irq_postinstall, .irq_uninstall = i915_driver_irq_uninstall, diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h index db7001f22561f6ea1a1f745b512e4bf51fd6e8c7..1b20f7c0639c24074cae6412e02ed605e51595a8 100644 --- a/drivers/char/drm/i915_drv.h +++ b/drivers/char/drm/i915_drv.h @@ -76,9 +76,8 @@ struct mem_block { typedef struct _drm_i915_vbl_swap { struct list_head head; drm_drawable_t drw_id; - unsigned int plane; + unsigned int pipe; unsigned int sequence; - int flip; } drm_i915_vbl_swap_t; typedef struct drm_i915_private { @@ -91,7 +90,7 @@ typedef struct drm_i915_private { drm_dma_handle_t *status_page_dmah; void *hw_status_page; dma_addr_t dma_status_page; - uint32_t counter; + unsigned long counter; unsigned int status_gfx_addr; drm_local_map_t hws_map; @@ -104,18 +103,13 @@ typedef struct drm_i915_private { wait_queue_head_t irq_queue; atomic_t irq_received; - atomic_t irq_emited; + atomic_t irq_emitted; int tex_lru_log_granularity; int allow_batchbuffer; struct mem_block *agp_heap; unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds; int vblank_pipe; - spinlock_t user_irq_lock; - int user_irq_refcount; - int fence_irq_on; - uint32_t irq_enable_reg; - int irq_enabled; spinlock_t swaps_lock; drm_i915_vbl_swap_t vbl_swaps; @@ -125,6 +119,7 @@ typedef struct drm_i915_private { u8 saveLBB; u32 saveDSPACNTR; u32 saveDSPBCNTR; + u32 saveDSPARB; u32 savePIPEACONF; u32 savePIPEBCONF; u32 savePIPEASRC; @@ -194,6 +189,7 @@ typedef struct drm_i915_private { u32 saveIIR; u32 saveIMR; u32 saveCACHE_MODE_0; + u32 saveD_STATE; u32 saveDSPCLK_GATE_D; u32 saveMI_ARB_STATE; u32 saveSWF0[16]; @@ -203,10 +199,10 @@ typedef struct drm_i915_private { u8 saveSR[8]; u8 saveGR[25]; u8 saveAR_INDEX; - u8 saveAR[20]; + u8 saveAR[21]; u8 saveDACMASK; u8 saveDACDATA[256*3]; /* 256 3-byte colors */ - u8 saveCR[36]; + u8 saveCR[37]; } drm_i915_private_t; extern struct drm_ioctl_desc i915_ioctls[]; @@ -222,7 +218,7 @@ extern void i915_driver_preclose(struct drm_device *dev, extern int i915_driver_device_is_agp(struct drm_device * dev); extern long i915_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); -extern void i915_dispatch_flip(struct drm_device * dev, int pipes, int sync); + /* i915_irq.c */ extern int i915_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv); @@ -233,7 +229,7 @@ extern int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequenc extern int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence); extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS); extern void i915_driver_irq_preinstall(struct drm_device * dev); -extern int i915_driver_irq_postinstall(struct drm_device * dev); +extern void i915_driver_irq_postinstall(struct drm_device * dev); extern void i915_driver_irq_uninstall(struct drm_device * dev); extern int i915_vblank_pipe_set(struct drm_device *dev, void *data, struct drm_file *file_priv); @@ -241,9 +237,6 @@ extern int i915_vblank_pipe_get(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int i915_vblank_swap(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int i915_enable_vblank(struct drm_device *dev, int crtc); -extern void i915_disable_vblank(struct drm_device *dev, int crtc); -extern u32 i915_get_vblank_counter(struct drm_device *dev, int crtc); /* i915_mem.c */ extern int i915_mem_alloc(struct drm_device *dev, void *data, @@ -388,91 +381,21 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); /* Interrupt bits: */ -#define I915_PIPE_CONTROL_NOTIFY_INTERRUPT (1<<18) -#define I915_DISPLAY_PORT_INTERRUPT (1<<17) -#define I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT (1<<15) -#define I915_GMCH_THERMAL_SENSOR_EVENT_INTERRUPT (1<<14) -#define I915_HWB_OOM_INTERRUPT (1<<13) /* binner out of memory */ -#define I915_SYNC_STATUS_INTERRUPT (1<<12) -#define I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT (1<<11) -#define I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT (1<<10) -#define I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT (1<<9) -#define I915_DISPLAY_PLANE_C_FLIP_PENDING_INTERRUPT (1<<8) -#define I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT (1<<7) -#define I915_DISPLAY_PIPE_A_EVENT_INTERRUPT (1<<6) -#define I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT (1<<5) -#define I915_DISPLAY_PIPE_B_EVENT_INTERRUPT (1<<4) -#define I915_DEBUG_INTERRUPT (1<<2) -#define I915_USER_INTERRUPT (1<<1) - +#define USER_INT_FLAG (1<<1) +#define VSYNC_PIPEB_FLAG (1<<5) +#define VSYNC_PIPEA_FLAG (1<<7) +#define HWB_OOM_FLAG (1<<13) /* binner out of memory */ #define I915REG_HWSTAM 0x02098 #define I915REG_INT_IDENTITY_R 0x020a4 #define I915REG_INT_MASK_R 0x020a8 #define I915REG_INT_ENABLE_R 0x020a0 -#define I915REG_INSTPM 0x020c0 - -#define PIPEADSL 0x70000 -#define PIPEBDSL 0x71000 #define I915REG_PIPEASTAT 0x70024 #define I915REG_PIPEBSTAT 0x71024 -/* - * The two pipe frame counter registers are not synchronized, so - * reading a stable value is somewhat tricky. The following code - * should work: - * - * do { - * high1 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >> - * PIPE_FRAME_HIGH_SHIFT; - * low1 = ((INREG(PIPEAFRAMEPIXEL) & PIPE_FRAME_LOW_MASK) >> - * PIPE_FRAME_LOW_SHIFT); - * high2 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >> - * PIPE_FRAME_HIGH_SHIFT); - * } while (high1 != high2); - * frame = (high1 << 8) | low1; - */ -#define PIPEAFRAMEHIGH 0x70040 -#define PIPEBFRAMEHIGH 0x71040 -#define PIPE_FRAME_HIGH_MASK 0x0000ffff -#define PIPE_FRAME_HIGH_SHIFT 0 -#define PIPEAFRAMEPIXEL 0x70044 -#define PIPEBFRAMEPIXEL 0x71044 -#define PIPE_FRAME_LOW_MASK 0xff000000 -#define PIPE_FRAME_LOW_SHIFT 24 -/* - * Pixel within the current frame is counted in the PIPEAFRAMEPIXEL register - * and is 24 bits wide. - */ -#define PIPE_PIXEL_MASK 0x00ffffff -#define PIPE_PIXEL_SHIFT 0 - -#define I915_FIFO_UNDERRUN_STATUS (1UL<<31) -#define I915_CRC_ERROR_ENABLE (1UL<<29) -#define I915_CRC_DONE_ENABLE (1UL<<28) -#define I915_GMBUS_EVENT_ENABLE (1UL<<27) -#define I915_VSYNC_INTERRUPT_ENABLE (1UL<<25) -#define I915_DISPLAY_LINE_COMPARE_ENABLE (1UL<<24) -#define I915_DPST_EVENT_ENABLE (1UL<<23) -#define I915_LEGACY_BLC_EVENT_ENABLE (1UL<<22) -#define I915_ODD_FIELD_INTERRUPT_ENABLE (1UL<<21) -#define I915_EVEN_FIELD_INTERRUPT_ENABLE (1UL<<20) -#define I915_START_VBLANK_INTERRUPT_ENABLE (1UL<<18) /* 965 or later */ -#define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17) -#define I915_OVERLAY_UPDATED_ENABLE (1UL<<16) -#define I915_CRC_ERROR_INTERRUPT_STATUS (1UL<<13) -#define I915_CRC_DONE_INTERRUPT_STATUS (1UL<<12) -#define I915_GMBUS_INTERRUPT_STATUS (1UL<<11) -#define I915_VSYNC_INTERRUPT_STATUS (1UL<<9) -#define I915_DISPLAY_LINE_COMPARE_STATUS (1UL<<8) -#define I915_DPST_EVENT_STATUS (1UL<<7) -#define I915_LEGACY_BLC_EVENT_STATUS (1UL<<6) -#define I915_ODD_FIELD_INTERRUPT_STATUS (1UL<<5) -#define I915_EVEN_FIELD_INTERRUPT_STATUS (1UL<<4) -#define I915_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */ -#define I915_VBLANK_INTERRUPT_STATUS (1UL<<1) -#define I915_OVERLAY_UPDATED_STATUS (1UL<<0) +#define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17) +#define I915_VBLANK_CLEAR (1UL<<1) #define SRX_INDEX 0x3c4 #define SRX_DATA 0x3c5 @@ -749,6 +672,8 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); /** P1 value is 2 greater than this field */ # define VGA0_PD_P1_MASK (0x1f << 0) +/* PCI D state control register */ +#define D_STATE 0x6104 #define DSPCLK_GATE_D 0x6200 /* I830 CRTC registers */ @@ -1059,6 +984,12 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21) #define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21) +#define DSPARB 0x70030 +#define DSPARB_CSTART_MASK (0x7f << 7) +#define DSPARB_CSTART_SHIFT 7 +#define DSPARB_BSTART_MASK (0x7f) +#define DSPARB_BSTART_SHIFT 0 + #define PIPEBCONF 0x71008 #define PIPEBCONF_ENABLE (1<<31) #define PIPEBCONF_DISABLE 0 diff --git a/drivers/char/drm/i915_irq.c b/drivers/char/drm/i915_irq.c index 023ce66ef3ab2f8858b3946f9777484836c8a799..f7f16e7a8bf3c8d724065268052b9659c99a2d61 100644 --- a/drivers/char/drm/i915_irq.c +++ b/drivers/char/drm/i915_irq.c @@ -37,109 +37,6 @@ #define MAX_NOPID ((u32)~0) -/** - * i915_get_pipe - return the the pipe associated with a given plane - * @dev: DRM device - * @plane: plane to look for - * - * The Intel Mesa & 2D drivers call the vblank routines with a plane number - * rather than a pipe number, since they may not always be equal. This routine - * maps the given @plane back to a pipe number. - */ -static int -i915_get_pipe(struct drm_device *dev, int plane) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - u32 dspcntr; - - dspcntr = plane ? I915_READ(DSPBCNTR) : I915_READ(DSPACNTR); - - return dspcntr & DISPPLANE_SEL_PIPE_MASK ? 1 : 0; -} - -/** - * i915_get_plane - return the the plane associated with a given pipe - * @dev: DRM device - * @pipe: pipe to look for - * - * The Intel Mesa & 2D drivers call the vblank routines with a plane number - * rather than a plane number, since they may not always be equal. This routine - * maps the given @pipe back to a plane number. - */ -static int -i915_get_plane(struct drm_device *dev, int pipe) -{ - if (i915_get_pipe(dev, 0) == pipe) - return 0; - return 1; -} - -/** - * i915_pipe_enabled - check if a pipe is enabled - * @dev: DRM device - * @pipe: pipe to check - * - * Reading certain registers when the pipe is disabled can hang the chip. - * Use this routine to make sure the PLL is running and the pipe is active - * before reading such registers if unsure. - */ -static int -i915_pipe_enabled(struct drm_device *dev, int pipe) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - unsigned long pipeconf = pipe ? PIPEBCONF : PIPEACONF; - - if (I915_READ(pipeconf) & PIPEACONF_ENABLE) - return 1; - - return 0; -} - -/** - * Emit a synchronous flip. - * - * This function must be called with the drawable spinlock held. - */ -static void -i915_dispatch_vsync_flip(struct drm_device *dev, struct drm_drawable_info *drw, - int plane) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv; - u16 x1, y1, x2, y2; - int pf_planes = 1 << plane; - - /* If the window is visible on the other plane, we have to flip on that - * plane as well. - */ - if (plane == 1) { - x1 = sarea_priv->planeA_x; - y1 = sarea_priv->planeA_y; - x2 = x1 + sarea_priv->planeA_w; - y2 = y1 + sarea_priv->planeA_h; - } else { - x1 = sarea_priv->planeB_x; - y1 = sarea_priv->planeB_y; - x2 = x1 + sarea_priv->planeB_w; - y2 = y1 + sarea_priv->planeB_h; - } - - if (x2 > 0 && y2 > 0) { - int i, num_rects = drw->num_rects; - struct drm_clip_rect *rect = drw->rects; - - for (i = 0; i < num_rects; i++) - if (!(rect[i].x1 >= x2 || rect[i].y1 >= y2 || - rect[i].x2 <= x1 || rect[i].y2 <= y1)) { - pf_planes = 0x3; - - break; - } - } - - i915_dispatch_flip(dev, pf_planes, 1); -} - /** * Emit blits for scheduled buffer swaps. * @@ -148,19 +45,20 @@ i915_dispatch_vsync_flip(struct drm_device *dev, struct drm_drawable_info *drw, static void i915_vblank_tasklet(struct drm_device *dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + unsigned long irqflags; struct list_head *list, *tmp, hits, *hit; - int nhits, nrects, slice[2], upper[2], lower[2], i, num_pages; - unsigned counter[2]; + int nhits, nrects, slice[2], upper[2], lower[2], i; + unsigned counter[2] = { atomic_read(&dev->vbl_received), + atomic_read(&dev->vbl_received2) }; struct drm_drawable_info *drw; drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv; - u32 cpp = dev_priv->cpp, offsets[3]; + u32 cpp = dev_priv->cpp; u32 cmd = (cpp == 4) ? (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB) : XY_SRC_COPY_BLT_CMD; u32 src_pitch = sarea_priv->pitch * cpp; u32 dst_pitch = sarea_priv->pitch * cpp; - /* COPY rop (0xcc), map cpp to magic color depth constants */ u32 ropcpp = (0xcc << 16) | ((cpp - 1) << 24); RING_LOCALS; @@ -173,34 +71,24 @@ static void i915_vblank_tasklet(struct drm_device *dev) src_pitch >>= 2; } - counter[0] = drm_vblank_count(dev, 0); - counter[1] = drm_vblank_count(dev, 1); - DRM_DEBUG("\n"); INIT_LIST_HEAD(&hits); nhits = nrects = 0; - /* No irqsave/restore necessary. This tasklet may be run in an - * interrupt context or normal context, but we don't have to worry - * about getting interrupted by something acquiring the lock, because - * we are the interrupt context thing that acquires the lock. - */ - spin_lock(&dev_priv->swaps_lock); + spin_lock_irqsave(&dev_priv->swaps_lock, irqflags); /* Find buffer swaps scheduled for this vertical blank */ list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) { drm_i915_vbl_swap_t *vbl_swap = list_entry(list, drm_i915_vbl_swap_t, head); - int pipe = i915_get_pipe(dev, vbl_swap->plane); - if ((counter[pipe] - vbl_swap->sequence) > (1<<23)) + if ((counter[vbl_swap->pipe] - vbl_swap->sequence) > (1<<23)) continue; list_del(list); dev_priv->swaps_pending--; - drm_vblank_put(dev, pipe); spin_unlock(&dev_priv->swaps_lock); spin_lock(&dev->drw_lock); @@ -238,23 +126,43 @@ static void i915_vblank_tasklet(struct drm_device *dev) spin_lock(&dev_priv->swaps_lock); } - spin_unlock(&dev_priv->swaps_lock); - - if (nhits == 0) + if (nhits == 0) { + spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags); return; + } + + spin_unlock(&dev_priv->swaps_lock); i915_kernel_lost_context(dev); - upper[0] = upper[1] = 0; - slice[0] = max(sarea_priv->planeA_h / nhits, 1); - slice[1] = max(sarea_priv->planeB_h / nhits, 1); - lower[0] = sarea_priv->planeA_y + slice[0]; - lower[1] = sarea_priv->planeB_y + slice[0]; + if (IS_I965G(dev)) { + BEGIN_LP_RING(4); + + OUT_RING(GFX_OP_DRAWRECT_INFO_I965); + OUT_RING(0); + OUT_RING(((sarea_priv->width - 1) & 0xffff) | ((sarea_priv->height - 1) << 16)); + OUT_RING(0); + ADVANCE_LP_RING(); + } else { + BEGIN_LP_RING(6); - offsets[0] = sarea_priv->front_offset; - offsets[1] = sarea_priv->back_offset; - offsets[2] = sarea_priv->third_offset; - num_pages = sarea_priv->third_handle ? 3 : 2; + OUT_RING(GFX_OP_DRAWRECT_INFO); + OUT_RING(0); + OUT_RING(0); + OUT_RING(sarea_priv->width | sarea_priv->height << 16); + OUT_RING(sarea_priv->width | sarea_priv->height << 16); + OUT_RING(0); + + ADVANCE_LP_RING(); + } + + sarea_priv->ctxOwner = DRM_KERNEL_CONTEXT; + + upper[0] = upper[1] = 0; + slice[0] = max(sarea_priv->pipeA_h / nhits, 1); + slice[1] = max(sarea_priv->pipeB_h / nhits, 1); + lower[0] = sarea_priv->pipeA_y + slice[0]; + lower[1] = sarea_priv->pipeB_y + slice[0]; spin_lock(&dev->drw_lock); @@ -266,8 +174,6 @@ static void i915_vblank_tasklet(struct drm_device *dev) for (i = 0; i++ < nhits; upper[0] = lower[0], lower[0] += slice[0], upper[1] = lower[1], lower[1] += slice[1]) { - int init_drawrect = 1; - if (i == nhits) lower[0] = lower[1] = sarea_priv->height; @@ -275,7 +181,7 @@ static void i915_vblank_tasklet(struct drm_device *dev) drm_i915_vbl_swap_t *swap_hit = list_entry(hit, drm_i915_vbl_swap_t, head); struct drm_clip_rect *rect; - int num_rects, plane, front, back; + int num_rects, pipe; unsigned short top, bottom; drw = drm_get_drawable_info(dev, swap_hit->drw_id); @@ -283,50 +189,10 @@ static void i915_vblank_tasklet(struct drm_device *dev) if (!drw) continue; - plane = swap_hit->plane; - - if (swap_hit->flip) { - i915_dispatch_vsync_flip(dev, drw, plane); - continue; - } - - if (init_drawrect) { - int width = sarea_priv->width; - int height = sarea_priv->height; - if (IS_I965G(dev)) { - BEGIN_LP_RING(4); - - OUT_RING(GFX_OP_DRAWRECT_INFO_I965); - OUT_RING(0); - OUT_RING(((width - 1) & 0xffff) | ((height - 1) << 16)); - OUT_RING(0); - - ADVANCE_LP_RING(); - } else { - BEGIN_LP_RING(6); - - OUT_RING(GFX_OP_DRAWRECT_INFO); - OUT_RING(0); - OUT_RING(0); - OUT_RING(((width - 1) & 0xffff) | ((height - 1) << 16)); - OUT_RING(0); - OUT_RING(0); - - ADVANCE_LP_RING(); - } - - sarea_priv->ctxOwner = DRM_KERNEL_CONTEXT; - - init_drawrect = 0; - } - rect = drw->rects; - top = upper[plane]; - bottom = lower[plane]; - - front = (dev_priv->sarea_priv->pf_current_page >> - (2 * plane)) & 0x3; - back = (front + 1) % num_pages; + pipe = swap_hit->pipe; + top = upper[pipe]; + bottom = lower[pipe]; for (num_rects = drw->num_rects; num_rects--; rect++) { int y1 = max(rect->y1, top); @@ -341,17 +207,17 @@ static void i915_vblank_tasklet(struct drm_device *dev) OUT_RING(ropcpp | dst_pitch); OUT_RING((y1 << 16) | rect->x1); OUT_RING((y2 << 16) | rect->x2); - OUT_RING(offsets[front]); + OUT_RING(sarea_priv->front_offset); OUT_RING((y1 << 16) | rect->x1); OUT_RING(src_pitch); - OUT_RING(offsets[back]); + OUT_RING(sarea_priv->back_offset); ADVANCE_LP_RING(); } } } - spin_unlock(&dev->drw_lock); + spin_unlock_irqrestore(&dev->drw_lock, irqflags); list_for_each_safe(hit, tmp, &hits) { drm_i915_vbl_swap_t *swap_hit = @@ -363,112 +229,67 @@ static void i915_vblank_tasklet(struct drm_device *dev) } } -u32 i915_get_vblank_counter(struct drm_device *dev, int plane) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - unsigned long high_frame; - unsigned long low_frame; - u32 high1, high2, low, count; - int pipe; - - pipe = i915_get_pipe(dev, plane); - high_frame = pipe ? PIPEBFRAMEHIGH : PIPEAFRAMEHIGH; - low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL; - - if (!i915_pipe_enabled(dev, pipe)) { - printk(KERN_ERR "trying to get vblank count for disabled " - "pipe %d\n", pipe); - return 0; - } - - /* - * High & low register fields aren't synchronized, so make sure - * we get a low value that's stable across two reads of the high - * register. - */ - do { - high1 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >> - PIPE_FRAME_HIGH_SHIFT); - low = ((I915_READ(low_frame) & PIPE_FRAME_LOW_MASK) >> - PIPE_FRAME_LOW_SHIFT); - high2 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >> - PIPE_FRAME_HIGH_SHIFT); - } while (high1 != high2); - - count = (high1 << 8) | low; - - /* count may be reset by other driver(e.g. 2D driver), - we have no way to know if it is wrapped or resetted - when count is zero. do a rough guess. - */ - if (count == 0 && dev->last_vblank[pipe] < dev->max_vblank_count/2) - dev->last_vblank[pipe] = 0; - - return count; -} - irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) { struct drm_device *dev = (struct drm_device *) arg; drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - u32 iir; + u16 temp; u32 pipea_stats, pipeb_stats; - int vblank = 0; - - iir = I915_READ(I915REG_INT_IDENTITY_R); - if (iir == 0) { - DRM_DEBUG ("iir 0x%08x im 0x%08x ie 0x%08x pipea 0x%08x pipeb 0x%08x\n", - iir, - I915_READ(I915REG_INT_MASK_R), - I915_READ(I915REG_INT_ENABLE_R), - I915_READ(I915REG_PIPEASTAT), - I915_READ(I915REG_PIPEBSTAT)); - return IRQ_NONE; - } - /* - * Clear the PIPE(A|B)STAT regs before the IIR otherwise - * we may get extra interrupts. - */ - if (iir & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT) { - pipea_stats = I915_READ(I915REG_PIPEASTAT); - if (pipea_stats & (I915_START_VBLANK_INTERRUPT_STATUS| - I915_VBLANK_INTERRUPT_STATUS)) - { - vblank++; - drm_handle_vblank(dev, i915_get_plane(dev, 0)); - } - I915_WRITE(I915REG_PIPEASTAT, pipea_stats); - } - if (iir & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) { - pipeb_stats = I915_READ(I915REG_PIPEBSTAT); - if (pipeb_stats & (I915_START_VBLANK_INTERRUPT_STATUS| - I915_VBLANK_INTERRUPT_STATUS)) - { - vblank++; - drm_handle_vblank(dev, i915_get_plane(dev, 1)); - } - I915_WRITE(I915REG_PIPEBSTAT, pipeb_stats); - } + pipea_stats = I915_READ(I915REG_PIPEASTAT); + pipeb_stats = I915_READ(I915REG_PIPEBSTAT); - if (dev_priv->sarea_priv) - dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); + temp = I915_READ16(I915REG_INT_IDENTITY_R); - I915_WRITE(I915REG_INT_IDENTITY_R, iir); - (void) I915_READ(I915REG_INT_IDENTITY_R); /* Flush posted write */ + temp &= (USER_INT_FLAG | VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG); - if (iir & I915_USER_INTERRUPT) { + DRM_DEBUG("%s flag=%08x\n", __FUNCTION__, temp); + + if (temp == 0) + return IRQ_NONE; + + I915_WRITE16(I915REG_INT_IDENTITY_R, temp); + (void) I915_READ16(I915REG_INT_IDENTITY_R); + DRM_READMEMORYBARRIER(); + + dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); + + if (temp & USER_INT_FLAG) DRM_WAKEUP(&dev_priv->irq_queue); - } - if (vblank) { + + if (temp & (VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG)) { + int vblank_pipe = dev_priv->vblank_pipe; + + if ((vblank_pipe & + (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B)) + == (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B)) { + if (temp & VSYNC_PIPEA_FLAG) + atomic_inc(&dev->vbl_received); + if (temp & VSYNC_PIPEB_FLAG) + atomic_inc(&dev->vbl_received2); + } else if (((temp & VSYNC_PIPEA_FLAG) && + (vblank_pipe & DRM_I915_VBLANK_PIPE_A)) || + ((temp & VSYNC_PIPEB_FLAG) && + (vblank_pipe & DRM_I915_VBLANK_PIPE_B))) + atomic_inc(&dev->vbl_received); + + DRM_WAKEUP(&dev->vbl_queue); + drm_vbl_send_signals(dev); + if (dev_priv->swaps_pending > 0) drm_locked_tasklet(dev, i915_vblank_tasklet); + I915_WRITE(I915REG_PIPEASTAT, + pipea_stats|I915_VBLANK_INTERRUPT_ENABLE| + I915_VBLANK_CLEAR); + I915_WRITE(I915REG_PIPEBSTAT, + pipeb_stats|I915_VBLANK_INTERRUPT_ENABLE| + I915_VBLANK_CLEAR); } return IRQ_HANDLED; } -static int i915_emit_irq(struct drm_device *dev) +static int i915_emit_irq(struct drm_device * dev) { drm_i915_private_t *dev_priv = dev->dev_private; RING_LOCALS; @@ -515,12 +336,42 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr) READ_BREADCRUMB(dev_priv), (int)dev_priv->counter); } - if (dev_priv->sarea_priv) - dev_priv->sarea_priv->last_dispatch = - READ_BREADCRUMB(dev_priv); + dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); return ret; } +static int i915_driver_vblank_do_wait(struct drm_device *dev, unsigned int *sequence, + atomic_t *counter) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + unsigned int cur_vblank; + int ret = 0; + + if (!dev_priv) { + DRM_ERROR("called with no initialization\n"); + return -EINVAL; + } + + DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, + (((cur_vblank = atomic_read(counter)) + - *sequence) <= (1<<23))); + + *sequence = cur_vblank; + + return ret; +} + + +int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence) +{ + return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received); +} + +int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence) +{ + return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received2); +} + /* Needs the lock as it touches the ring. */ int i915_irq_emit(struct drm_device *dev, void *data, @@ -563,96 +414,18 @@ int i915_irq_wait(struct drm_device *dev, void *data, return i915_wait_irq(dev, irqwait->irq_seq); } -int i915_enable_vblank(struct drm_device *dev, int plane) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - int pipe = i915_get_pipe(dev, plane); - u32 pipestat_reg = 0; - u32 pipestat; - - switch (pipe) { - case 0: - pipestat_reg = I915REG_PIPEASTAT; - dev_priv->irq_enable_reg |= I915_DISPLAY_PIPE_A_EVENT_INTERRUPT; - break; - case 1: - pipestat_reg = I915REG_PIPEBSTAT; - dev_priv->irq_enable_reg |= I915_DISPLAY_PIPE_B_EVENT_INTERRUPT; - break; - default: - DRM_ERROR("tried to enable vblank on non-existent pipe %d\n", - pipe); - break; - } - - if (pipestat_reg) - { - pipestat = I915_READ (pipestat_reg); - /* - * Older chips didn't have the start vblank interrupt, - * but - */ - if (IS_I965G (dev)) - pipestat |= I915_START_VBLANK_INTERRUPT_ENABLE; - else - pipestat |= I915_VBLANK_INTERRUPT_ENABLE; - /* - * Clear any pending status - */ - pipestat |= (I915_START_VBLANK_INTERRUPT_STATUS | - I915_VBLANK_INTERRUPT_STATUS); - I915_WRITE(pipestat_reg, pipestat); - } - I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); - - return 0; -} - -void i915_disable_vblank(struct drm_device *dev, int plane) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - int pipe = i915_get_pipe(dev, plane); - u32 pipestat_reg = 0; - u32 pipestat; - - switch (pipe) { - case 0: - pipestat_reg = I915REG_PIPEASTAT; - dev_priv->irq_enable_reg &= ~I915_DISPLAY_PIPE_A_EVENT_INTERRUPT; - break; - case 1: - pipestat_reg = I915REG_PIPEBSTAT; - dev_priv->irq_enable_reg &= ~I915_DISPLAY_PIPE_B_EVENT_INTERRUPT; - break; - default: - DRM_ERROR("tried to disable vblank on non-existent pipe %d\n", - pipe); - break; - } - - I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); - if (pipestat_reg) - { - pipestat = I915_READ (pipestat_reg); - pipestat &= ~(I915_START_VBLANK_INTERRUPT_ENABLE | - I915_VBLANK_INTERRUPT_ENABLE); - /* - * Clear any pending status - */ - pipestat |= (I915_START_VBLANK_INTERRUPT_STATUS | - I915_VBLANK_INTERRUPT_STATUS); - I915_WRITE(pipestat_reg, pipestat); - } -} - static void i915_enable_interrupt (struct drm_device *dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + u16 flag; - dev_priv->irq_enable_reg |= I915_USER_INTERRUPT; + flag = 0; + if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A) + flag |= VSYNC_PIPEA_FLAG; + if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B) + flag |= VSYNC_PIPEB_FLAG; - I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); - dev_priv->irq_enabled = 1; + I915_WRITE16(I915REG_INT_ENABLE_R, USER_INT_FLAG | flag); } /* Set the vblank monitor pipe @@ -675,6 +448,8 @@ int i915_vblank_pipe_set(struct drm_device *dev, void *data, dev_priv->vblank_pipe = pipe->pipe; + i915_enable_interrupt (dev); + return 0; } @@ -692,9 +467,9 @@ int i915_vblank_pipe_get(struct drm_device *dev, void *data, flag = I915_READ(I915REG_INT_ENABLE_R); pipe->pipe = 0; - if (flag & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT) + if (flag & VSYNC_PIPEA_FLAG) pipe->pipe |= DRM_I915_VBLANK_PIPE_A; - if (flag & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) + if (flag & VSYNC_PIPEB_FLAG) pipe->pipe |= DRM_I915_VBLANK_PIPE_B; return 0; @@ -709,30 +484,27 @@ int i915_vblank_swap(struct drm_device *dev, void *data, drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_vblank_swap_t *swap = data; drm_i915_vbl_swap_t *vbl_swap; - unsigned int pipe, seqtype, curseq, plane; + unsigned int pipe, seqtype, curseq; unsigned long irqflags; struct list_head *list; - int ret; if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __func__); return -EINVAL; } - if (!dev_priv->sarea_priv || dev_priv->sarea_priv->rotation) { + if (dev_priv->sarea_priv->rotation) { DRM_DEBUG("Rotation not supported\n"); return -EINVAL; } if (swap->seqtype & ~(_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE | - _DRM_VBLANK_SECONDARY | _DRM_VBLANK_NEXTONMISS | - _DRM_VBLANK_FLIP)) { + _DRM_VBLANK_SECONDARY | _DRM_VBLANK_NEXTONMISS)) { DRM_ERROR("Invalid sequence type 0x%x\n", swap->seqtype); return -EINVAL; } - plane = (swap->seqtype & _DRM_VBLANK_SECONDARY) ? 1 : 0; - pipe = i915_get_pipe(dev, plane); + pipe = (swap->seqtype & _DRM_VBLANK_SECONDARY) ? 1 : 0; seqtype = swap->seqtype & (_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE); @@ -743,11 +515,6 @@ int i915_vblank_swap(struct drm_device *dev, void *data, spin_lock_irqsave(&dev->drw_lock, irqflags); - /* It makes no sense to schedule a swap for a drawable that doesn't have - * valid information at this point. E.g. this could mean that the X - * server is too old to push drawable information to the DRM, in which - * case all such swaps would become ineffective. - */ if (!drm_get_drawable_info(dev, swap->drawable)) { spin_unlock_irqrestore(&dev->drw_lock, irqflags); DRM_DEBUG("Invalid drawable ID %d\n", swap->drawable); @@ -756,8 +523,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data, spin_unlock_irqrestore(&dev->drw_lock, irqflags); - drm_update_vblank_count(dev, pipe); - curseq = drm_vblank_count(dev, pipe); + curseq = atomic_read(pipe ? &dev->vbl_received2 : &dev->vbl_received); if (seqtype == _DRM_VBLANK_RELATIVE) swap->sequence += curseq; @@ -771,43 +537,14 @@ int i915_vblank_swap(struct drm_device *dev, void *data, } } - if (swap->seqtype & _DRM_VBLANK_FLIP) { - swap->sequence--; - - if ((curseq - swap->sequence) <= (1<<23)) { - struct drm_drawable_info *drw; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - spin_lock_irqsave(&dev->drw_lock, irqflags); - - drw = drm_get_drawable_info(dev, swap->drawable); - - if (!drw) { - spin_unlock_irqrestore(&dev->drw_lock, - irqflags); - DRM_DEBUG("Invalid drawable ID %d\n", - swap->drawable); - return -EINVAL; - } - - i915_dispatch_vsync_flip(dev, drw, plane); - - spin_unlock_irqrestore(&dev->drw_lock, irqflags); - - return 0; - } - } - spin_lock_irqsave(&dev_priv->swaps_lock, irqflags); list_for_each(list, &dev_priv->vbl_swaps.head) { vbl_swap = list_entry(list, drm_i915_vbl_swap_t, head); if (vbl_swap->drw_id == swap->drawable && - vbl_swap->plane == plane && + vbl_swap->pipe == pipe && vbl_swap->sequence == swap->sequence) { - vbl_swap->flip = (swap->seqtype & _DRM_VBLANK_FLIP); spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags); DRM_DEBUG("Already scheduled\n"); return 0; @@ -830,19 +567,9 @@ int i915_vblank_swap(struct drm_device *dev, void *data, DRM_DEBUG("\n"); - ret = drm_vblank_get(dev, pipe); - if (ret) { - drm_free(vbl_swap, sizeof(*vbl_swap), DRM_MEM_DRIVER); - return ret; - } - vbl_swap->drw_id = swap->drawable; - vbl_swap->plane = plane; + vbl_swap->pipe = pipe; vbl_swap->sequence = swap->sequence; - vbl_swap->flip = (swap->seqtype & _DRM_VBLANK_FLIP); - - if (vbl_swap->flip) - swap->sequence++; spin_lock_irqsave(&dev_priv->swaps_lock, irqflags); @@ -860,57 +587,37 @@ void i915_driver_irq_preinstall(struct drm_device * dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - I915_WRITE16(I915REG_HWSTAM, 0xeffe); + I915_WRITE16(I915REG_HWSTAM, 0xfffe); I915_WRITE16(I915REG_INT_MASK_R, 0x0); I915_WRITE16(I915REG_INT_ENABLE_R, 0x0); } -int i915_driver_irq_postinstall(struct drm_device * dev) +void i915_driver_irq_postinstall(struct drm_device * dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - int ret, num_pipes = 2; spin_lock_init(&dev_priv->swaps_lock); INIT_LIST_HEAD(&dev_priv->vbl_swaps.head); dev_priv->swaps_pending = 0; - dev_priv->user_irq_refcount = 0; - dev_priv->irq_enable_reg = 0; - - ret = drm_vblank_init(dev, num_pipes); - if (ret) - return ret; - - dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ - + if (!dev_priv->vblank_pipe) + dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A; i915_enable_interrupt(dev); DRM_INIT_WAITQUEUE(&dev_priv->irq_queue); - - /* - * Initialize the hardware status page IRQ location. - */ - - I915_WRITE(I915REG_INSTPM, (1 << 5) | (1 << 21)); - return 0; } void i915_driver_irq_uninstall(struct drm_device * dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - u32 temp; + u16 temp; if (!dev_priv) return; - dev_priv->irq_enabled = 0; - I915_WRITE(I915REG_HWSTAM, 0xffffffff); - I915_WRITE(I915REG_INT_MASK_R, 0xffffffff); - I915_WRITE(I915REG_INT_ENABLE_R, 0x0); - - temp = I915_READ(I915REG_PIPEASTAT); - I915_WRITE(I915REG_PIPEASTAT, temp); - temp = I915_READ(I915REG_PIPEBSTAT); - I915_WRITE(I915REG_PIPEBSTAT, temp); - temp = I915_READ(I915REG_INT_IDENTITY_R); - I915_WRITE(I915REG_INT_IDENTITY_R, temp); + I915_WRITE16(I915REG_HWSTAM, 0xffff); + I915_WRITE16(I915REG_INT_MASK_R, 0xffff); + I915_WRITE16(I915REG_INT_ENABLE_R, 0x0); + + temp = I915_READ16(I915REG_INT_IDENTITY_R); + I915_WRITE16(I915REG_INT_IDENTITY_R, temp); } diff --git a/drivers/char/drm/mga_drv.c b/drivers/char/drm/mga_drv.c index 6b3790939e762d91e7ed4c7a8bcb4d6ac6eb7f9e..5572939fc7d19cb1f986833a22ce79a21ad1da0a 100644 --- a/drivers/char/drm/mga_drv.c +++ b/drivers/char/drm/mga_drv.c @@ -45,16 +45,15 @@ static struct pci_device_id pciidlist[] = { static struct drm_driver driver = { .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | - DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, + DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | + DRIVER_IRQ_VBL, .dev_priv_size = sizeof(drm_mga_buf_priv_t), .load = mga_driver_load, .unload = mga_driver_unload, .lastclose = mga_driver_lastclose, .dma_quiescent = mga_driver_dma_quiescent, .device_is_agp = mga_driver_device_is_agp, - .get_vblank_counter = mga_get_vblank_counter, - .enable_vblank = mga_enable_vblank, - .disable_vblank = mga_disable_vblank, + .vblank_wait = mga_driver_vblank_wait, .irq_preinstall = mga_driver_irq_preinstall, .irq_postinstall = mga_driver_irq_postinstall, .irq_uninstall = mga_driver_irq_uninstall, diff --git a/drivers/char/drm/mga_drv.h b/drivers/char/drm/mga_drv.h index 8f7291f36363590c3431570d78c364b81cb4bbea..f6ebd24bd5871ebad2204c64195e3e3e31219401 100644 --- a/drivers/char/drm/mga_drv.h +++ b/drivers/char/drm/mga_drv.h @@ -120,7 +120,6 @@ typedef struct drm_mga_private { u32 clear_cmd; u32 maccess; - atomic_t vbl_received; /**< Number of vblanks received. */ wait_queue_head_t fence_queue; atomic_t last_fence_retired; u32 next_fence_to_post; @@ -182,14 +181,11 @@ extern int mga_warp_install_microcode(drm_mga_private_t * dev_priv); extern int mga_warp_init(drm_mga_private_t * dev_priv); /* mga_irq.c */ -extern int mga_enable_vblank(struct drm_device *dev, int crtc); -extern void mga_disable_vblank(struct drm_device *dev, int crtc); -extern u32 mga_get_vblank_counter(struct drm_device *dev, int crtc); extern int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence); extern int mga_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence); extern irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS); extern void mga_driver_irq_preinstall(struct drm_device * dev); -extern int mga_driver_irq_postinstall(struct drm_device * dev); +extern void mga_driver_irq_postinstall(struct drm_device * dev); extern void mga_driver_irq_uninstall(struct drm_device * dev); extern long mga_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); diff --git a/drivers/char/drm/mga_irq.c b/drivers/char/drm/mga_irq.c index 06852fb4b278fd0c5b0f3d84ff0d915858135913..9302cb8f0f83bef1e99be219a9b977884d3f6d28 100644 --- a/drivers/char/drm/mga_irq.c +++ b/drivers/char/drm/mga_irq.c @@ -35,20 +35,6 @@ #include "mga_drm.h" #include "mga_drv.h" -u32 mga_get_vblank_counter(struct drm_device *dev, int crtc) -{ - const drm_mga_private_t *const dev_priv = - (drm_mga_private_t *) dev->dev_private; - - if (crtc != 0) { - return 0; - } - - - return atomic_read(&dev_priv->vbl_received); -} - - irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS) { struct drm_device *dev = (struct drm_device *) arg; @@ -61,8 +47,9 @@ irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS) /* VBLANK interrupt */ if (status & MGA_VLINEPEN) { MGA_WRITE(MGA_ICLEAR, MGA_VLINEICLR); - atomic_inc(&dev_priv->vbl_received); - drm_handle_vblank(dev, 0); + atomic_inc(&dev->vbl_received); + DRM_WAKEUP(&dev->vbl_queue); + drm_vbl_send_signals(dev); handled = 1; } @@ -91,34 +78,22 @@ irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS) return IRQ_NONE; } -int mga_enable_vblank(struct drm_device *dev, int crtc) +int mga_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence) { - drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; - - if (crtc != 0) { - DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", - crtc); - return 0; - } - - MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); - return 0; -} + unsigned int cur_vblank; + int ret = 0; + /* Assume that the user has missed the current sequence number + * by about a day rather than she wants to wait for years + * using vertical blanks... + */ + DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, + (((cur_vblank = atomic_read(&dev->vbl_received)) + - *sequence) <= (1 << 23))); -void mga_disable_vblank(struct drm_device *dev, int crtc) -{ - if (crtc != 0) { - DRM_ERROR("tried to disable vblank on non-existent crtc %d\n", - crtc); - } + *sequence = cur_vblank; - /* Do *NOT* disable the vertical refresh interrupt. MGA doesn't have - * a nice hardware counter that tracks the number of refreshes when - * the interrupt is disabled, and the kernel doesn't know the refresh - * rate to calculate an estimate. - */ - /* MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); */ + return ret; } int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence) @@ -150,22 +125,14 @@ void mga_driver_irq_preinstall(struct drm_device * dev) MGA_WRITE(MGA_ICLEAR, ~0); } -int mga_driver_irq_postinstall(struct drm_device * dev) +void mga_driver_irq_postinstall(struct drm_device * dev) { drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; - int ret; - - ret = drm_vblank_init(dev, 1); - if (ret) - return ret; DRM_INIT_WAITQUEUE(&dev_priv->fence_queue); - /* Turn on soft trap interrupt. Vertical blank interrupts are enabled - * in mga_enable_vblank. - */ - MGA_WRITE(MGA_IEN, MGA_SOFTRAPEN); - return 0; + /* Turn on vertical blank interrupt and soft trap interrupt. */ + MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); } void mga_driver_irq_uninstall(struct drm_device * dev) diff --git a/drivers/char/drm/r128_drv.c b/drivers/char/drm/r128_drv.c index 2888aa01ebc78779c28a63a63a1382108d33e8e4..6108e7587e12470daba9576ef185458f5fc545c1 100644 --- a/drivers/char/drm/r128_drv.c +++ b/drivers/char/drm/r128_drv.c @@ -43,13 +43,12 @@ static struct pci_device_id pciidlist[] = { static struct drm_driver driver = { .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | - DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, + DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | + DRIVER_IRQ_VBL, .dev_priv_size = sizeof(drm_r128_buf_priv_t), .preclose = r128_driver_preclose, .lastclose = r128_driver_lastclose, - .get_vblank_counter = r128_get_vblank_counter, - .enable_vblank = r128_enable_vblank, - .disable_vblank = r128_disable_vblank, + .vblank_wait = r128_driver_vblank_wait, .irq_preinstall = r128_driver_irq_preinstall, .irq_postinstall = r128_driver_irq_postinstall, .irq_uninstall = r128_driver_irq_uninstall, diff --git a/drivers/char/drm/r128_drv.h b/drivers/char/drm/r128_drv.h index 80af9e09e75da49610fb54b1539022df20d789bd..011105e51ac660117c88a1e1a3d9db860702b325 100644 --- a/drivers/char/drm/r128_drv.h +++ b/drivers/char/drm/r128_drv.h @@ -97,8 +97,6 @@ typedef struct drm_r128_private { u32 crtc_offset; u32 crtc_offset_cntl; - atomic_t vbl_received; - u32 color_fmt; unsigned int front_offset; unsigned int front_pitch; @@ -151,12 +149,11 @@ extern int r128_wait_ring(drm_r128_private_t * dev_priv, int n); extern int r128_do_cce_idle(drm_r128_private_t * dev_priv); extern int r128_do_cleanup_cce(struct drm_device * dev); -extern int r128_enable_vblank(struct drm_device *dev, int crtc); -extern void r128_disable_vblank(struct drm_device *dev, int crtc); -extern u32 r128_get_vblank_counter(struct drm_device *dev, int crtc); +extern int r128_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence); + extern irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS); extern void r128_driver_irq_preinstall(struct drm_device * dev); -extern int r128_driver_irq_postinstall(struct drm_device * dev); +extern void r128_driver_irq_postinstall(struct drm_device * dev); extern void r128_driver_irq_uninstall(struct drm_device * dev); extern void r128_driver_lastclose(struct drm_device * dev); extern void r128_driver_preclose(struct drm_device * dev, diff --git a/drivers/char/drm/r128_irq.c b/drivers/char/drm/r128_irq.c index 5b95bd898f95c54128d6238e34a68b7a7b713865..c76fdca7662d78bcdb0cb83684ce2c9005a471c2 100644 --- a/drivers/char/drm/r128_irq.c +++ b/drivers/char/drm/r128_irq.c @@ -35,16 +35,6 @@ #include "r128_drm.h" #include "r128_drv.h" -u32 r128_get_vblank_counter(struct drm_device *dev, int crtc) -{ - const drm_r128_private_t *dev_priv = dev->dev_private; - - if (crtc != 0) - return 0; - - return atomic_read(&dev_priv->vbl_received); -} - irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS) { struct drm_device *dev = (struct drm_device *) arg; @@ -56,38 +46,30 @@ irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS) /* VBLANK interrupt */ if (status & R128_CRTC_VBLANK_INT) { R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK); - atomic_inc(&dev_priv->vbl_received); - drm_handle_vblank(dev, 0); + atomic_inc(&dev->vbl_received); + DRM_WAKEUP(&dev->vbl_queue); + drm_vbl_send_signals(dev); return IRQ_HANDLED; } return IRQ_NONE; } -int r128_enable_vblank(struct drm_device *dev, int crtc) +int r128_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence) { - drm_r128_private_t *dev_priv = dev->dev_private; - - if (crtc != 0) { - DRM_ERROR("%s: bad crtc %d\n", __FUNCTION__, crtc); - return -EINVAL; - } + unsigned int cur_vblank; + int ret = 0; - R128_WRITE(R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN); - return 0; -} + /* Assume that the user has missed the current sequence number + * by about a day rather than she wants to wait for years + * using vertical blanks... + */ + DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, + (((cur_vblank = atomic_read(&dev->vbl_received)) + - *sequence) <= (1 << 23))); -void r128_disable_vblank(struct drm_device *dev, int crtc) -{ - if (crtc != 0) - DRM_ERROR("%s: bad crtc %d\n", __FUNCTION__, crtc); + *sequence = cur_vblank; - /* - * FIXME: implement proper interrupt disable by using the vblank - * counter register (if available) - * - * R128_WRITE(R128_GEN_INT_CNTL, - * R128_READ(R128_GEN_INT_CNTL) & ~R128_CRTC_VBLANK_INT_EN); - */ + return ret; } void r128_driver_irq_preinstall(struct drm_device * dev) @@ -100,9 +82,12 @@ void r128_driver_irq_preinstall(struct drm_device * dev) R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK); } -int r128_driver_irq_postinstall(struct drm_device * dev) +void r128_driver_irq_postinstall(struct drm_device * dev) { - return drm_vblank_init(dev, 1); + drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private; + + /* Turn on VBL interrupt */ + R128_WRITE(R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN); } void r128_driver_irq_uninstall(struct drm_device * dev) diff --git a/drivers/char/drm/radeon_drv.c b/drivers/char/drm/radeon_drv.c index a2610319624d3509fe98d9e1c93215357b586160..349ac3d3b8480c13d91c850f917819774f92edbf 100644 --- a/drivers/char/drm/radeon_drv.c +++ b/drivers/char/drm/radeon_drv.c @@ -59,7 +59,8 @@ static struct pci_device_id pciidlist[] = { static struct drm_driver driver = { .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | - DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED, + DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | + DRIVER_IRQ_VBL | DRIVER_IRQ_VBL2, .dev_priv_size = sizeof(drm_radeon_buf_priv_t), .load = radeon_driver_load, .firstopen = radeon_driver_firstopen, @@ -68,9 +69,8 @@ static struct drm_driver driver = { .postclose = radeon_driver_postclose, .lastclose = radeon_driver_lastclose, .unload = radeon_driver_unload, - .get_vblank_counter = radeon_get_vblank_counter, - .enable_vblank = radeon_enable_vblank, - .disable_vblank = radeon_disable_vblank, + .vblank_wait = radeon_driver_vblank_wait, + .vblank_wait2 = radeon_driver_vblank_wait2, .dri_library_name = dri_library_name, .irq_preinstall = radeon_driver_irq_preinstall, .irq_postinstall = radeon_driver_irq_postinstall, diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h index b791420bd3d98f4886a1d95e3ebf863282133f13..173ae620223a052238a0a212711e25290bff4f0c 100644 --- a/drivers/char/drm/radeon_drv.h +++ b/drivers/char/drm/radeon_drv.h @@ -304,9 +304,6 @@ typedef struct drm_radeon_private { u32 scratch_ages[5]; - unsigned int crtc_last_cnt; - unsigned int crtc2_last_cnt; - /* starting from here on, data is preserved accross an open */ uint32_t flags; /* see radeon_chip_flags */ unsigned long fb_aper_offset; @@ -377,13 +374,13 @@ extern int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file * extern int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_priv); extern void radeon_do_release(struct drm_device * dev); -extern u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc); -extern int radeon_enable_vblank(struct drm_device *dev, int crtc); -extern void radeon_disable_vblank(struct drm_device *dev, int crtc); -extern void radeon_do_release(struct drm_device * dev); +extern int radeon_driver_vblank_wait(struct drm_device * dev, + unsigned int *sequence); +extern int radeon_driver_vblank_wait2(struct drm_device * dev, + unsigned int *sequence); extern irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS); extern void radeon_driver_irq_preinstall(struct drm_device * dev); -extern int radeon_driver_irq_postinstall(struct drm_device * dev); +extern void radeon_driver_irq_postinstall(struct drm_device * dev); extern void radeon_driver_irq_uninstall(struct drm_device * dev); extern int radeon_vblank_crtc_get(struct drm_device *dev); extern int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value); @@ -561,12 +558,6 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev, ? DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(x) ) \ : RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x) ) ) -#define RADEON_CRTC_CRNT_FRAME 0x0214 -#define RADEON_CRTC2_CRNT_FRAME 0x0314 - -#define RADEON_CRTC_STATUS 0x005c -#define RADEON_CRTC2_STATUS 0x03fc - #define RADEON_GEN_INT_CNTL 0x0040 # define RADEON_CRTC_VBLANK_MASK (1 << 0) # define RADEON_CRTC2_VBLANK_MASK (1 << 9) diff --git a/drivers/char/drm/radeon_irq.c b/drivers/char/drm/radeon_irq.c index 507d6b747a13139cf3aeeb8e0a4f8339a950eaab..009af3814b6f12ec4dcf34aff23cffff79e0d5db 100644 --- a/drivers/char/drm/radeon_irq.c +++ b/drivers/char/drm/radeon_irq.c @@ -35,61 +35,12 @@ #include "radeon_drm.h" #include "radeon_drv.h" -static void radeon_irq_set_state(struct drm_device *dev, u32 mask, int state) +static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t * dev_priv, + u32 mask) { - drm_radeon_private_t *dev_priv = dev->dev_private; - - if (state) - dev_priv->irq_enable_reg |= mask; - else - dev_priv->irq_enable_reg &= ~mask; - - RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg); -} - -int radeon_enable_vblank(struct drm_device *dev, int crtc) -{ - switch (crtc) { - case 0: - radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 1); - break; - case 1: - radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 1); - break; - default: - DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", - crtc); - return EINVAL; - } - - return 0; -} - -void radeon_disable_vblank(struct drm_device *dev, int crtc) -{ - switch (crtc) { - case 0: - radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 0); - break; - case 1: - radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 0); - break; - default: - DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", - crtc); - break; - } -} - -static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t * dev_priv) -{ - u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS) & - (RADEON_SW_INT_TEST | RADEON_CRTC_VBLANK_STAT | - RADEON_CRTC2_VBLANK_STAT); - + u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS) & mask; if (irqs) RADEON_WRITE(RADEON_GEN_INT_STATUS, irqs); - return irqs; } @@ -121,21 +72,39 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS) /* Only consider the bits we're interested in - others could be used * outside the DRM */ - stat = radeon_acknowledge_irqs(dev_priv); + stat = radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | + RADEON_CRTC_VBLANK_STAT | + RADEON_CRTC2_VBLANK_STAT)); if (!stat) return IRQ_NONE; stat &= dev_priv->irq_enable_reg; /* SW interrupt */ - if (stat & RADEON_SW_INT_TEST) + if (stat & RADEON_SW_INT_TEST) { DRM_WAKEUP(&dev_priv->swi_queue); + } /* VBLANK interrupt */ - if (stat & RADEON_CRTC_VBLANK_STAT) - drm_handle_vblank(dev, 0); - if (stat & RADEON_CRTC2_VBLANK_STAT) - drm_handle_vblank(dev, 1); + if (stat & (RADEON_CRTC_VBLANK_STAT|RADEON_CRTC2_VBLANK_STAT)) { + int vblank_crtc = dev_priv->vblank_crtc; + + if ((vblank_crtc & + (DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) == + (DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) { + if (stat & RADEON_CRTC_VBLANK_STAT) + atomic_inc(&dev->vbl_received); + if (stat & RADEON_CRTC2_VBLANK_STAT) + atomic_inc(&dev->vbl_received2); + } else if (((stat & RADEON_CRTC_VBLANK_STAT) && + (vblank_crtc & DRM_RADEON_VBLANK_CRTC1)) || + ((stat & RADEON_CRTC2_VBLANK_STAT) && + (vblank_crtc & DRM_RADEON_VBLANK_CRTC2))) + atomic_inc(&dev->vbl_received); + + DRM_WAKEUP(&dev->vbl_queue); + drm_vbl_send_signals(dev); + } return IRQ_HANDLED; } @@ -175,27 +144,54 @@ static int radeon_wait_irq(struct drm_device * dev, int swi_nr) return ret; } -u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc) +static int radeon_driver_vblank_do_wait(struct drm_device * dev, + unsigned int *sequence, int crtc) { - drm_radeon_private_t *dev_priv = dev->dev_private; - u32 crtc_cnt_reg, crtc_status_reg; - + drm_radeon_private_t *dev_priv = + (drm_radeon_private_t *) dev->dev_private; + unsigned int cur_vblank; + int ret = 0; + int ack = 0; + atomic_t *counter; if (!dev_priv) { DRM_ERROR("called with no initialization\n"); return -EINVAL; } - if (crtc == 0) { - crtc_cnt_reg = RADEON_CRTC_CRNT_FRAME; - crtc_status_reg = RADEON_CRTC_STATUS; - } else if (crtc == 1) { - crtc_cnt_reg = RADEON_CRTC2_CRNT_FRAME; - crtc_status_reg = RADEON_CRTC2_STATUS; - } else { + if (crtc == DRM_RADEON_VBLANK_CRTC1) { + counter = &dev->vbl_received; + ack |= RADEON_CRTC_VBLANK_STAT; + } else if (crtc == DRM_RADEON_VBLANK_CRTC2) { + counter = &dev->vbl_received2; + ack |= RADEON_CRTC2_VBLANK_STAT; + } else return -EINVAL; - } - return RADEON_READ(crtc_cnt_reg) + (RADEON_READ(crtc_status_reg) & 1); + radeon_acknowledge_irqs(dev_priv, ack); + + dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; + + /* Assume that the user has missed the current sequence number + * by about a day rather than she wants to wait for years + * using vertical blanks... + */ + DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, + (((cur_vblank = atomic_read(counter)) + - *sequence) <= (1 << 23))); + + *sequence = cur_vblank; + + return ret; +} + +int radeon_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence) +{ + return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC1); +} + +int radeon_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence) +{ + return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC2); } /* Needs the lock as it touches the ring. @@ -238,6 +234,21 @@ int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_pr return radeon_wait_irq(dev, irqwait->irq_seq); } +static void radeon_enable_interrupt(struct drm_device *dev) +{ + drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; + + dev_priv->irq_enable_reg = RADEON_SW_INT_ENABLE; + if (dev_priv->vblank_crtc & DRM_RADEON_VBLANK_CRTC1) + dev_priv->irq_enable_reg |= RADEON_CRTC_VBLANK_MASK; + + if (dev_priv->vblank_crtc & DRM_RADEON_VBLANK_CRTC2) + dev_priv->irq_enable_reg |= RADEON_CRTC2_VBLANK_MASK; + + RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg); + dev_priv->irq_enabled = 1; +} + /* drm_dma.h hooks */ void radeon_driver_irq_preinstall(struct drm_device * dev) @@ -249,27 +260,20 @@ void radeon_driver_irq_preinstall(struct drm_device * dev) RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); /* Clear bits if they're already high */ - radeon_acknowledge_irqs(dev_priv); + radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | + RADEON_CRTC_VBLANK_STAT | + RADEON_CRTC2_VBLANK_STAT)); } -int radeon_driver_irq_postinstall(struct drm_device * dev) +void radeon_driver_irq_postinstall(struct drm_device * dev) { drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; - int ret; atomic_set(&dev_priv->swi_emitted, 0); DRM_INIT_WAITQUEUE(&dev_priv->swi_queue); - ret = drm_vblank_init(dev, 2); - if (ret) - return ret; - - dev->max_vblank_count = 0x001fffff; - - radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1); - - return 0; + radeon_enable_interrupt(dev); } void radeon_driver_irq_uninstall(struct drm_device * dev) @@ -311,5 +315,6 @@ int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value) return -EINVAL; } dev_priv->vblank_crtc = (unsigned int)value; + radeon_enable_interrupt(dev); return 0; } diff --git a/drivers/char/drm/via_drv.c b/drivers/char/drm/via_drv.c index 37870a4a3dc729877a4d659018260778783982ce..80c01cdfa37d54db94ec5a382f83ec4e6b026432 100644 --- a/drivers/char/drm/via_drv.c +++ b/drivers/char/drm/via_drv.c @@ -40,13 +40,11 @@ static struct pci_device_id pciidlist[] = { static struct drm_driver driver = { .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_IRQ | - DRIVER_IRQ_SHARED, + DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL, .load = via_driver_load, .unload = via_driver_unload, .context_dtor = via_final_context, - .get_vblank_counter = via_get_vblank_counter, - .enable_vblank = via_enable_vblank, - .disable_vblank = via_disable_vblank, + .vblank_wait = via_driver_vblank_wait, .irq_preinstall = via_driver_irq_preinstall, .irq_postinstall = via_driver_irq_postinstall, .irq_uninstall = via_driver_irq_uninstall, diff --git a/drivers/char/drm/via_drv.h b/drivers/char/drm/via_drv.h index fe67030e39ac6b8f3dadb3624fe23a6bed7a958a..2daae81874cdd049fdcd2ff9f0783eb15994fb53 100644 --- a/drivers/char/drm/via_drv.h +++ b/drivers/char/drm/via_drv.h @@ -75,7 +75,6 @@ typedef struct drm_via_private { struct timeval last_vblank; int last_vblank_valid; unsigned usec_per_vblank; - atomic_t vbl_received; drm_via_state_t hc_state; char pci_buf[VIA_PCI_BUF_SIZE]; const uint32_t *fire_offsets[VIA_FIRE_BUF_SIZE]; @@ -131,13 +130,11 @@ extern int via_init_context(struct drm_device * dev, int context); extern int via_final_context(struct drm_device * dev, int context); extern int via_do_cleanup_map(struct drm_device * dev); -extern u32 via_get_vblank_counter(struct drm_device *dev, int crtc); -extern int via_enable_vblank(struct drm_device *dev, int crtc); -extern void via_disable_vblank(struct drm_device *dev, int crtc); +extern int via_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence); extern irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS); extern void via_driver_irq_preinstall(struct drm_device * dev); -extern int via_driver_irq_postinstall(struct drm_device * dev); +extern void via_driver_irq_postinstall(struct drm_device * dev); extern void via_driver_irq_uninstall(struct drm_device * dev); extern int via_dma_cleanup(struct drm_device * dev); diff --git a/drivers/char/drm/via_irq.c b/drivers/char/drm/via_irq.c index f1ab6fc7c07e8a32227ae7516bc65add4c61d030..c6bb978a110673821a3aa6db6e3cefd32bcc20ce 100644 --- a/drivers/char/drm/via_irq.c +++ b/drivers/char/drm/via_irq.c @@ -92,17 +92,8 @@ static int via_irqmap_unichrome[] = {-1, -1, -1, 0, -1, 1}; static unsigned time_diff(struct timeval *now, struct timeval *then) { return (now->tv_usec >= then->tv_usec) ? - now->tv_usec - then->tv_usec : - 1000000 - (then->tv_usec - now->tv_usec); -} - -u32 via_get_vblank_counter(struct drm_device *dev, int crtc) -{ - drm_via_private_t *dev_priv = dev->dev_private; - if (crtc != 0) - return 0; - - return atomic_read(&dev_priv->vbl_received); + now->tv_usec - then->tv_usec : + 1000000 - (then->tv_usec - now->tv_usec); } irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) @@ -117,8 +108,8 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) status = VIA_READ(VIA_REG_INTERRUPT); if (status & VIA_IRQ_VBLANK_PENDING) { - atomic_inc(&dev_priv->vbl_received); - if (!(atomic_read(&dev_priv->vbl_received) & 0x0F)) { + atomic_inc(&dev->vbl_received); + if (!(atomic_read(&dev->vbl_received) & 0x0F)) { do_gettimeofday(&cur_vblank); if (dev_priv->last_vblank_valid) { dev_priv->usec_per_vblank = @@ -128,11 +119,12 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) dev_priv->last_vblank = cur_vblank; dev_priv->last_vblank_valid = 1; } - if (!(atomic_read(&dev_priv->vbl_received) & 0xFF)) { + if (!(atomic_read(&dev->vbl_received) & 0xFF)) { DRM_DEBUG("US per vblank is: %u\n", dev_priv->usec_per_vblank); } - drm_handle_vblank(dev, 0); + DRM_WAKEUP(&dev->vbl_queue); + drm_vbl_send_signals(dev); handled = 1; } @@ -171,34 +163,31 @@ static __inline__ void viadrv_acknowledge_irqs(drm_via_private_t * dev_priv) } } -int via_enable_vblank(struct drm_device *dev, int crtc) +int via_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence) { - drm_via_private_t *dev_priv = dev->dev_private; - u32 status; + drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; + unsigned int cur_vblank; + int ret = 0; - if (crtc != 0) { - DRM_ERROR("%s: bad crtc %d\n", __FUNCTION__, crtc); + DRM_DEBUG("\n"); + if (!dev_priv) { + DRM_ERROR("called with no initialization\n"); return -EINVAL; } - status = VIA_READ(VIA_REG_INTERRUPT); - VIA_WRITE(VIA_REG_INTERRUPT, status & VIA_IRQ_VBLANK_ENABLE); + viadrv_acknowledge_irqs(dev_priv); - VIA_WRITE8(0x83d4, 0x11); - VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30); + /* Assume that the user has missed the current sequence number + * by about a day rather than she wants to wait for years + * using vertical blanks... + */ - return 0; -} + DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, + (((cur_vblank = atomic_read(&dev->vbl_received)) - + *sequence) <= (1 << 23))); -void via_disable_vblank(struct drm_device *dev, int crtc) -{ - drm_via_private_t *dev_priv = dev->dev_private; - - VIA_WRITE8(0x83d4, 0x11); - VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) & ~0x30); - - if (crtc != 0) - DRM_ERROR("%s: bad crtc %d\n", __FUNCTION__, crtc); + *sequence = cur_vblank; + return ret; } static int @@ -303,25 +292,23 @@ void via_driver_irq_preinstall(struct drm_device * dev) } } -int via_driver_irq_postinstall(struct drm_device * dev) +void via_driver_irq_postinstall(struct drm_device * dev) { drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; u32 status; - DRM_DEBUG("via_driver_irq_postinstall\n"); - if (!dev_priv) - return -EINVAL; + DRM_DEBUG("\n"); + if (dev_priv) { + status = VIA_READ(VIA_REG_INTERRUPT); + VIA_WRITE(VIA_REG_INTERRUPT, status | VIA_IRQ_GLOBAL + | dev_priv->irq_enable_mask); - drm_vblank_init(dev, 1); - status = VIA_READ(VIA_REG_INTERRUPT); - VIA_WRITE(VIA_REG_INTERRUPT, status | VIA_IRQ_GLOBAL - | dev_priv->irq_enable_mask); + /* Some magic, oh for some data sheets ! */ - /* Some magic, oh for some data sheets ! */ - VIA_WRITE8(0x83d4, 0x11); - VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30); + VIA_WRITE8(0x83d4, 0x11); + VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30); - return 0; + } } void via_driver_irq_uninstall(struct drm_device * dev) diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 5a5455585c1d278bd770a784fd5e1df603df85e3..192688344ed2d628bc789fa85d9ba4cafcadf867 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -2352,10 +2352,16 @@ static int __devinit ipmi_of_probe(struct of_device *dev, info->si_type = (enum si_type) match->data; info->addr_source = "device-tree"; - info->io_setup = mem_setup; info->irq_setup = std_irq_setup; - info->io.addr_type = IPMI_MEM_ADDR_SPACE; + if (resource.flags & IORESOURCE_IO) { + info->io_setup = port_setup; + info->io.addr_type = IPMI_IO_ADDR_SPACE; + } else { + info->io_setup = mem_setup; + info->io.addr_type = IPMI_MEM_ADDR_SPACE; + } + info->io.addr_data = resource.start; info->io.regsize = regsize ? *regsize : DEFAULT_REGSIZE; diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c index 19105ec203f7afe611edfdc10c99bf50741ccecc..8096389b0dc2d4bd07df5d9cfc902902a043b333 100644 --- a/drivers/char/n_tty.c +++ b/drivers/char/n_tty.c @@ -282,16 +282,20 @@ static int opost(unsigned char c, struct tty_struct *tty) if (O_ONLRET(tty)) tty->column = 0; if (O_ONLCR(tty)) { - if (space < 2) + if (space < 2) { + unlock_kernel(); return -1; + } tty_put_char(tty, '\r'); tty->column = 0; } tty->canon_column = tty->column; break; case '\r': - if (O_ONOCR(tty) && tty->column == 0) + if (O_ONOCR(tty) && tty->column == 0) { + unlock_kernel(); return 0; + } if (O_OCRNL(tty)) { c = '\n'; if (O_ONLRET(tty)) @@ -303,10 +307,13 @@ static int opost(unsigned char c, struct tty_struct *tty) case '\t': spaces = 8 - (tty->column & 7); if (O_TABDLY(tty) == XTABS) { - if (space < spaces) + if (space < spaces) { + unlock_kernel(); return -1; + } tty->column += spaces; tty->ops->write(tty, " ", spaces); + unlock_kernel(); return 0; } tty->column += spaces; diff --git a/drivers/char/snsc_event.c b/drivers/char/snsc_event.c index 53b3d44f8c066bb06dfa84e6ac98a7ddff660628..55a95892ccf91d1005bad85fab371a7104fabe42 100644 --- a/drivers/char/snsc_event.c +++ b/drivers/char/snsc_event.c @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include #include "snsc.h" diff --git a/drivers/char/sx.c b/drivers/char/sx.c index f39f6fd8935064f01af2b91115e70111ddaa6769..b1a7a8cb65ea0252f0cbc0c5194dbc9ad9c8dcd9 100644 --- a/drivers/char/sx.c +++ b/drivers/char/sx.c @@ -970,7 +970,8 @@ static int sx_set_real_termios(void *ptr) sx_write_channel_byte(port, hi_mask, 0x1f); break; default: - printk(KERN_INFO "sx: Invalid wordsize: %u\n", CFLAG & CSIZE); + printk(KERN_INFO "sx: Invalid wordsize: %u\n", + (unsigned int)CFLAG & CSIZE); break; } @@ -997,7 +998,8 @@ static int sx_set_real_termios(void *ptr) set_bit(TTY_HW_COOK_IN, &port->gs.tty->flags); } sx_dprintk(SX_DEBUG_TERMIOS, "iflags: %x(%d) ", - port->gs.tty->termios->c_iflag, I_OTHER(port->gs.tty)); + (unsigned int)port->gs.tty->termios->c_iflag, + I_OTHER(port->gs.tty)); /* Tell line discipline whether we will do output cooking. * If OPOST is set and no other output flags are set then we can do output @@ -1010,7 +1012,8 @@ static int sx_set_real_termios(void *ptr) clear_bit(TTY_HW_COOK_OUT, &port->gs.tty->flags); } sx_dprintk(SX_DEBUG_TERMIOS, "oflags: %x(%d)\n", - port->gs.tty->termios->c_oflag, O_OTHER(port->gs.tty)); + (unsigned int)port->gs.tty->termios->c_oflag, + O_OTHER(port->gs.tty)); /* port->c_dcd = sx_get_CD (port); */ func_exit(); return 0; diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index 2001b0e52dc69c51a765ff8ffdef2a426e202b01..55c1653be00ca86f0f76051d940cfe7e5e933145 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c @@ -916,7 +916,7 @@ static int put_char(struct tty_struct *tty, unsigned char ch) { struct slgt_info *info = tty->driver_data; unsigned long flags; - int ret; + int ret = 0; if (sanity_check(info, tty->name, "put_char")) return 0; diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 49c1a2267a55c7490c504ba7486b276575851ae8..e94bee0323148548d9374852e7b140999af40b81 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -1215,10 +1215,11 @@ int tty_check_change(struct tty_struct *tty) if (!tty->pgrp) { printk(KERN_WARNING "tty_check_change: tty->pgrp == NULL!\n"); - goto out; + goto out_unlock; } if (task_pgrp(current) == tty->pgrp) - goto out; + goto out_unlock; + spin_unlock_irqrestore(&tty->ctrl_lock, flags); if (is_ignored(SIGTTOU)) goto out; if (is_current_pgrp_orphaned()) { @@ -1229,6 +1230,8 @@ int tty_check_change(struct tty_struct *tty) set_thread_flag(TIF_SIGPENDING); ret = -ERESTARTSYS; out: + return ret; +out_unlock: spin_unlock_irqrestore(&tty->ctrl_lock, flags); return ret; } diff --git a/drivers/char/vme_scc.c b/drivers/char/vme_scc.c index e122a0e87bb0b8a53984262ae29bc5d0d3e34e63..f17ac043b551ee3bc6deb01148d45baac2bd2f2d 100644 --- a/drivers/char/vme_scc.c +++ b/drivers/char/vme_scc.c @@ -89,9 +89,7 @@ static void scc_break_ctl(struct tty_struct *tty, int break_state); static struct tty_driver *scc_driver; -struct scc_port scc_ports[2]; - -int scc_initialized = 0; +static struct scc_port scc_ports[2]; /*--------------------------------------------------------------------------- * Interface from generic_serial.c back here diff --git a/drivers/char/vt.c b/drivers/char/vt.c index e458b08139afb6fd638b125334ca1b602eb8e136..fa1ffbf2c621a88aa231f1262a57bd470df97e9e 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c @@ -2742,6 +2742,10 @@ static int con_open(struct tty_struct *tty, struct file *filp) tty->winsize.ws_row = vc_cons[currcons].d->vc_rows; tty->winsize.ws_col = vc_cons[currcons].d->vc_cols; } + if (vc->vc_utf) + tty->termios->c_iflag |= IUTF8; + else + tty->termios->c_iflag &= ~IUTF8; release_console_sem(); vcs_make_sysfs(tty); return ret; @@ -2918,6 +2922,8 @@ int __init vty_init(void) console_driver->minor_start = 1; console_driver->type = TTY_DRIVER_TYPE_CONSOLE; console_driver->init_termios = tty_std_termios; + if (default_utf8) + console_driver->init_termios.c_iflag |= IUTF8; console_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS; tty_set_operations(console_driver, &con_ops); if (tty_register_driver(console_driver)) diff --git a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c index 2fa43183d3759bc8b2d1ea284ca30984aee44fad..43508d61eb7cf455c03fee1c82d4dfe501fbd260 100644 --- a/drivers/i2c/busses/i2c-amd756.c +++ b/drivers/i2c/busses/i2c-amd756.c @@ -290,7 +290,7 @@ static u32 amd756_func(struct i2c_adapter *adapter) { return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | - I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_PROC_CALL; + I2C_FUNC_SMBUS_BLOCK_DATA; } static const struct i2c_algorithm smbus_algorithm = { diff --git a/drivers/i2c/busses/i2c-au1550.c b/drivers/i2c/busses/i2c-au1550.c index 491718fe46b78a00ac959885fe00745cb682c18a..cae9dc89d88cc0737379cf38f1ce55116f1abbac 100644 --- a/drivers/i2c/busses/i2c-au1550.c +++ b/drivers/i2c/busses/i2c-au1550.c @@ -335,7 +335,7 @@ i2c_au1550_probe(struct platform_device *pdev) goto out_mem; } - priv->psc_base = r->start; + priv->psc_base = CKSEG1ADDR(r->start); priv->xfer_timeout = 200; priv->ack_timeout = 200; diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index 18beb0ad7bf3ad1b9fc703c3c75952fd6017e848..a076129de7e811acb2434864ef2d48fccbeafa3b 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -99,7 +99,7 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing) u32 x; int result = 0; - if (i2c->irq == 0) + if (i2c->irq == NO_IRQ) { while (!(readb(i2c->base + MPC_I2C_SR) & CSR_MIF)) { schedule(); @@ -329,10 +329,9 @@ static int fsl_i2c_probe(struct platform_device *pdev) return -ENOMEM; i2c->irq = platform_get_irq(pdev, 0); - if (i2c->irq < 0) { - result = -ENXIO; - goto fail_get_irq; - } + if (i2c->irq < 0) + i2c->irq = NO_IRQ; /* Use polling */ + i2c->flags = pdata->device_flags; init_waitqueue_head(&i2c->queue); @@ -344,7 +343,7 @@ static int fsl_i2c_probe(struct platform_device *pdev) goto fail_map; } - if (i2c->irq != 0) + if (i2c->irq != NO_IRQ) if ((result = request_irq(i2c->irq, mpc_i2c_isr, IRQF_SHARED, "i2c-mpc", i2c)) < 0) { printk(KERN_ERR @@ -367,12 +366,11 @@ static int fsl_i2c_probe(struct platform_device *pdev) return result; fail_add: - if (i2c->irq != 0) + if (i2c->irq != NO_IRQ) free_irq(i2c->irq, i2c); fail_irq: iounmap(i2c->base); fail_map: - fail_get_irq: kfree(i2c); return result; }; @@ -384,7 +382,7 @@ static int fsl_i2c_remove(struct platform_device *pdev) i2c_del_adapter(&i2c->adap); platform_set_drvdata(pdev, NULL); - if (i2c->irq != 0) + if (i2c->irq != NO_IRQ) free_irq(i2c->irq, i2c); iounmap(i2c->base); diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c index 3dac920e53ea2ab6cf8e07780e0a62d30e35135c..43c9f8df950913a85137e13b124a90df30ae2041 100644 --- a/drivers/i2c/busses/i2c-nforce2.c +++ b/drivers/i2c/busses/i2c-nforce2.c @@ -50,6 +50,7 @@ #include #include #include +#include #include MODULE_LICENSE("GPL"); @@ -109,6 +110,18 @@ struct nforce2_smbus { /* Misc definitions */ #define MAX_TIMEOUT 100 +/* We disable the second SMBus channel on these boards */ +static struct dmi_system_id __devinitdata nforce2_dmi_blacklist2[] = { + { + .ident = "DFI Lanparty NF4 Expert", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "DFI Corp,LTD"), + DMI_MATCH(DMI_BOARD_NAME, "LP UT NF4 Expert"), + }, + }, + { } +}; + static struct pci_driver nforce2_driver; static void nforce2_abort(struct i2c_adapter *adap) @@ -367,10 +380,17 @@ static int __devinit nforce2_probe(struct pci_dev *dev, const struct pci_device_ smbuses[0].base = 0; /* to have a check value */ } /* SMBus adapter 2 */ - res2 = nforce2_probe_smb(dev, 5, NFORCE_PCI_SMB2, &smbuses[1], "SMB2"); - if (res2 < 0) { - dev_err(&dev->dev, "Error probing SMB2.\n"); - smbuses[1].base = 0; /* to have a check value */ + if (dmi_check_system(nforce2_dmi_blacklist2)) { + dev_err(&dev->dev, "Disabling SMB2 for safety reasons.\n"); + res2 = -EPERM; + smbuses[1].base = 0; + } else { + res2 = nforce2_probe_smb(dev, 5, NFORCE_PCI_SMB2, &smbuses[1], + "SMB2"); + if (res2 < 0) { + dev_err(&dev->dev, "Error probing SMB2.\n"); + smbuses[1].base = 0; /* to have a check value */ + } } if ((res1 < 0) && (res2 < 0)) { /* we did not find even one of the SMBuses, so we give up */ diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index fdc9ad805e358528b8599f0dbd4635bb817155e7..ac916596858764481f08afdde261b770be1a1b54 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c @@ -104,10 +104,31 @@ MODULE_PARM_DESC(force_addr, static int piix4_transaction(void); static unsigned short piix4_smba; +static int srvrworks_csb5_delay; static struct pci_driver piix4_driver; static struct i2c_adapter piix4_adapter; -static struct dmi_system_id __devinitdata piix4_dmi_table[] = { +static struct dmi_system_id __devinitdata piix4_dmi_blacklist[] = { + { + .ident = "Sapphire AM2RD790", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "SAPPHIRE Inc."), + DMI_MATCH(DMI_BOARD_NAME, "PC-AM2RD790"), + }, + }, + { + .ident = "DFI Lanparty UT 790FX", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "DFI Inc."), + DMI_MATCH(DMI_BOARD_NAME, "LP UT 790FX"), + }, + }, + { } +}; + +/* The IBM entry is in a separate table because we only check it + on Intel-based systems */ +static struct dmi_system_id __devinitdata piix4_dmi_ibm[] = { { .ident = "IBM", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), }, @@ -122,8 +143,20 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev, dev_info(&PIIX4_dev->dev, "Found %s device\n", pci_name(PIIX4_dev)); + if ((PIIX4_dev->vendor == PCI_VENDOR_ID_SERVERWORKS) && + (PIIX4_dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5)) + srvrworks_csb5_delay = 1; + + /* On some motherboards, it was reported that accessing the SMBus + caused severe hardware problems */ + if (dmi_check_system(piix4_dmi_blacklist)) { + dev_err(&PIIX4_dev->dev, + "Accessing the SMBus on this system is unsafe!\n"); + return -EPERM; + } + /* Don't access SMBus on IBM systems which get corrupted eeproms */ - if (dmi_check_system(piix4_dmi_table) && + if (dmi_check_system(piix4_dmi_ibm) && PIIX4_dev->vendor == PCI_VENDOR_ID_INTEL) { dev_err(&PIIX4_dev->dev, "IBM system detected; this module " "may corrupt your serial eeprom! Refusing to load " @@ -230,10 +263,14 @@ static int piix4_transaction(void) outb_p(inb(SMBHSTCNT) | 0x040, SMBHSTCNT); /* We will always wait for a fraction of a second! (See PIIX4 docs errata) */ - do { + if (srvrworks_csb5_delay) /* Extra delay for SERVERWORKS_CSB5 */ + msleep(2); + else + msleep(1); + + while ((timeout++ < MAX_TIMEOUT) && + ((temp = inb_p(SMBHSTSTS)) & 0x01)) msleep(1); - temp = inb_p(SMBHSTSTS); - } while ((temp & 0x01) && (timeout++ < MAX_TIMEOUT)); /* If the SMBus is still busy, we give up */ if (timeout >= MAX_TIMEOUT) { diff --git a/drivers/i2c/busses/i2c-sibyte.c b/drivers/i2c/busses/i2c-sibyte.c index 8fbbdb4c2f35d0c81c2252f84b2e99ade7ca36a4..114634da6c6e9f3a7bd7ca77bf04476fc1c2818c 100644 --- a/drivers/i2c/busses/i2c-sibyte.c +++ b/drivers/i2c/busses/i2c-sibyte.c @@ -132,14 +132,14 @@ static const struct i2c_algorithm i2c_sibyte_algo = { /* * registering functions to load algorithms at runtime */ -int __init i2c_sibyte_add_bus(struct i2c_adapter *i2c_adap, int speed) +static int __init i2c_sibyte_add_bus(struct i2c_adapter *i2c_adap, int speed) { struct i2c_algo_sibyte_data *adap = i2c_adap->algo_data; - /* register new adapter to i2c module... */ + /* Register new adapter to i2c module... */ i2c_adap->algo = &i2c_sibyte_algo; - /* Set the frequency to 100 kHz */ + /* Set the requested frequency. */ csr_out32(speed, SMB_CSR(adap,R_SMB_FREQ)); csr_out32(0, SMB_CSR(adap,R_SMB_CONTROL)); diff --git a/drivers/i2c/chips/max6875.c b/drivers/i2c/chips/max6875.c index fb7ea5637ecaef03f3ccdf0338232431da118087..cf507b3f60f3567888bc4c964767744652bec99d 100644 --- a/drivers/i2c/chips/max6875.c +++ b/drivers/i2c/chips/max6875.c @@ -207,9 +207,6 @@ static int max6875_detect(struct i2c_adapter *adapter, int address, int kind) fake_client->flags = 0; strlcpy(fake_client->name, "max6875 subclient", I2C_NAME_SIZE); - /* Prevent 24RF08 corruption (in case of user error) */ - i2c_smbus_write_quick(real_client, 0); - if ((err = i2c_attach_client(real_client)) != 0) goto exit_kfree2; diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 26384daccb968180c369207e70f35e0a3598e04d..d0175f4f8fc683941057bf4866e97a8a9abdcfd3 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -74,10 +74,7 @@ static int i2c_device_match(struct device *dev, struct device_driver *drv) if (driver->id_table) return i2c_match_id(driver->id_table, client) != NULL; - /* new style drivers use the same kind of driver matching policy - * as platform devices or SPI: compare device and driver IDs. - */ - return strcmp(client->driver_name, drv->name) == 0; + return 0; } #ifdef CONFIG_HOTPLUG @@ -91,14 +88,9 @@ static int i2c_device_uevent(struct device *dev, struct kobj_uevent_env *env) if (dev->driver) return 0; - if (client->driver_name[0]) { - if (add_uevent_var(env, "MODALIAS=%s", client->driver_name)) - return -ENOMEM; - } else { - if (add_uevent_var(env, "MODALIAS=%s%s", - I2C_MODULE_PREFIX, client->name)) - return -ENOMEM; - } + if (add_uevent_var(env, "MODALIAS=%s%s", + I2C_MODULE_PREFIX, client->name)) + return -ENOMEM; dev_dbg(dev, "uevent\n"); return 0; } @@ -206,9 +198,7 @@ static ssize_t show_client_name(struct device *dev, struct device_attribute *att static ssize_t show_modalias(struct device *dev, struct device_attribute *attr, char *buf) { struct i2c_client *client = to_i2c_client(dev); - return client->driver_name[0] - ? sprintf(buf, "%s\n", client->driver_name) - : sprintf(buf, "%s%s\n", I2C_MODULE_PREFIX, client->name); + return sprintf(buf, "%s%s\n", I2C_MODULE_PREFIX, client->name); } static struct device_attribute i2c_dev_attrs[] = { @@ -282,8 +272,6 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info) client->addr = info->addr; client->irq = info->irq; - strlcpy(client->driver_name, info->driver_name, - sizeof(client->driver_name)); strlcpy(client->name, info->type, sizeof(client->name)); /* a new style driver may be bound to this device when we @@ -327,6 +315,11 @@ void i2c_unregister_device(struct i2c_client *client) EXPORT_SYMBOL_GPL(i2c_unregister_device); +static const struct i2c_device_id dummy_id[] = { + { "dummy", 0 }, + { }, +}; + static int dummy_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -342,13 +335,13 @@ static struct i2c_driver dummy_driver = { .driver.name = "dummy", .probe = dummy_probe, .remove = dummy_remove, + .id_table = dummy_id, }; /** * i2c_new_dummy - return a new i2c device bound to a dummy driver * @adapter: the adapter managing the device * @address: seven bit address to be used - * @type: optional label used for i2c_client.name * Context: can sleep * * This returns an I2C client bound to the "dummy" driver, intended for use @@ -364,15 +357,12 @@ static struct i2c_driver dummy_driver = { * i2c_unregister_device(); or NULL to indicate an error. */ struct i2c_client * -i2c_new_dummy(struct i2c_adapter *adapter, u16 address, const char *type) +i2c_new_dummy(struct i2c_adapter *adapter, u16 address) { struct i2c_board_info info = { - .driver_name = "dummy", - .addr = address, + I2C_BOARD_INFO("dummy", address), }; - if (type) - strlcpy(info.type, type, sizeof info.type); return i2c_new_device(adapter, &info); } EXPORT_SYMBOL_GPL(i2c_new_dummy); diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index f702f9152ce6992ba91ef2702133f9740d432f54..b4f3aefa12b6935f7435a2ec67a177f57bd6b991 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -1,8 +1,6 @@ # # IDE ATA ATAPI Block device driver configuration # -# Andre Hedrick -# # Select HAVE_IDE if IDE is supported config HAVE_IDE @@ -335,7 +333,7 @@ config BLK_DEV_CMD640 This driver will work automatically in PCI based systems (most new systems have PCI slots). But if your system uses VESA local bus (VLB) instead of PCI, you must also supply a kernel boot parameter - to enable the CMD640 bugfix/support: "ide0=cmd640_vlb". (Try "man + to enable the CMD640 bugfix/support: "cmd640.probe_vlb". (Try "man bootparam" or see the documentation of your boot loader about how to pass options to the kernel.) @@ -457,27 +455,11 @@ config BLK_DEV_ALI15X3 onboard chipsets. It also tests for Simplex mode and enables normal dual channel support. - If you say Y here, you also need to say Y to "Use DMA by default - when available", above. Please read the comments at the top of + Please read the comments at the top of . If unsure, say N. -config WDC_ALI15X3 - bool "ALI M15x3 WDC support (DANGEROUS)" - depends on BLK_DEV_ALI15X3 - ---help--- - This allows for UltraDMA support for WDC drives that ignore CRC - checking. You are a fool for enabling this option, but there have - been requests. DO NOT COMPLAIN IF YOUR DRIVE HAS FS CORRUPTION, IF - YOU ENABLE THIS! No one will listen, just laugh for ignoring this - SERIOUS WARNING. - - Using this option can allow WDC drives to run at ATA-4/5 transfer - rates with only an ATA-2 support structure. - - SAY N! - config BLK_DEV_AMD74XX tristate "AMD and nVidia IDE support" depends on !ARM @@ -520,9 +502,6 @@ config BLK_DEV_CY82C693 This driver adds detection and support for the CY82C693 chipset used on Digital's PC-Alpha 164SX boards. - If you say Y here, you need to say Y to "Use DMA by default - when available" as well. - config BLK_DEV_CS5520 tristate "Cyrix CS5510/20 MediaGX chipset support (VERY EXPERIMENTAL)" depends on EXPERIMENTAL @@ -613,13 +592,12 @@ config BLK_DEV_SC1200 National SCx200 series of embedded x86 "Geode" systems. config BLK_DEV_PIIX - tristate "Intel PIIXn chipsets support" + tristate "Intel PIIX/ICH chipsets support" select BLK_DEV_IDEDMA_PCI help - This driver adds explicit support for Intel PIIX and ICH chips - and also for the Efar Victory66 (slc90e66) chip. This allows - the kernel to change PIO, DMA and UDMA speeds and to configure - the chip to optimum performance. + This driver adds explicit support for Intel PIIX and ICH chips. + This allows the kernel to change PIO, DMA and UDMA speeds and to + configure the chip to optimum performance. config BLK_DEV_IT8213 tristate "IT8213 IDE support" @@ -657,11 +635,7 @@ config BLK_DEV_PDC202XX_OLD happen if the BIOS revisions of all installed cards (three-max) do not match, the driver attempts to do dynamic tuning of the chipset at boot-time for max-speed. Ultra33 BIOS 1.25 or newer is required - for more than one card. This card may require that you say Y to - "Special UDMA Feature". - - If you say Y here, you need to say Y to "Use DMA by default when - available" as well. + for more than one card. Please read the comments at the top of . @@ -710,9 +684,6 @@ config BLK_DEV_SIS5513 ATA100: SiS635, SiS645, SiS650, SiS730, SiS735, SiS740, SiS745, SiS750 - If you say Y here, you need to say Y to "Use DMA by default when - available" as well. - Please read the comments at the top of . config BLK_DEV_SL82C105 @@ -734,9 +705,6 @@ config BLK_DEV_SLC90E66 and it will handle timing cycles. Since this is an improved look-a-like to the PIIX4 it should be a nice addition. - If you say Y here, you need to say Y to "Use DMA by default when - available" as well. - Please read the comments at the top of . @@ -888,17 +856,17 @@ config BLK_DEV_IDEDOUBLER bool "Amiga IDE Doubler support (EXPERIMENTAL)" depends on BLK_DEV_GAYLE && EXPERIMENTAL ---help--- - This driver provides support for the so-called `IDE doublers' (made + This feature provides support for the so-called `IDE doublers' (made by various manufacturers, e.g. Eyetech) that can be connected to the on-board IDE interface of some Amiga models. Using such an IDE doubler, you can connect up to four instead of two IDE devices to the Amiga's on-board IDE interface. Note that the normal Amiga Gayle IDE driver may not work correctly - if you have an IDE doubler and don't enable this driver! + if you have an IDE doubler and don't enable this feature! - Say Y if you have an IDE doubler. The driver is enabled at kernel - runtime using the "ide=doubler" kernel boot parameter. + Say Y if you have an IDE doubler. The feature is enabled at kernel + runtime using the "gayle.doubler" kernel boot parameter. config BLK_DEV_BUDDHA tristate "Buddha/Catweasel/X-Surf IDE interface support (EXPERIMENTAL)" diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index 57d9a9a79a6f845842a9b1baeb7d20254754dda8..0daf923541ffbc50fe7a9e139e8f172d882b6c78 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -95,7 +95,7 @@ void SELECT_DRIVE (ide_drive_t *drive) hwif->OUTB(drive->select.all, hwif->io_ports.device_addr); } -void SELECT_MASK (ide_drive_t *drive, int mask) +static void SELECT_MASK(ide_drive_t *drive, int mask) { const struct ide_port_ops *port_ops = drive->hwif->port_ops; diff --git a/drivers/ide/legacy/macide.c b/drivers/ide/legacy/macide.c index 1f527bbf8d96f9ebb34637223bce6bb07a8db82b..caa2632dd08e1f96d5e5e4379b23ea9ea8cc3563 100644 --- a/drivers/ide/legacy/macide.c +++ b/drivers/ide/legacy/macide.c @@ -95,6 +95,9 @@ static int __init macide_init(void) int irq; hw_regs_t hw; + if (!MACH_IS_MAC) + return -ENODEV; + switch (macintosh_config->ide_type) { case MAC_IDE_QUADRA: base = IDE_BASE; diff --git a/drivers/ide/mips/swarm.c b/drivers/ide/mips/swarm.c index 712d17bdd4705f8ff2d07bf20371c702de79a564..52fee3d2771a7ce7bfdb95592e44b898d9288417 100644 --- a/drivers/ide/mips/swarm.c +++ b/drivers/ide/mips/swarm.c @@ -4,7 +4,7 @@ * Author: Manish Lachwani, mlachwani@mvista.com * Copyright (C) 2004 MIPS Technologies, Inc. All rights reserved. * Author: Maciej W. Rozycki - * Copyright (c) 2006 Maciej W. Rozycki + * Copyright (c) 2006, 2008 Maciej W. Rozycki * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -70,8 +70,9 @@ static int __devinit swarm_ide_probe(struct device *dev) ide_hwif_t *hwif; u8 __iomem *base; phys_t offset, size; + hw_regs_t hw; int i; - u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; + u8 idx[] = { 0xff, 0xff, 0xff, 0xff }; if (!SIBYTE_HAVE_IDE) return -ENODEV; @@ -112,14 +113,15 @@ static int __devinit swarm_ide_probe(struct device *dev) hwif->host_flags = IDE_HFLAG_MMIO; default_hwif_mmiops(hwif); - hwif->chipset = ide_generic; - for (i = 0; i <= 7; i++) - hwif->io_ports_array[i] = + hw.io_ports_array[i] = (unsigned long)(base + ((0x1f0 + i) << 5)); - hwif->io_ports.ctl_addr = + hw.io_ports.ctl_addr = (unsigned long)(base + (0x3f6 << 5)); - hwif->irq = K_INT_GB_IDE; + hw.irq = K_INT_GB_IDE; + hw.chipset = ide_generic; + + ide_init_port_hw(hwif, &hw); idx[0] = hwif->index; diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c index c1922f9cfe80606e82a1ca2f38ae12e42877fc18..f2129d5e07f2683215eb20940529d457ae04cd3b 100644 --- a/drivers/ide/pci/alim15x3.c +++ b/drivers/ide/pci/alim15x3.c @@ -38,6 +38,16 @@ #include +/* + * Allow UDMA on M1543C-E chipset for WDC disks that ignore CRC checking + * (this is DANGEROUS and could result in data corruption). + */ +static int wdc_udma; + +module_param(wdc_udma, bool, 0); +MODULE_PARM_DESC(wdc_udma, + "allow UDMA on M1543C-E chipset for WDC disks (DANGEROUS)"); + /* * ALi devices are not plug in. Otherwise these static values would * need to go. They ought to go away anyway @@ -76,11 +86,6 @@ static void ali_set_pio_mode(ide_drive_t *drive, const u8 pio) a_clc = 0; c_time = ide_pio_timings[pio].cycle_time; -#if 0 - if ((r_clc = ((c_time - s_time - a_time) * bus_speed + 999) / 1000) >= 16) - r_clc = 0; -#endif - if (!(r_clc = (c_time * bus_speed + 999) / 1000 - a_clc - s_clc)) { r_clc = 1; } else { @@ -110,16 +115,6 @@ static void ali_set_pio_mode(ide_drive_t *drive, const u8 pio) pci_write_config_byte(dev, port, s_clc); pci_write_config_byte(dev, port+drive->select.b.unit+2, (a_clc << 4) | r_clc); local_irq_restore(flags); - - /* - * setup active rec - * { 70, 165, 365 }, PIO Mode 0 - * { 50, 125, 208 }, PIO Mode 1 - * { 30, 100, 110 }, PIO Mode 2 - * { 30, 80, 70 }, PIO Mode 3 with IORDY - * { 25, 70, 25 }, PIO Mode 4 with IORDY ns - * { 20, 50, 30 } PIO Mode 5 with IORDY (nonstandard) - */ } /** @@ -131,9 +126,7 @@ static void ali_set_pio_mode(ide_drive_t *drive, const u8 pio) * The actual rules for the ALi are: * No UDMA on revisions <= 0x20 * Disk only for revisions < 0xC2 - * Not WDC drives for revisions < 0xC2 - * - * FIXME: WDC ifdef needs to die + * Not WDC drives on M1543C-E (?) */ static u8 ali_udma_filter(ide_drive_t *drive) @@ -141,10 +134,9 @@ static u8 ali_udma_filter(ide_drive_t *drive) if (m5229_revision > 0x20 && m5229_revision < 0xC2) { if (drive->media != ide_disk) return 0; -#ifndef CONFIG_WDC_ALI15X3 - if (chip_is_1543c_e && strstr(drive->id->model, "WDC ")) + if (chip_is_1543c_e && strstr(drive->id->model, "WDC ") && + wdc_udma == 0) return 0; -#endif } return drive->hwif->ultra_mask; @@ -537,17 +529,9 @@ static const struct ide_port_info ali15x3_chipset __devinitdata = { static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - static struct pci_device_id ati_rs100[] = { - { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS100) }, - { }, - }; - struct ide_port_info d = ali15x3_chipset; u8 rev = dev->revision, idx = id->driver_data; - if (pci_dev_present(ati_rs100)) - printk(KERN_WARNING "alim15x3: ATI Radeon IGP Northbridge is not yet fully tested.\n"); - /* don't use LBA48 DMA on ALi devices before rev 0xC5 */ if (rev <= 0xC4) d.host_flags |= IDE_HFLAG_NO_LBA48_DMA; diff --git a/drivers/ide/pci/cs5520.c b/drivers/ide/pci/cs5520.c index 17669a434438bccbd596e23b4fdc51fdfb2f679e..992b1cf8db6976be67833338a6932ba19593e4aa 100644 --- a/drivers/ide/pci/cs5520.c +++ b/drivers/ide/pci/cs5520.c @@ -119,6 +119,7 @@ static const struct ide_dma_ops cs5520_dma_ops = { .dma_timeout = ide_dma_timeout, }; +/* FIXME: VDMA is disabled because it caused system hangs */ #define DECLARE_CS_DEV(name_str) \ { \ .name = name_str, \ @@ -126,7 +127,6 @@ static const struct ide_dma_ops cs5520_dma_ops = { .dma_ops = &cs5520_dma_ops, \ .host_flags = IDE_HFLAG_ISA_PORTS | \ IDE_HFLAG_CS5520 | \ - IDE_HFLAG_VDMA | \ IDE_HFLAG_NO_ATAPI_DMA | \ IDE_HFLAG_ABUSE_SET_DMA_MODE, \ .pio_mask = ATA_PIO4, \ diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.c b/drivers/infiniband/hw/cxgb3/cxio_hal.c index 5fd8506a865735a87df96738a4677ad227e8e381..3f441fc57c1719c6991d028dd5a0979760aa2d30 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_hal.c +++ b/drivers/infiniband/hw/cxgb3/cxio_hal.c @@ -405,11 +405,11 @@ int cxio_flush_sq(struct t3_wq *wq, struct t3_cq *cq, int count) struct t3_swsq *sqp = wq->sq + Q_PTR2IDX(wq->sq_rptr, wq->sq_size_log2); ptr = wq->sq_rptr + count; - sqp += count; + sqp = wq->sq + Q_PTR2IDX(ptr, wq->sq_size_log2); while (ptr != wq->sq_wptr) { insert_sq_cqe(wq, cq, sqp); - sqp++; ptr++; + sqp = wq->sq + Q_PTR2IDX(ptr, wq->sq_size_log2); flushed++; } return flushed; @@ -588,7 +588,7 @@ static int cxio_hal_destroy_ctrl_qp(struct cxio_rdev *rdev_p) * caller aquires the ctrl_qp lock before the call */ static int cxio_hal_ctrl_qp_write_mem(struct cxio_rdev *rdev_p, u32 addr, - u32 len, void *data, int completion) + u32 len, void *data) { u32 i, nr_wqe, copy_len; u8 *copy_data; @@ -624,7 +624,7 @@ static int cxio_hal_ctrl_qp_write_mem(struct cxio_rdev *rdev_p, u32 addr, flag = 0; if (i == (nr_wqe - 1)) { /* last WQE */ - flag = completion ? T3_COMPLETION_FLAG : 0; + flag = T3_COMPLETION_FLAG; if (len % 32) utx_len = len / 32 + 1; else @@ -683,21 +683,20 @@ static int cxio_hal_ctrl_qp_write_mem(struct cxio_rdev *rdev_p, u32 addr, return 0; } -/* IN: stag key, pdid, perm, zbva, to, len, page_size, pbl, and pbl_size - * OUT: stag index, actual pbl_size, pbl_addr allocated. +/* IN: stag key, pdid, perm, zbva, to, len, page_size, pbl_size and pbl_addr + * OUT: stag index * TBD: shared memory region support */ static int __cxio_tpt_op(struct cxio_rdev *rdev_p, u32 reset_tpt_entry, u32 *stag, u8 stag_state, u32 pdid, enum tpt_mem_type type, enum tpt_mem_perm perm, - u32 zbva, u64 to, u32 len, u8 page_size, __be64 *pbl, - u32 *pbl_size, u32 *pbl_addr) + u32 zbva, u64 to, u32 len, u8 page_size, + u32 pbl_size, u32 pbl_addr) { int err; struct tpt_entry tpt; u32 stag_idx; u32 wptr; - int rereg = (*stag != T3_STAG_UNSET); stag_state = stag_state > 0; stag_idx = (*stag) >> 8; @@ -711,30 +710,8 @@ static int __cxio_tpt_op(struct cxio_rdev *rdev_p, u32 reset_tpt_entry, PDBG("%s stag_state 0x%0x type 0x%0x pdid 0x%0x, stag_idx 0x%x\n", __func__, stag_state, type, pdid, stag_idx); - if (reset_tpt_entry) - cxio_hal_pblpool_free(rdev_p, *pbl_addr, *pbl_size << 3); - else if (!rereg) { - *pbl_addr = cxio_hal_pblpool_alloc(rdev_p, *pbl_size << 3); - if (!*pbl_addr) { - return -ENOMEM; - } - } - mutex_lock(&rdev_p->ctrl_qp.lock); - /* write PBL first if any - update pbl only if pbl list exist */ - if (pbl) { - - PDBG("%s *pdb_addr 0x%x, pbl_base 0x%x, pbl_size %d\n", - __func__, *pbl_addr, rdev_p->rnic_info.pbl_base, - *pbl_size); - err = cxio_hal_ctrl_qp_write_mem(rdev_p, - (*pbl_addr >> 5), - (*pbl_size << 3), pbl, 0); - if (err) - goto ret; - } - /* write TPT entry */ if (reset_tpt_entry) memset(&tpt, 0, sizeof(tpt)); @@ -749,23 +726,23 @@ static int __cxio_tpt_op(struct cxio_rdev *rdev_p, u32 reset_tpt_entry, V_TPT_ADDR_TYPE((zbva ? TPT_ZBTO : TPT_VATO)) | V_TPT_PAGE_SIZE(page_size)); tpt.rsvd_pbl_addr = reset_tpt_entry ? 0 : - cpu_to_be32(V_TPT_PBL_ADDR(PBL_OFF(rdev_p, *pbl_addr)>>3)); + cpu_to_be32(V_TPT_PBL_ADDR(PBL_OFF(rdev_p, pbl_addr)>>3)); tpt.len = cpu_to_be32(len); tpt.va_hi = cpu_to_be32((u32) (to >> 32)); tpt.va_low_or_fbo = cpu_to_be32((u32) (to & 0xFFFFFFFFULL)); tpt.rsvd_bind_cnt_or_pstag = 0; tpt.rsvd_pbl_size = reset_tpt_entry ? 0 : - cpu_to_be32(V_TPT_PBL_SIZE((*pbl_size) >> 2)); + cpu_to_be32(V_TPT_PBL_SIZE(pbl_size >> 2)); } err = cxio_hal_ctrl_qp_write_mem(rdev_p, stag_idx + (rdev_p->rnic_info.tpt_base >> 5), - sizeof(tpt), &tpt, 1); + sizeof(tpt), &tpt); /* release the stag index to free pool */ if (reset_tpt_entry) cxio_hal_put_stag(rdev_p->rscp, stag_idx); -ret: + wptr = rdev_p->ctrl_qp.wptr; mutex_unlock(&rdev_p->ctrl_qp.lock); if (!err) @@ -776,44 +753,67 @@ ret: return err; } +int cxio_write_pbl(struct cxio_rdev *rdev_p, __be64 *pbl, + u32 pbl_addr, u32 pbl_size) +{ + u32 wptr; + int err; + + PDBG("%s *pdb_addr 0x%x, pbl_base 0x%x, pbl_size %d\n", + __func__, pbl_addr, rdev_p->rnic_info.pbl_base, + pbl_size); + + mutex_lock(&rdev_p->ctrl_qp.lock); + err = cxio_hal_ctrl_qp_write_mem(rdev_p, pbl_addr >> 5, pbl_size << 3, + pbl); + wptr = rdev_p->ctrl_qp.wptr; + mutex_unlock(&rdev_p->ctrl_qp.lock); + if (err) + return err; + + if (wait_event_interruptible(rdev_p->ctrl_qp.waitq, + SEQ32_GE(rdev_p->ctrl_qp.rptr, + wptr))) + return -ERESTARTSYS; + + return 0; +} + int cxio_register_phys_mem(struct cxio_rdev *rdev_p, u32 *stag, u32 pdid, enum tpt_mem_perm perm, u32 zbva, u64 to, u32 len, - u8 page_size, __be64 *pbl, u32 *pbl_size, - u32 *pbl_addr) + u8 page_size, u32 pbl_size, u32 pbl_addr) { *stag = T3_STAG_UNSET; return __cxio_tpt_op(rdev_p, 0, stag, 1, pdid, TPT_NON_SHARED_MR, perm, - zbva, to, len, page_size, pbl, pbl_size, pbl_addr); + zbva, to, len, page_size, pbl_size, pbl_addr); } int cxio_reregister_phys_mem(struct cxio_rdev *rdev_p, u32 *stag, u32 pdid, enum tpt_mem_perm perm, u32 zbva, u64 to, u32 len, - u8 page_size, __be64 *pbl, u32 *pbl_size, - u32 *pbl_addr) + u8 page_size, u32 pbl_size, u32 pbl_addr) { return __cxio_tpt_op(rdev_p, 0, stag, 1, pdid, TPT_NON_SHARED_MR, perm, - zbva, to, len, page_size, pbl, pbl_size, pbl_addr); + zbva, to, len, page_size, pbl_size, pbl_addr); } int cxio_dereg_mem(struct cxio_rdev *rdev_p, u32 stag, u32 pbl_size, u32 pbl_addr) { - return __cxio_tpt_op(rdev_p, 1, &stag, 0, 0, 0, 0, 0, 0ULL, 0, 0, NULL, - &pbl_size, &pbl_addr); + return __cxio_tpt_op(rdev_p, 1, &stag, 0, 0, 0, 0, 0, 0ULL, 0, 0, + pbl_size, pbl_addr); } int cxio_allocate_window(struct cxio_rdev *rdev_p, u32 * stag, u32 pdid) { - u32 pbl_size = 0; *stag = T3_STAG_UNSET; return __cxio_tpt_op(rdev_p, 0, stag, 0, pdid, TPT_MW, 0, 0, 0ULL, 0, 0, - NULL, &pbl_size, NULL); + 0, 0); } int cxio_deallocate_window(struct cxio_rdev *rdev_p, u32 stag) { - return __cxio_tpt_op(rdev_p, 1, &stag, 0, 0, 0, 0, 0, 0ULL, 0, 0, NULL, - NULL, NULL); + return __cxio_tpt_op(rdev_p, 1, &stag, 0, 0, 0, 0, 0, 0ULL, 0, 0, + 0, 0); } int cxio_rdma_init(struct cxio_rdev *rdev_p, struct t3_rdma_init_attr *attr) diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.h b/drivers/infiniband/hw/cxgb3/cxio_hal.h index 69ab08ebc680166292ffe8f4b040f96b21dcabb3..6e128f6bab05140282e1d86930aaab98ddb4cc0c 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_hal.h +++ b/drivers/infiniband/hw/cxgb3/cxio_hal.h @@ -154,14 +154,14 @@ int cxio_create_qp(struct cxio_rdev *rdev, u32 kernel_domain, struct t3_wq *wq, int cxio_destroy_qp(struct cxio_rdev *rdev, struct t3_wq *wq, struct cxio_ucontext *uctx); int cxio_peek_cq(struct t3_wq *wr, struct t3_cq *cq, int opcode); +int cxio_write_pbl(struct cxio_rdev *rdev_p, __be64 *pbl, + u32 pbl_addr, u32 pbl_size); int cxio_register_phys_mem(struct cxio_rdev *rdev, u32 * stag, u32 pdid, enum tpt_mem_perm perm, u32 zbva, u64 to, u32 len, - u8 page_size, __be64 *pbl, u32 *pbl_size, - u32 *pbl_addr); + u8 page_size, u32 pbl_size, u32 pbl_addr); int cxio_reregister_phys_mem(struct cxio_rdev *rdev, u32 * stag, u32 pdid, enum tpt_mem_perm perm, u32 zbva, u64 to, u32 len, - u8 page_size, __be64 *pbl, u32 *pbl_size, - u32 *pbl_addr); + u8 page_size, u32 pbl_size, u32 pbl_addr); int cxio_dereg_mem(struct cxio_rdev *rdev, u32 stag, u32 pbl_size, u32 pbl_addr); int cxio_allocate_window(struct cxio_rdev *rdev, u32 * stag, u32 pdid); diff --git a/drivers/infiniband/hw/cxgb3/cxio_resource.c b/drivers/infiniband/hw/cxgb3/cxio_resource.c index 45ed4f25ef785b1efa23cd6f335d8569e4c81c55..bd233c087653de5fed49dfbbf95f4d53cb43b7d0 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_resource.c +++ b/drivers/infiniband/hw/cxgb3/cxio_resource.c @@ -250,7 +250,6 @@ void cxio_hal_destroy_resource(struct cxio_hal_resource *rscp) */ #define MIN_PBL_SHIFT 8 /* 256B == min PBL size (32 entries) */ -#define PBL_CHUNK 2*1024*1024 u32 cxio_hal_pblpool_alloc(struct cxio_rdev *rdev_p, int size) { @@ -267,14 +266,35 @@ void cxio_hal_pblpool_free(struct cxio_rdev *rdev_p, u32 addr, int size) int cxio_hal_pblpool_create(struct cxio_rdev *rdev_p) { - unsigned long i; + unsigned pbl_start, pbl_chunk; + rdev_p->pbl_pool = gen_pool_create(MIN_PBL_SHIFT, -1); - if (rdev_p->pbl_pool) - for (i = rdev_p->rnic_info.pbl_base; - i <= rdev_p->rnic_info.pbl_top - PBL_CHUNK + 1; - i += PBL_CHUNK) - gen_pool_add(rdev_p->pbl_pool, i, PBL_CHUNK, -1); - return rdev_p->pbl_pool ? 0 : -ENOMEM; + if (!rdev_p->pbl_pool) + return -ENOMEM; + + pbl_start = rdev_p->rnic_info.pbl_base; + pbl_chunk = rdev_p->rnic_info.pbl_top - pbl_start + 1; + + while (pbl_start < rdev_p->rnic_info.pbl_top) { + pbl_chunk = min(rdev_p->rnic_info.pbl_top - pbl_start + 1, + pbl_chunk); + if (gen_pool_add(rdev_p->pbl_pool, pbl_start, pbl_chunk, -1)) { + PDBG("%s failed to add PBL chunk (%x/%x)\n", + __func__, pbl_start, pbl_chunk); + if (pbl_chunk <= 1024 << MIN_PBL_SHIFT) { + printk(KERN_WARNING MOD "%s: Failed to add all PBL chunks (%x/%x)\n", + __func__, pbl_start, rdev_p->rnic_info.pbl_top - pbl_start); + return 0; + } + pbl_chunk >>= 1; + } else { + PDBG("%s added PBL chunk (%x/%x)\n", + __func__, pbl_start, pbl_chunk); + pbl_start += pbl_chunk; + } + } + + return 0; } void cxio_hal_pblpool_destroy(struct cxio_rdev *rdev_p) diff --git a/drivers/infiniband/hw/cxgb3/iwch_mem.c b/drivers/infiniband/hw/cxgb3/iwch_mem.c index 58c3d61bcd14a24ec0623b0cec8d8eb6771bbaa9..ec49a5cbdebbc19705968069b58d2ab9f98d7d8e 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_mem.c +++ b/drivers/infiniband/hw/cxgb3/iwch_mem.c @@ -35,17 +35,26 @@ #include #include "cxio_hal.h" +#include "cxio_resource.h" #include "iwch.h" #include "iwch_provider.h" -int iwch_register_mem(struct iwch_dev *rhp, struct iwch_pd *php, - struct iwch_mr *mhp, - int shift, - __be64 *page_list) +static void iwch_finish_mem_reg(struct iwch_mr *mhp, u32 stag) { - u32 stag; u32 mmid; + mhp->attr.state = 1; + mhp->attr.stag = stag; + mmid = stag >> 8; + mhp->ibmr.rkey = mhp->ibmr.lkey = stag; + insert_handle(mhp->rhp, &mhp->rhp->mmidr, mhp, mmid); + PDBG("%s mmid 0x%x mhp %p\n", __func__, mmid, mhp); +} + +int iwch_register_mem(struct iwch_dev *rhp, struct iwch_pd *php, + struct iwch_mr *mhp, int shift) +{ + u32 stag; if (cxio_register_phys_mem(&rhp->rdev, &stag, mhp->attr.pdid, @@ -53,28 +62,21 @@ int iwch_register_mem(struct iwch_dev *rhp, struct iwch_pd *php, mhp->attr.zbva, mhp->attr.va_fbo, mhp->attr.len, - shift-12, - page_list, - &mhp->attr.pbl_size, &mhp->attr.pbl_addr)) + shift - 12, + mhp->attr.pbl_size, mhp->attr.pbl_addr)) return -ENOMEM; - mhp->attr.state = 1; - mhp->attr.stag = stag; - mmid = stag >> 8; - mhp->ibmr.rkey = mhp->ibmr.lkey = stag; - insert_handle(rhp, &rhp->mmidr, mhp, mmid); - PDBG("%s mmid 0x%x mhp %p\n", __func__, mmid, mhp); + + iwch_finish_mem_reg(mhp, stag); + return 0; } int iwch_reregister_mem(struct iwch_dev *rhp, struct iwch_pd *php, struct iwch_mr *mhp, int shift, - __be64 *page_list, int npages) { u32 stag; - u32 mmid; - /* We could support this... */ if (npages > mhp->attr.pbl_size) @@ -87,19 +89,40 @@ int iwch_reregister_mem(struct iwch_dev *rhp, struct iwch_pd *php, mhp->attr.zbva, mhp->attr.va_fbo, mhp->attr.len, - shift-12, - page_list, - &mhp->attr.pbl_size, &mhp->attr.pbl_addr)) + shift - 12, + mhp->attr.pbl_size, mhp->attr.pbl_addr)) return -ENOMEM; - mhp->attr.state = 1; - mhp->attr.stag = stag; - mmid = stag >> 8; - mhp->ibmr.rkey = mhp->ibmr.lkey = stag; - insert_handle(rhp, &rhp->mmidr, mhp, mmid); - PDBG("%s mmid 0x%x mhp %p\n", __func__, mmid, mhp); + + iwch_finish_mem_reg(mhp, stag); + + return 0; +} + +int iwch_alloc_pbl(struct iwch_mr *mhp, int npages) +{ + mhp->attr.pbl_addr = cxio_hal_pblpool_alloc(&mhp->rhp->rdev, + npages << 3); + + if (!mhp->attr.pbl_addr) + return -ENOMEM; + + mhp->attr.pbl_size = npages; + return 0; } +void iwch_free_pbl(struct iwch_mr *mhp) +{ + cxio_hal_pblpool_free(&mhp->rhp->rdev, mhp->attr.pbl_addr, + mhp->attr.pbl_size << 3); +} + +int iwch_write_pbl(struct iwch_mr *mhp, __be64 *pages, int npages, int offset) +{ + return cxio_write_pbl(&mhp->rhp->rdev, pages, + mhp->attr.pbl_addr + (offset << 3), npages); +} + int build_phys_page_list(struct ib_phys_buf *buffer_list, int num_phys_buf, u64 *iova_start, diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c index d07d3a377b5f2b02644e2164db56b858ac898e07..8934178a23ee6d615ed2a7badfd1758c3aab3f6b 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_provider.c +++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c @@ -442,6 +442,7 @@ static int iwch_dereg_mr(struct ib_mr *ib_mr) mmid = mhp->attr.stag >> 8; cxio_dereg_mem(&rhp->rdev, mhp->attr.stag, mhp->attr.pbl_size, mhp->attr.pbl_addr); + iwch_free_pbl(mhp); remove_handle(rhp, &rhp->mmidr, mmid); if (mhp->kva) kfree((void *) (unsigned long) mhp->kva); @@ -475,6 +476,8 @@ static struct ib_mr *iwch_register_phys_mem(struct ib_pd *pd, if (!mhp) return ERR_PTR(-ENOMEM); + mhp->rhp = rhp; + /* First check that we have enough alignment */ if ((*iova_start & ~PAGE_MASK) != (buffer_list[0].addr & ~PAGE_MASK)) { ret = -EINVAL; @@ -492,7 +495,17 @@ static struct ib_mr *iwch_register_phys_mem(struct ib_pd *pd, if (ret) goto err; - mhp->rhp = rhp; + ret = iwch_alloc_pbl(mhp, npages); + if (ret) { + kfree(page_list); + goto err_pbl; + } + + ret = iwch_write_pbl(mhp, page_list, npages, 0); + kfree(page_list); + if (ret) + goto err_pbl; + mhp->attr.pdid = php->pdid; mhp->attr.zbva = 0; @@ -502,12 +515,15 @@ static struct ib_mr *iwch_register_phys_mem(struct ib_pd *pd, mhp->attr.len = (u32) total_size; mhp->attr.pbl_size = npages; - ret = iwch_register_mem(rhp, php, mhp, shift, page_list); - kfree(page_list); - if (ret) { - goto err; - } + ret = iwch_register_mem(rhp, php, mhp, shift); + if (ret) + goto err_pbl; + return &mhp->ibmr; + +err_pbl: + iwch_free_pbl(mhp); + err: kfree(mhp); return ERR_PTR(ret); @@ -560,7 +576,7 @@ static int iwch_reregister_phys_mem(struct ib_mr *mr, return ret; } - ret = iwch_reregister_mem(rhp, php, &mh, shift, page_list, npages); + ret = iwch_reregister_mem(rhp, php, &mh, shift, npages); kfree(page_list); if (ret) { return ret; @@ -602,6 +618,8 @@ static struct ib_mr *iwch_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, if (!mhp) return ERR_PTR(-ENOMEM); + mhp->rhp = rhp; + mhp->umem = ib_umem_get(pd->uobject->context, start, length, acc, 0); if (IS_ERR(mhp->umem)) { err = PTR_ERR(mhp->umem); @@ -615,10 +633,14 @@ static struct ib_mr *iwch_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, list_for_each_entry(chunk, &mhp->umem->chunk_list, list) n += chunk->nents; - pages = kmalloc(n * sizeof(u64), GFP_KERNEL); + err = iwch_alloc_pbl(mhp, n); + if (err) + goto err; + + pages = (__be64 *) __get_free_page(GFP_KERNEL); if (!pages) { err = -ENOMEM; - goto err; + goto err_pbl; } i = n = 0; @@ -630,25 +652,38 @@ static struct ib_mr *iwch_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, pages[i++] = cpu_to_be64(sg_dma_address( &chunk->page_list[j]) + mhp->umem->page_size * k); + if (i == PAGE_SIZE / sizeof *pages) { + err = iwch_write_pbl(mhp, pages, i, n); + if (err) + goto pbl_done; + n += i; + i = 0; + } } } - mhp->rhp = rhp; + if (i) + err = iwch_write_pbl(mhp, pages, i, n); + +pbl_done: + free_page((unsigned long) pages); + if (err) + goto err_pbl; + mhp->attr.pdid = php->pdid; mhp->attr.zbva = 0; mhp->attr.perms = iwch_ib_to_tpt_access(acc); mhp->attr.va_fbo = virt; mhp->attr.page_size = shift - 12; mhp->attr.len = (u32) length; - mhp->attr.pbl_size = i; - err = iwch_register_mem(rhp, php, mhp, shift, pages); - kfree(pages); + + err = iwch_register_mem(rhp, php, mhp, shift); if (err) - goto err; + goto err_pbl; if (udata && !t3a_device(rhp)) { uresp.pbl_addr = (mhp->attr.pbl_addr - - rhp->rdev.rnic_info.pbl_base) >> 3; + rhp->rdev.rnic_info.pbl_base) >> 3; PDBG("%s user resp pbl_addr 0x%x\n", __func__, uresp.pbl_addr); @@ -661,6 +696,9 @@ static struct ib_mr *iwch_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, return &mhp->ibmr; +err_pbl: + iwch_free_pbl(mhp); + err: ib_umem_release(mhp->umem); kfree(mhp); diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.h b/drivers/infiniband/hw/cxgb3/iwch_provider.h index db5100d27ca2e9f7746cb26444488c80883be292..836163fc54291cdd2cbaab8980cf8bba448c68a9 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_provider.h +++ b/drivers/infiniband/hw/cxgb3/iwch_provider.h @@ -340,14 +340,14 @@ int iwch_quiesce_qps(struct iwch_cq *chp); int iwch_resume_qps(struct iwch_cq *chp); void stop_read_rep_timer(struct iwch_qp *qhp); int iwch_register_mem(struct iwch_dev *rhp, struct iwch_pd *php, - struct iwch_mr *mhp, - int shift, - __be64 *page_list); + struct iwch_mr *mhp, int shift); int iwch_reregister_mem(struct iwch_dev *rhp, struct iwch_pd *php, struct iwch_mr *mhp, int shift, - __be64 *page_list, int npages); +int iwch_alloc_pbl(struct iwch_mr *mhp, int npages); +void iwch_free_pbl(struct iwch_mr *mhp); +int iwch_write_pbl(struct iwch_mr *mhp, __be64 *pages, int npages, int offset); int build_phys_page_list(struct ib_phys_buf *buffer_list, int num_phys_buf, u64 *iova_start, diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h index 00bab60f6de474a1ed24e77ee9331f46efe7103f..1e9e99a13933bd7dfa671cc8a125c9abddb526fc 100644 --- a/drivers/infiniband/hw/ehca/ehca_classes.h +++ b/drivers/infiniband/hw/ehca/ehca_classes.h @@ -192,6 +192,8 @@ struct ehca_qp { int mtu_shift; u32 message_count; u32 packet_count; + atomic_t nr_events; /* events seen */ + wait_queue_head_t wait_completion; }; #define IS_SRQ(qp) (qp->ext_type == EQPT_SRQ) diff --git a/drivers/infiniband/hw/ehca/ehca_irq.c b/drivers/infiniband/hw/ehca/ehca_irq.c index ca5eb0cb628cf74cb4df726667cd2f378199448c..ce1ab0571be38303b8554bd69dcde739f252c826 100644 --- a/drivers/infiniband/hw/ehca/ehca_irq.c +++ b/drivers/infiniband/hw/ehca/ehca_irq.c @@ -204,6 +204,8 @@ static void qp_event_callback(struct ehca_shca *shca, u64 eqe, read_lock(&ehca_qp_idr_lock); qp = idr_find(&ehca_qp_idr, token); + if (qp) + atomic_inc(&qp->nr_events); read_unlock(&ehca_qp_idr_lock); if (!qp) @@ -223,6 +225,8 @@ static void qp_event_callback(struct ehca_shca *shca, u64 eqe, if (fatal && qp->ext_type == EQPT_SRQBASE) dispatch_qp_event(shca, qp, IB_EVENT_QP_LAST_WQE_REACHED); + if (atomic_dec_and_test(&qp->nr_events)) + wake_up(&qp->wait_completion); return; } diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c index 18fba92fa7ae107311121b7cc591aa077c7b51eb..3f59587338ea5fc03a2404500f0d9633a468439f 100644 --- a/drivers/infiniband/hw/ehca/ehca_qp.c +++ b/drivers/infiniband/hw/ehca/ehca_qp.c @@ -566,6 +566,8 @@ static struct ehca_qp *internal_create_qp( return ERR_PTR(-ENOMEM); } + atomic_set(&my_qp->nr_events, 0); + init_waitqueue_head(&my_qp->wait_completion); spin_lock_init(&my_qp->spinlock_s); spin_lock_init(&my_qp->spinlock_r); my_qp->qp_type = qp_type; @@ -1934,6 +1936,9 @@ static int internal_destroy_qp(struct ib_device *dev, struct ehca_qp *my_qp, idr_remove(&ehca_qp_idr, my_qp->token); write_unlock_irqrestore(&ehca_qp_idr_lock, flags); + /* now wait until all pending events have completed */ + wait_event(my_qp->wait_completion, !atomic_read(&my_qp->nr_events)); + h_ret = hipz_h_destroy_qp(shca->ipz_hca_handle, my_qp); if (h_ret != H_SUCCESS) { ehca_err(dev, "hipz_h_destroy_qp() failed h_ret=%li " diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c index acf30c06a0c0ff8eb1981e692c7cc2818b78c4cc..daad09a459106ffb36241805fc579a2efde43a2d 100644 --- a/drivers/infiniband/hw/ipath/ipath_driver.c +++ b/drivers/infiniband/hw/ipath/ipath_driver.c @@ -1197,7 +1197,7 @@ void ipath_kreceive(struct ipath_portdata *pd) } reloop: - for (last = 0, i = 1; !last; i++) { + for (last = 0, i = 1; !last; i += !last) { hdr = dd->ipath_f_get_msgheader(dd, rhf_addr); eflags = ipath_hdrget_err_flags(rhf_addr); etype = ipath_hdrget_rcv_type(rhf_addr); @@ -1428,6 +1428,40 @@ static void ipath_update_pio_bufs(struct ipath_devdata *dd) spin_unlock_irqrestore(&ipath_pioavail_lock, flags); } +/* + * used to force update of pioavailshadow if we can't get a pio buffer. + * Needed primarily due to exitting freeze mode after recovering + * from errors. Done lazily, because it's safer (known to not + * be writing pio buffers). + */ +static void ipath_reset_availshadow(struct ipath_devdata *dd) +{ + int i, im; + unsigned long flags; + + spin_lock_irqsave(&ipath_pioavail_lock, flags); + for (i = 0; i < dd->ipath_pioavregs; i++) { + u64 val, oldval; + /* deal with 6110 chip bug on high register #s */ + im = (i > 3 && (dd->ipath_flags & IPATH_SWAP_PIOBUFS)) ? + i ^ 1 : i; + val = le64_to_cpu(dd->ipath_pioavailregs_dma[im]); + /* + * busy out the buffers not in the kernel avail list, + * without changing the generation bits. + */ + oldval = dd->ipath_pioavailshadow[i]; + dd->ipath_pioavailshadow[i] = val | + ((~dd->ipath_pioavailkernel[i] << + INFINIPATH_SENDPIOAVAIL_BUSY_SHIFT) & + 0xaaaaaaaaaaaaaaaaULL); /* All BUSY bits in qword */ + if (oldval != dd->ipath_pioavailshadow[i]) + ipath_dbg("shadow[%d] was %Lx, now %lx\n", + i, oldval, dd->ipath_pioavailshadow[i]); + } + spin_unlock_irqrestore(&ipath_pioavail_lock, flags); +} + /** * ipath_setrcvhdrsize - set the receive header size * @dd: the infinipath device @@ -1482,9 +1516,12 @@ static noinline void no_pio_bufs(struct ipath_devdata *dd) */ ipath_stats.sps_nopiobufs++; if (!(++dd->ipath_consec_nopiobuf % 100000)) { - ipath_dbg("%u pio sends with no bufavail; dmacopy: " - "%llx %llx %llx %llx; shadow: %lx %lx %lx %lx\n", + ipath_force_pio_avail_update(dd); /* at start */ + ipath_dbg("%u tries no piobufavail ts%lx; dmacopy: " + "%llx %llx %llx %llx\n" + "ipath shadow: %lx %lx %lx %lx\n", dd->ipath_consec_nopiobuf, + (unsigned long)get_cycles(), (unsigned long long) le64_to_cpu(dma[0]), (unsigned long long) le64_to_cpu(dma[1]), (unsigned long long) le64_to_cpu(dma[2]), @@ -1496,14 +1533,17 @@ static noinline void no_pio_bufs(struct ipath_devdata *dd) */ if ((dd->ipath_piobcnt2k + dd->ipath_piobcnt4k) > (sizeof(shadow[0]) * 4 * 4)) - ipath_dbg("2nd group: dmacopy: %llx %llx " - "%llx %llx; shadow: %lx %lx %lx %lx\n", + ipath_dbg("2nd group: dmacopy: " + "%llx %llx %llx %llx\n" + "ipath shadow: %lx %lx %lx %lx\n", (unsigned long long)le64_to_cpu(dma[4]), (unsigned long long)le64_to_cpu(dma[5]), (unsigned long long)le64_to_cpu(dma[6]), (unsigned long long)le64_to_cpu(dma[7]), - shadow[4], shadow[5], shadow[6], - shadow[7]); + shadow[4], shadow[5], shadow[6], shadow[7]); + + /* at end, so update likely happened */ + ipath_reset_availshadow(dd); } } @@ -1652,19 +1692,46 @@ void ipath_chg_pioavailkernel(struct ipath_devdata *dd, unsigned start, unsigned len, int avail) { unsigned long flags; - unsigned end; + unsigned end, cnt = 0, next; /* There are two bits per send buffer (busy and generation) */ start *= 2; - len *= 2; - end = start + len; + end = start + len * 2; - /* Set or clear the generation bits. */ spin_lock_irqsave(&ipath_pioavail_lock, flags); + /* Set or clear the busy bit in the shadow. */ while (start < end) { if (avail) { - __clear_bit(start + INFINIPATH_SENDPIOAVAIL_BUSY_SHIFT, - dd->ipath_pioavailshadow); + unsigned long dma; + int i, im; + /* + * the BUSY bit will never be set, because we disarm + * the user buffers before we hand them back to the + * kernel. We do have to make sure the generation + * bit is set correctly in shadow, since it could + * have changed many times while allocated to user. + * We can't use the bitmap functions on the full + * dma array because it is always little-endian, so + * we have to flip to host-order first. + * BITS_PER_LONG is slightly wrong, since it's + * always 64 bits per register in chip... + * We only work on 64 bit kernels, so that's OK. + */ + /* deal with 6110 chip bug on high register #s */ + i = start / BITS_PER_LONG; + im = (i > 3 && (dd->ipath_flags & IPATH_SWAP_PIOBUFS)) ? + i ^ 1 : i; + __clear_bit(INFINIPATH_SENDPIOAVAIL_BUSY_SHIFT + + start, dd->ipath_pioavailshadow); + dma = (unsigned long) le64_to_cpu( + dd->ipath_pioavailregs_dma[im]); + if (test_bit((INFINIPATH_SENDPIOAVAIL_CHECK_SHIFT + + start) % BITS_PER_LONG, &dma)) + __set_bit(INFINIPATH_SENDPIOAVAIL_CHECK_SHIFT + + start, dd->ipath_pioavailshadow); + else + __clear_bit(INFINIPATH_SENDPIOAVAIL_CHECK_SHIFT + + start, dd->ipath_pioavailshadow); __set_bit(start, dd->ipath_pioavailkernel); } else { __set_bit(start + INFINIPATH_SENDPIOAVAIL_BUSY_SHIFT, @@ -1673,7 +1740,44 @@ void ipath_chg_pioavailkernel(struct ipath_devdata *dd, unsigned start, } start += 2; } + + if (dd->ipath_pioupd_thresh) { + end = 2 * (dd->ipath_piobcnt2k + dd->ipath_piobcnt4k); + next = find_first_bit(dd->ipath_pioavailkernel, end); + while (next < end) { + cnt++; + next = find_next_bit(dd->ipath_pioavailkernel, end, + next + 1); + } + } spin_unlock_irqrestore(&ipath_pioavail_lock, flags); + + /* + * When moving buffers from kernel to user, if number assigned to + * the user is less than the pio update threshold, and threshold + * is supported (cnt was computed > 0), drop the update threshold + * so we update at least once per allocated number of buffers. + * In any case, if the kernel buffers are less than the threshold, + * drop the threshold. We don't bother increasing it, having once + * decreased it, since it would typically just cycle back and forth. + * If we don't decrease below buffers in use, we can wait a long + * time for an update, until some other context uses PIO buffers. + */ + if (!avail && len < cnt) + cnt = len; + if (cnt < dd->ipath_pioupd_thresh) { + dd->ipath_pioupd_thresh = cnt; + ipath_dbg("Decreased pio update threshold to %u\n", + dd->ipath_pioupd_thresh); + spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags); + dd->ipath_sendctrl &= ~(INFINIPATH_S_UPDTHRESH_MASK + << INFINIPATH_S_UPDTHRESH_SHIFT); + dd->ipath_sendctrl |= dd->ipath_pioupd_thresh + << INFINIPATH_S_UPDTHRESH_SHIFT; + ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, + dd->ipath_sendctrl); + spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags); + } } /** @@ -1790,12 +1894,12 @@ void ipath_cancel_sends(struct ipath_devdata *dd, int restore_sendctrl) */ if (dd->ipath_flags & IPATH_HAS_SEND_DMA) { int skip_cancel; - u64 *statp = &dd->ipath_sdma_status; + unsigned long *statp = &dd->ipath_sdma_status; spin_lock_irqsave(&dd->ipath_sdma_lock, flags); skip_cancel = - !test_bit(IPATH_SDMA_DISABLED, statp) && - test_and_set_bit(IPATH_SDMA_ABORTING, statp); + test_and_set_bit(IPATH_SDMA_ABORTING, statp) + && !test_bit(IPATH_SDMA_DISABLED, statp); spin_unlock_irqrestore(&dd->ipath_sdma_lock, flags); if (skip_cancel) goto bail; @@ -1826,6 +1930,9 @@ void ipath_cancel_sends(struct ipath_devdata *dd, int restore_sendctrl) ipath_disarm_piobufs(dd, 0, dd->ipath_piobcnt2k + dd->ipath_piobcnt4k); + if (dd->ipath_flags & IPATH_HAS_SEND_DMA) + set_bit(IPATH_SDMA_DISARMED, &dd->ipath_sdma_status); + if (restore_sendctrl) { /* else done by caller later if needed */ spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags); @@ -1845,7 +1952,6 @@ void ipath_cancel_sends(struct ipath_devdata *dd, int restore_sendctrl) /* only wait so long for intr */ dd->ipath_sdma_abort_intr_timeout = jiffies + HZ; dd->ipath_sdma_reset_wait = 200; - __set_bit(IPATH_SDMA_DISARMED, &dd->ipath_sdma_status); if (!test_bit(IPATH_SDMA_SHUTDOWN, &dd->ipath_sdma_status)) tasklet_hi_schedule(&dd->ipath_sdma_abort_task); spin_unlock_irqrestore(&dd->ipath_sdma_lock, flags); @@ -2510,7 +2616,7 @@ int ipath_reset_device(int unit) ipath_dbg("unit %u port %d is in use " "(PID %u cmd %s), can't reset\n", unit, i, - dd->ipath_pd[i]->port_pid, + pid_nr(dd->ipath_pd[i]->port_pid), dd->ipath_pd[i]->port_comm); ret = -EBUSY; goto bail; @@ -2548,19 +2654,21 @@ bail: static int ipath_signal_procs(struct ipath_devdata *dd, int sig) { int i, sub, any = 0; - pid_t pid; + struct pid *pid; if (!dd->ipath_pd) return 0; for (i = 1; i < dd->ipath_cfgports; i++) { - if (!dd->ipath_pd[i] || !dd->ipath_pd[i]->port_cnt || - !dd->ipath_pd[i]->port_pid) + if (!dd->ipath_pd[i] || !dd->ipath_pd[i]->port_cnt) continue; pid = dd->ipath_pd[i]->port_pid; + if (!pid) + continue; + dev_info(&dd->pcidev->dev, "context %d in use " "(PID %u), sending signal %d\n", - i, pid, sig); - kill_proc(pid, sig, 1); + i, pid_nr(pid), sig); + kill_pid(pid, sig, 1); any++; for (sub = 0; sub < INFINIPATH_MAX_SUBPORT; sub++) { pid = dd->ipath_pd[i]->port_subpid[sub]; @@ -2568,8 +2676,8 @@ static int ipath_signal_procs(struct ipath_devdata *dd, int sig) continue; dev_info(&dd->pcidev->dev, "sub-context " "%d:%d in use (PID %u), sending " - "signal %d\n", i, sub, pid, sig); - kill_proc(pid, sig, 1); + "signal %d\n", i, sub, pid_nr(pid), sig); + kill_pid(pid, sig, 1); any++; } } diff --git a/drivers/infiniband/hw/ipath/ipath_file_ops.c b/drivers/infiniband/hw/ipath/ipath_file_ops.c index 8b1752202e78a8d69c09579428a339df283bd55c..b472b15637f003da8b1a980a2d62206fb9c51eb3 100644 --- a/drivers/infiniband/hw/ipath/ipath_file_ops.c +++ b/drivers/infiniband/hw/ipath/ipath_file_ops.c @@ -173,47 +173,25 @@ static int ipath_get_base_info(struct file *fp, (void *) dd->ipath_statusp - (void *) dd->ipath_pioavailregs_dma; if (!shared) { - kinfo->spi_piocnt = dd->ipath_pbufsport; + kinfo->spi_piocnt = pd->port_piocnt; kinfo->spi_piobufbase = (u64) pd->port_piobufs; kinfo->__spi_uregbase = (u64) dd->ipath_uregbase + dd->ipath_ureg_align * pd->port_port; } else if (master) { - kinfo->spi_piocnt = (dd->ipath_pbufsport / subport_cnt) + - (dd->ipath_pbufsport % subport_cnt); + kinfo->spi_piocnt = (pd->port_piocnt / subport_cnt) + + (pd->port_piocnt % subport_cnt); /* Master's PIO buffers are after all the slave's */ kinfo->spi_piobufbase = (u64) pd->port_piobufs + dd->ipath_palign * - (dd->ipath_pbufsport - kinfo->spi_piocnt); + (pd->port_piocnt - kinfo->spi_piocnt); } else { unsigned slave = subport_fp(fp) - 1; - kinfo->spi_piocnt = dd->ipath_pbufsport / subport_cnt; + kinfo->spi_piocnt = pd->port_piocnt / subport_cnt; kinfo->spi_piobufbase = (u64) pd->port_piobufs + dd->ipath_palign * kinfo->spi_piocnt * slave; } - /* - * Set the PIO avail update threshold to no larger - * than the number of buffers per process. Note that - * we decrease it here, but won't ever increase it. - */ - if (dd->ipath_pioupd_thresh && - kinfo->spi_piocnt < dd->ipath_pioupd_thresh) { - unsigned long flags; - - dd->ipath_pioupd_thresh = kinfo->spi_piocnt; - ipath_dbg("Decreased pio update threshold to %u\n", - dd->ipath_pioupd_thresh); - spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags); - dd->ipath_sendctrl &= ~(INFINIPATH_S_UPDTHRESH_MASK - << INFINIPATH_S_UPDTHRESH_SHIFT); - dd->ipath_sendctrl |= dd->ipath_pioupd_thresh - << INFINIPATH_S_UPDTHRESH_SHIFT; - ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, - dd->ipath_sendctrl); - spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags); - } - if (shared) { kinfo->spi_port_uregbase = (u64) dd->ipath_uregbase + dd->ipath_ureg_align * pd->port_port; @@ -577,7 +555,7 @@ static int ipath_tid_free(struct ipath_portdata *pd, unsigned subport, p = dd->ipath_pageshadow[porttid + tid]; dd->ipath_pageshadow[porttid + tid] = NULL; ipath_cdbg(VERBOSE, "PID %u freeing TID %u\n", - pd->port_pid, tid); + pid_nr(pd->port_pid), tid); dd->ipath_f_put_tid(dd, &tidbase[tid], RCVHQ_RCV_TYPE_EXPECTED, dd->ipath_tidinvalid); @@ -1309,19 +1287,19 @@ static int ipath_mmap(struct file *fp, struct vm_area_struct *vma) ureg = dd->ipath_uregbase + dd->ipath_ureg_align * pd->port_port; if (!pd->port_subport_cnt) { /* port is not shared */ - piocnt = dd->ipath_pbufsport; + piocnt = pd->port_piocnt; piobufs = pd->port_piobufs; } else if (!subport_fp(fp)) { /* caller is the master */ - piocnt = (dd->ipath_pbufsport / pd->port_subport_cnt) + - (dd->ipath_pbufsport % pd->port_subport_cnt); + piocnt = (pd->port_piocnt / pd->port_subport_cnt) + + (pd->port_piocnt % pd->port_subport_cnt); piobufs = pd->port_piobufs + - dd->ipath_palign * (dd->ipath_pbufsport - piocnt); + dd->ipath_palign * (pd->port_piocnt - piocnt); } else { unsigned slave = subport_fp(fp) - 1; /* caller is a slave */ - piocnt = dd->ipath_pbufsport / pd->port_subport_cnt; + piocnt = pd->port_piocnt / pd->port_subport_cnt; piobufs = pd->port_piobufs + dd->ipath_palign * piocnt * slave; } @@ -1631,11 +1609,8 @@ static int try_alloc_port(struct ipath_devdata *dd, int port, port); pd->port_cnt = 1; port_fp(fp) = pd; - pd->port_pid = current->pid; + pd->port_pid = get_pid(task_pid(current)); strncpy(pd->port_comm, current->comm, sizeof(pd->port_comm)); - ipath_chg_pioavailkernel(dd, - dd->ipath_pbufsport * (pd->port_port - 1), - dd->ipath_pbufsport, 0); ipath_stats.sps_ports++; ret = 0; } else @@ -1818,14 +1793,15 @@ static int find_shared_port(struct file *fp, } port_fp(fp) = pd; subport_fp(fp) = pd->port_cnt++; - pd->port_subpid[subport_fp(fp)] = current->pid; + pd->port_subpid[subport_fp(fp)] = + get_pid(task_pid(current)); tidcursor_fp(fp) = 0; pd->active_slaves |= 1 << subport_fp(fp); ipath_cdbg(PROC, "%s[%u] %u sharing %s[%u] unit:port %u:%u\n", current->comm, current->pid, subport_fp(fp), - pd->port_comm, pd->port_pid, + pd->port_comm, pid_nr(pd->port_pid), dd->ipath_unit, pd->port_port); ret = 1; goto done; @@ -1938,11 +1914,25 @@ static int ipath_do_user_init(struct file *fp, /* for now we do nothing with rcvhdrcnt: uinfo->spu_rcvhdrcnt */ + /* some ports may get extra buffers, calculate that here */ + if (pd->port_port <= dd->ipath_ports_extrabuf) + pd->port_piocnt = dd->ipath_pbufsport + 1; + else + pd->port_piocnt = dd->ipath_pbufsport; + /* for right now, kernel piobufs are at end, so port 1 is at 0 */ + if (pd->port_port <= dd->ipath_ports_extrabuf) + pd->port_pio_base = (dd->ipath_pbufsport + 1) + * (pd->port_port - 1); + else + pd->port_pio_base = dd->ipath_ports_extrabuf + + dd->ipath_pbufsport * (pd->port_port - 1); pd->port_piobufs = dd->ipath_piobufbase + - dd->ipath_pbufsport * (pd->port_port - 1) * dd->ipath_palign; - ipath_cdbg(VERBOSE, "Set base of piobufs for port %u to 0x%x\n", - pd->port_port, pd->port_piobufs); + pd->port_pio_base * dd->ipath_palign; + ipath_cdbg(VERBOSE, "piobuf base for port %u is 0x%x, piocnt %u," + " first pio %u\n", pd->port_port, pd->port_piobufs, + pd->port_piocnt, pd->port_pio_base); + ipath_chg_pioavailkernel(dd, pd->port_pio_base, pd->port_piocnt, 0); /* * Now allocate the rcvhdr Q and eager TIDs; skip the TID @@ -2077,7 +2067,8 @@ static int ipath_close(struct inode *in, struct file *fp) * the slave(s) don't wait for receive data forever. */ pd->active_slaves &= ~(1 << fd->subport); - pd->port_subpid[fd->subport] = 0; + put_pid(pd->port_subpid[fd->subport]); + pd->port_subpid[fd->subport] = NULL; mutex_unlock(&ipath_mutex); goto bail; } @@ -2085,7 +2076,7 @@ static int ipath_close(struct inode *in, struct file *fp) if (pd->port_hdrqfull) { ipath_cdbg(PROC, "%s[%u] had %u rcvhdrqfull errors " - "during run\n", pd->port_comm, pd->port_pid, + "during run\n", pd->port_comm, pid_nr(pd->port_pid), pd->port_hdrqfull); pd->port_hdrqfull = 0; } @@ -2107,7 +2098,6 @@ static int ipath_close(struct inode *in, struct file *fp) } if (dd->ipath_kregbase) { - int i; /* atomically clear receive enable port and intr avail. */ clear_bit(dd->ipath_r_portenable_shift + port, &dd->ipath_rcvctrl); @@ -2136,9 +2126,9 @@ static int ipath_close(struct inode *in, struct file *fp) ipath_write_kreg_port(dd, dd->ipath_kregs->kr_rcvhdraddr, pd->port_port, dd->ipath_dummy_hdrq_phys); - i = dd->ipath_pbufsport * (port - 1); - ipath_disarm_piobufs(dd, i, dd->ipath_pbufsport); - ipath_chg_pioavailkernel(dd, i, dd->ipath_pbufsport, 1); + ipath_disarm_piobufs(dd, pd->port_pio_base, pd->port_piocnt); + ipath_chg_pioavailkernel(dd, pd->port_pio_base, + pd->port_piocnt, 1); dd->ipath_f_clear_tids(dd, pd->port_port); @@ -2146,11 +2136,12 @@ static int ipath_close(struct inode *in, struct file *fp) unlock_expected_tids(pd); ipath_stats.sps_ports--; ipath_cdbg(PROC, "%s[%u] closed port %u:%u\n", - pd->port_comm, pd->port_pid, + pd->port_comm, pid_nr(pd->port_pid), dd->ipath_unit, port); } - pd->port_pid = 0; + put_pid(pd->port_pid); + pd->port_pid = NULL; dd->ipath_pd[pd->port_port] = NULL; /* before releasing mutex */ mutex_unlock(&ipath_mutex); ipath_free_pddata(dd, pd); /* after releasing the mutex */ diff --git a/drivers/infiniband/hw/ipath/ipath_iba7220.c b/drivers/infiniband/hw/ipath/ipath_iba7220.c index e3ec0d1bdf505ae50d592174bfb2633a6d48b522..8eee7830f042b3d05b20fa4955295905294378a3 100644 --- a/drivers/infiniband/hw/ipath/ipath_iba7220.c +++ b/drivers/infiniband/hw/ipath/ipath_iba7220.c @@ -595,7 +595,7 @@ static void ipath_7220_txe_recover(struct ipath_devdata *dd) dev_info(&dd->pcidev->dev, "Recovering from TXE PIO parity error\n"); - ipath_disarm_senderrbufs(dd, 1); + ipath_disarm_senderrbufs(dd); } @@ -675,10 +675,8 @@ static void ipath_7220_handle_hwerrors(struct ipath_devdata *dd, char *msg, ctrl = ipath_read_kreg32(dd, dd->ipath_kregs->kr_control); if ((ctrl & INFINIPATH_C_FREEZEMODE) && !ipath_diag_inuse) { /* - * Parity errors in send memory are recoverable, - * just cancel the send (if indicated in * sendbuffererror), - * count the occurrence, unfreeze (if no other handled - * hardware error bits are set), and continue. + * Parity errors in send memory are recoverable by h/w + * just do housekeeping, exit freeze mode and continue. */ if (hwerrs & ((INFINIPATH_HWE_TXEMEMPARITYERR_PIOBUF | INFINIPATH_HWE_TXEMEMPARITYERR_PIOPBC) @@ -687,13 +685,6 @@ static void ipath_7220_handle_hwerrors(struct ipath_devdata *dd, char *msg, hwerrs &= ~((INFINIPATH_HWE_TXEMEMPARITYERR_PIOBUF | INFINIPATH_HWE_TXEMEMPARITYERR_PIOPBC) << INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT); - if (!hwerrs) { - /* else leave in freeze mode */ - ipath_write_kreg(dd, - dd->ipath_kregs->kr_control, - dd->ipath_control); - goto bail; - } } if (hwerrs) { /* @@ -723,8 +714,8 @@ static void ipath_7220_handle_hwerrors(struct ipath_devdata *dd, char *msg, *dd->ipath_statusp |= IPATH_STATUS_HWERROR; dd->ipath_flags &= ~IPATH_INITTED; } else { - ipath_dbg("Clearing freezemode on ignored hardware " - "error\n"); + ipath_dbg("Clearing freezemode on ignored or " + "recovered hardware error\n"); ipath_clear_freeze(dd); } } @@ -870,8 +861,9 @@ static int ipath_7220_boardname(struct ipath_devdata *dd, char *name, "revision %u.%u!\n", dd->ipath_majrev, dd->ipath_minrev); ret = 1; - } else if (dd->ipath_minrev == 1) { - /* Rev1 chips are prototype. Complain, but allow use */ + } else if (dd->ipath_minrev == 1 && + !(dd->ipath_flags & IPATH_INITTED)) { + /* Rev1 chips are prototype. Complain at init, but allow use */ ipath_dev_err(dd, "Unsupported hardware " "revision %u.%u, Contact support@qlogic.com\n", dd->ipath_majrev, dd->ipath_minrev); @@ -1966,7 +1958,7 @@ static void ipath_7220_config_ports(struct ipath_devdata *dd, ushort cfgports) dd->ipath_rcvctrl); dd->ipath_p0_rcvegrcnt = 2048; /* always */ if (dd->ipath_flags & IPATH_HAS_SEND_DMA) - dd->ipath_pioreserved = 1; /* reserve a buffer */ + dd->ipath_pioreserved = 3; /* kpiobufs used for PIO */ } diff --git a/drivers/infiniband/hw/ipath/ipath_init_chip.c b/drivers/infiniband/hw/ipath/ipath_init_chip.c index 27dd89476660846c723f60518828d4692206f213..3e5baa43fc822468b232819f62716a2aba1d8c1d 100644 --- a/drivers/infiniband/hw/ipath/ipath_init_chip.c +++ b/drivers/infiniband/hw/ipath/ipath_init_chip.c @@ -41,7 +41,7 @@ /* * min buffers we want to have per port, after driver */ -#define IPATH_MIN_USER_PORT_BUFCNT 8 +#define IPATH_MIN_USER_PORT_BUFCNT 7 /* * Number of ports we are configured to use (to allow for more pio @@ -54,13 +54,9 @@ MODULE_PARM_DESC(cfgports, "Set max number of ports to use"); /* * Number of buffers reserved for driver (verbs and layered drivers.) - * Reserved at end of buffer list. Initialized based on - * number of PIO buffers if not set via module interface. + * Initialized based on number of PIO buffers if not set via module interface. * The problem with this is that it's global, but we'll use different - * numbers for different chip types. So the default value is not - * very useful. I've redefined it for the 1.3 release so that it's - * zero unless set by the user to something else, in which case we - * try to respect it. + * numbers for different chip types. */ static ushort ipath_kpiobufs; @@ -546,9 +542,12 @@ static void enable_chip(struct ipath_devdata *dd, int reinit) pioavail = dd->ipath_pioavailregs_dma[i ^ 1]; else pioavail = dd->ipath_pioavailregs_dma[i]; - dd->ipath_pioavailshadow[i] = le64_to_cpu(pioavail) | - (~dd->ipath_pioavailkernel[i] << - INFINIPATH_SENDPIOAVAIL_BUSY_SHIFT); + /* + * don't need to worry about ipath_pioavailkernel here + * because we will call ipath_chg_pioavailkernel() later + * in initialization, to busy out buffers as needed + */ + dd->ipath_pioavailshadow[i] = le64_to_cpu(pioavail); } /* can get counters, stats, etc. */ dd->ipath_flags |= IPATH_PRESENT; @@ -708,12 +707,11 @@ static void verify_interrupt(unsigned long opaque) int ipath_init_chip(struct ipath_devdata *dd, int reinit) { int ret = 0; - u32 val32, kpiobufs; + u32 kpiobufs, defkbufs; u32 piobufs, uports; u64 val; struct ipath_portdata *pd; gfp_t gfp_flags = GFP_USER | __GFP_COMP; - unsigned long flags; ret = init_housekeeping(dd, reinit); if (ret) @@ -753,69 +751,52 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit) dd->ipath_pioavregs = ALIGN(piobufs, sizeof(u64) * BITS_PER_BYTE / 2) / (sizeof(u64) * BITS_PER_BYTE / 2); uports = dd->ipath_cfgports ? dd->ipath_cfgports - 1 : 0; - if (ipath_kpiobufs == 0) { - /* not set by user (this is default) */ - if (piobufs > 144) - kpiobufs = 32; - else - kpiobufs = 16; - } + if (piobufs > 144) + defkbufs = 32 + dd->ipath_pioreserved; else - kpiobufs = ipath_kpiobufs; + defkbufs = 16 + dd->ipath_pioreserved; - if (kpiobufs + (uports * IPATH_MIN_USER_PORT_BUFCNT) > piobufs) { + if (ipath_kpiobufs && (ipath_kpiobufs + + (uports * IPATH_MIN_USER_PORT_BUFCNT)) > piobufs) { int i = (int) piobufs - (int) (uports * IPATH_MIN_USER_PORT_BUFCNT); if (i < 1) i = 1; dev_info(&dd->pcidev->dev, "Allocating %d PIO bufs of " "%d for kernel leaves too few for %d user ports " - "(%d each); using %u\n", kpiobufs, + "(%d each); using %u\n", ipath_kpiobufs, piobufs, uports, IPATH_MIN_USER_PORT_BUFCNT, i); /* * shouldn't change ipath_kpiobufs, because could be * different for different devices... */ kpiobufs = i; - } + } else if (ipath_kpiobufs) + kpiobufs = ipath_kpiobufs; + else + kpiobufs = defkbufs; dd->ipath_lastport_piobuf = piobufs - kpiobufs; dd->ipath_pbufsport = uports ? dd->ipath_lastport_piobuf / uports : 0; - val32 = dd->ipath_lastport_piobuf - (dd->ipath_pbufsport * uports); - if (val32 > 0) { - ipath_dbg("allocating %u pbufs/port leaves %u unused, " - "add to kernel\n", dd->ipath_pbufsport, val32); - dd->ipath_lastport_piobuf -= val32; - kpiobufs += val32; - ipath_dbg("%u pbufs/port leaves %u unused, add to kernel\n", - dd->ipath_pbufsport, val32); - } + /* if not an even divisor, some user ports get extra buffers */ + dd->ipath_ports_extrabuf = dd->ipath_lastport_piobuf - + (dd->ipath_pbufsport * uports); + if (dd->ipath_ports_extrabuf) + ipath_dbg("%u pbufs/port leaves some unused, add 1 buffer to " + "ports <= %u\n", dd->ipath_pbufsport, + dd->ipath_ports_extrabuf); dd->ipath_lastpioindex = 0; dd->ipath_lastpioindexl = dd->ipath_piobcnt2k; - ipath_chg_pioavailkernel(dd, 0, piobufs, 1); + /* ipath_pioavailshadow initialized earlier */ ipath_cdbg(VERBOSE, "%d PIO bufs for kernel out of %d total %u " "each for %u user ports\n", kpiobufs, piobufs, dd->ipath_pbufsport, uports); - if (dd->ipath_pioupd_thresh) { - if (dd->ipath_pbufsport < dd->ipath_pioupd_thresh) - dd->ipath_pioupd_thresh = dd->ipath_pbufsport; - if (kpiobufs < dd->ipath_pioupd_thresh) - dd->ipath_pioupd_thresh = kpiobufs; - } - ret = dd->ipath_f_early_init(dd); if (ret) { ipath_dev_err(dd, "Early initialization failure\n"); goto done; } - /* - * Cancel any possible active sends from early driver load. - * Follows early_init because some chips have to initialize - * PIO buffers in early_init to avoid false parity errors. - */ - ipath_cancel_sends(dd, 0); - /* * Early_init sets rcvhdrentsize and rcvhdrsize, so this must be * done after early_init. @@ -836,6 +817,7 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit) ipath_write_kreg(dd, dd->ipath_kregs->kr_sendpioavailaddr, dd->ipath_pioavailregs_phys); + /* * this is to detect s/w errors, which the h/w works around by * ignoring the low 6 bits of address, if it wasn't aligned. @@ -862,12 +844,6 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit) ~0ULL&~INFINIPATH_HWE_MEMBISTFAILED); ipath_write_kreg(dd, dd->ipath_kregs->kr_control, 0ULL); - spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags); - dd->ipath_sendctrl = INFINIPATH_S_PIOENABLE; - ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, dd->ipath_sendctrl); - ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); - spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags); - /* * before error clears, since we expect serdes pll errors during * this, the first time after reset @@ -940,6 +916,19 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit) else enable_chip(dd, reinit); + /* after enable_chip, so pioavailshadow setup */ + ipath_chg_pioavailkernel(dd, 0, piobufs, 1); + + /* + * Cancel any possible active sends from early driver load. + * Follows early_init because some chips have to initialize + * PIO buffers in early_init to avoid false parity errors. + * After enable and ipath_chg_pioavailkernel so we can safely + * enable pioavail updates and PIOENABLE; packets are now + * ready to go out. + */ + ipath_cancel_sends(dd, 1); + if (!reinit) { /* * Used when we close a port, for DMA already in flight diff --git a/drivers/infiniband/hw/ipath/ipath_intr.c b/drivers/infiniband/hw/ipath/ipath_intr.c index 1b58f4737c716e88629a465b34847a22e6e695b4..26900b3b7a4ee1bcef2fe064a1a8148900128fae 100644 --- a/drivers/infiniband/hw/ipath/ipath_intr.c +++ b/drivers/infiniband/hw/ipath/ipath_intr.c @@ -38,42 +38,12 @@ #include "ipath_verbs.h" #include "ipath_common.h" -/* - * clear (write) a pio buffer, to clear a parity error. This routine - * should only be called when in freeze mode, and the buffer should be - * canceled afterwards. - */ -static void ipath_clrpiobuf(struct ipath_devdata *dd, u32 pnum) -{ - u32 __iomem *pbuf; - u32 dwcnt; /* dword count to write */ - if (pnum < dd->ipath_piobcnt2k) { - pbuf = (u32 __iomem *) (dd->ipath_pio2kbase + pnum * - dd->ipath_palign); - dwcnt = dd->ipath_piosize2k >> 2; - } - else { - pbuf = (u32 __iomem *) (dd->ipath_pio4kbase + - (pnum - dd->ipath_piobcnt2k) * dd->ipath_4kalign); - dwcnt = dd->ipath_piosize4k >> 2; - } - dev_info(&dd->pcidev->dev, - "Rewrite PIO buffer %u, to recover from parity error\n", - pnum); - - /* no flush required, since already in freeze */ - writel(dwcnt + 1, pbuf); - while (--dwcnt) - writel(0, pbuf++); -} /* * Called when we might have an error that is specific to a particular * PIO buffer, and may need to cancel that buffer, so it can be re-used. - * If rewrite is true, and bits are set in the sendbufferror registers, - * we'll write to the buffer, for error recovery on parity errors. */ -void ipath_disarm_senderrbufs(struct ipath_devdata *dd, int rewrite) +void ipath_disarm_senderrbufs(struct ipath_devdata *dd) { u32 piobcnt; unsigned long sbuf[4]; @@ -109,11 +79,8 @@ void ipath_disarm_senderrbufs(struct ipath_devdata *dd, int rewrite) } for (i = 0; i < piobcnt; i++) - if (test_bit(i, sbuf)) { - if (rewrite) - ipath_clrpiobuf(dd, i); + if (test_bit(i, sbuf)) ipath_disarm_piobufs(dd, i, 1); - } /* ignore armlaunch errs for a bit */ dd->ipath_lastcancel = jiffies+3; } @@ -164,7 +131,7 @@ static u64 handle_e_sum_errs(struct ipath_devdata *dd, ipath_err_t errs) { u64 ignore_this_time = 0; - ipath_disarm_senderrbufs(dd, 0); + ipath_disarm_senderrbufs(dd); if ((errs & E_SUM_LINK_PKTERRS) && !(dd->ipath_flags & IPATH_LINKACTIVE)) { /* @@ -909,8 +876,8 @@ static int handle_errors(struct ipath_devdata *dd, ipath_err_t errs) * processes (causing armlaunch), send errors due to going into freeze mode, * etc., and try to avoid causing extra interrupts while doing so. * Forcibly update the in-memory pioavail register copies after cleanup - * because the chip won't do it for anything changing while in freeze mode - * (we don't want to wait for the next pio buffer state change). + * because the chip won't do it while in freeze mode (the register values + * themselves are kept correct). * Make sure that we don't lose any important interrupts by using the chip * feature that says that writing 0 to a bit in *clear that is set in * *status will cause an interrupt to be generated again (if allowed by @@ -918,43 +885,22 @@ static int handle_errors(struct ipath_devdata *dd, ipath_err_t errs) */ void ipath_clear_freeze(struct ipath_devdata *dd) { - int i, im; - u64 val; - /* disable error interrupts, to avoid confusion */ ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask, 0ULL); /* also disable interrupts; errormask is sometimes overwriten */ ipath_write_kreg(dd, dd->ipath_kregs->kr_intmask, 0ULL); - /* - * clear all sends, because they have may been - * completed by usercode while in freeze mode, and - * therefore would not be sent, and eventually - * might cause the process to run out of bufs - */ - ipath_cancel_sends(dd, 0); + ipath_cancel_sends(dd, 1); + + /* clear the freeze, and be sure chip saw it */ ipath_write_kreg(dd, dd->ipath_kregs->kr_control, dd->ipath_control); + ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); - /* ensure pio avail updates continue */ + /* force in-memory update now we are out of freeze */ ipath_force_pio_avail_update(dd); - /* - * We just enabled pioavailupdate, so dma copy is almost certainly - * not yet right, so read the registers directly. Similar to init - */ - for (i = 0; i < dd->ipath_pioavregs; i++) { - /* deal with 6110 chip bug */ - im = (i > 3 && (dd->ipath_flags & IPATH_SWAP_PIOBUFS)) ? - i ^ 1 : i; - val = ipath_read_kreg64(dd, (0x1000 / sizeof(u64)) + im); - dd->ipath_pioavailregs_dma[i] = cpu_to_le64(val); - dd->ipath_pioavailshadow[i] = val | - (~dd->ipath_pioavailkernel[i] << - INFINIPATH_SENDPIOAVAIL_BUSY_SHIFT); - } - /* * force new interrupt if any hwerr, error or interrupt bits are * still set, and clear "safe" send packet errors related to freeze @@ -1312,10 +1258,8 @@ irqreturn_t ipath_intr(int irq, void *data) ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags); - if (!(dd->ipath_flags & IPATH_HAS_SEND_DMA)) - handle_layer_pioavail(dd); - else - ipath_dbg("unexpected BUFAVAIL intr\n"); + /* always process; sdma verbs uses PIO for acks and VL15 */ + handle_layer_pioavail(dd); } ret = IRQ_HANDLED; diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h index 202337ae90dc68621dc89feefe931dbb82982c37..59a8b254b97fd3b3ad110be7944259b733f358eb 100644 --- a/drivers/infiniband/hw/ipath/ipath_kernel.h +++ b/drivers/infiniband/hw/ipath/ipath_kernel.h @@ -117,6 +117,10 @@ struct ipath_portdata { u16 port_subport_cnt; /* non-zero if port is being shared. */ u16 port_subport_id; + /* number of pio bufs for this port (all procs, if shared) */ + u32 port_piocnt; + /* first pio buffer for this port */ + u32 port_pio_base; /* chip offset of PIO buffers for this port */ u32 port_piobufs; /* how many alloc_pages() chunks in port_rcvegrbuf_pages */ @@ -155,8 +159,8 @@ struct ipath_portdata { /* saved total number of polled urgent packets for poll edge trigger */ u32 port_urgent_poll; /* pid of process using this port */ - pid_t port_pid; - pid_t port_subpid[INFINIPATH_MAX_SUBPORT]; + struct pid *port_pid; + struct pid *port_subpid[INFINIPATH_MAX_SUBPORT]; /* same size as task_struct .comm[] */ char port_comm[16]; /* pkeys set by this use of this port */ @@ -384,6 +388,8 @@ struct ipath_devdata { u32 ipath_lastrpkts; /* pio bufs allocated per port */ u32 ipath_pbufsport; + /* if remainder on bufs/port, ports < extrabuf get 1 extra */ + u32 ipath_ports_extrabuf; u32 ipath_pioupd_thresh; /* update threshold, some chips */ /* * number of ports configured as max; zero is set to number chip @@ -477,7 +483,7 @@ struct ipath_devdata { /* SendDMA related entries */ spinlock_t ipath_sdma_lock; - u64 ipath_sdma_status; + unsigned long ipath_sdma_status; unsigned long ipath_sdma_abort_jiffies; unsigned long ipath_sdma_abort_intr_timeout; unsigned long ipath_sdma_buf_jiffies; @@ -816,8 +822,8 @@ struct ipath_devdata { #define IPATH_SDMA_DISARMED 1 #define IPATH_SDMA_DISABLED 2 #define IPATH_SDMA_LAYERBUF 3 -#define IPATH_SDMA_RUNNING 62 -#define IPATH_SDMA_SHUTDOWN 63 +#define IPATH_SDMA_RUNNING 30 +#define IPATH_SDMA_SHUTDOWN 31 /* bit combinations that correspond to abort states */ #define IPATH_SDMA_ABORT_NONE 0 @@ -1011,7 +1017,7 @@ void ipath_get_eeprom_info(struct ipath_devdata *); int ipath_update_eeprom_log(struct ipath_devdata *dd); void ipath_inc_eeprom_err(struct ipath_devdata *dd, u32 eidx, u32 incr); u64 ipath_snap_cntr(struct ipath_devdata *, ipath_creg); -void ipath_disarm_senderrbufs(struct ipath_devdata *, int); +void ipath_disarm_senderrbufs(struct ipath_devdata *); void ipath_force_pio_avail_update(struct ipath_devdata *); void signal_ib_event(struct ipath_devdata *dd, enum ib_event_type ev); diff --git a/drivers/infiniband/hw/ipath/ipath_qp.c b/drivers/infiniband/hw/ipath/ipath_qp.c index dd5b6e9d57c29bf2417d8b3a6e23223d0b142cf9..4715911101e4fff8363c0e748929302a213d05bc 100644 --- a/drivers/infiniband/hw/ipath/ipath_qp.c +++ b/drivers/infiniband/hw/ipath/ipath_qp.c @@ -242,7 +242,6 @@ static void ipath_free_qp(struct ipath_qp_table *qpt, struct ipath_qp *qp) { struct ipath_qp *q, **qpp; unsigned long flags; - int fnd = 0; spin_lock_irqsave(&qpt->lock, flags); @@ -253,51 +252,40 @@ static void ipath_free_qp(struct ipath_qp_table *qpt, struct ipath_qp *qp) *qpp = qp->next; qp->next = NULL; atomic_dec(&qp->refcount); - fnd = 1; break; } } spin_unlock_irqrestore(&qpt->lock, flags); - - if (!fnd) - return; - - free_qpn(qpt, qp->ibqp.qp_num); - - wait_event(qp->wait, !atomic_read(&qp->refcount)); } /** - * ipath_free_all_qps - remove all QPs from the table + * ipath_free_all_qps - check for QPs still in use * @qpt: the QP table to empty + * + * There should not be any QPs still in use. + * Free memory for table. */ -void ipath_free_all_qps(struct ipath_qp_table *qpt) +unsigned ipath_free_all_qps(struct ipath_qp_table *qpt) { unsigned long flags; - struct ipath_qp *qp, *nqp; - u32 n; + struct ipath_qp *qp; + u32 n, qp_inuse = 0; + spin_lock_irqsave(&qpt->lock, flags); for (n = 0; n < qpt->max; n++) { - spin_lock_irqsave(&qpt->lock, flags); qp = qpt->table[n]; qpt->table[n] = NULL; - spin_unlock_irqrestore(&qpt->lock, flags); - - while (qp) { - nqp = qp->next; - free_qpn(qpt, qp->ibqp.qp_num); - if (!atomic_dec_and_test(&qp->refcount) || - !ipath_destroy_qp(&qp->ibqp)) - ipath_dbg("QP memory leak!\n"); - qp = nqp; - } + + for (; qp; qp = qp->next) + qp_inuse++; } + spin_unlock_irqrestore(&qpt->lock, flags); - for (n = 0; n < ARRAY_SIZE(qpt->map); n++) { + for (n = 0; n < ARRAY_SIZE(qpt->map); n++) if (qpt->map[n].page) - free_page((unsigned long)qpt->map[n].page); - } + free_page((unsigned long) qpt->map[n].page); + return qp_inuse; } /** @@ -336,11 +324,12 @@ static void ipath_reset_qp(struct ipath_qp *qp, enum ib_qp_type type) qp->remote_qpn = 0; qp->qkey = 0; qp->qp_access_flags = 0; - qp->s_busy = 0; + atomic_set(&qp->s_dma_busy, 0); qp->s_flags &= IPATH_S_SIGNAL_REQ_WR; qp->s_hdrwords = 0; qp->s_wqe = NULL; qp->s_pkt_delay = 0; + qp->s_draining = 0; qp->s_psn = 0; qp->r_psn = 0; qp->r_msn = 0; @@ -353,7 +342,8 @@ static void ipath_reset_qp(struct ipath_qp *qp, enum ib_qp_type type) } qp->s_ack_state = IB_OPCODE_RC_ACKNOWLEDGE; qp->r_nak_state = 0; - qp->r_wrid_valid = 0; + qp->r_aflags = 0; + qp->r_flags = 0; qp->s_rnr_timeout = 0; qp->s_head = 0; qp->s_tail = 0; @@ -361,7 +351,6 @@ static void ipath_reset_qp(struct ipath_qp *qp, enum ib_qp_type type) qp->s_last = 0; qp->s_ssn = 1; qp->s_lsn = 0; - qp->s_wait_credit = 0; memset(qp->s_ack_queue, 0, sizeof(qp->s_ack_queue)); qp->r_head_ack_queue = 0; qp->s_tail_ack_queue = 0; @@ -370,17 +359,17 @@ static void ipath_reset_qp(struct ipath_qp *qp, enum ib_qp_type type) qp->r_rq.wq->head = 0; qp->r_rq.wq->tail = 0; } - qp->r_reuse_sge = 0; } /** - * ipath_error_qp - put a QP into an error state - * @qp: the QP to put into an error state + * ipath_error_qp - put a QP into the error state + * @qp: the QP to put into the error state * @err: the receive completion error to signal if a RWQE is active * * Flushes both send and receive work queues. * Returns true if last WQE event should be generated. * The QP s_lock should be held and interrupts disabled. + * If we are already in error state, just return. */ int ipath_error_qp(struct ipath_qp *qp, enum ib_wc_status err) @@ -389,8 +378,10 @@ int ipath_error_qp(struct ipath_qp *qp, enum ib_wc_status err) struct ib_wc wc; int ret = 0; - ipath_dbg("QP%d/%d in error state (%d)\n", - qp->ibqp.qp_num, qp->remote_qpn, err); + if (qp->state == IB_QPS_ERR) + goto bail; + + qp->state = IB_QPS_ERR; spin_lock(&dev->pending_lock); if (!list_empty(&qp->timerwait)) @@ -399,39 +390,21 @@ int ipath_error_qp(struct ipath_qp *qp, enum ib_wc_status err) list_del_init(&qp->piowait); spin_unlock(&dev->pending_lock); - wc.vendor_err = 0; - wc.byte_len = 0; - wc.imm_data = 0; + /* Schedule the sending tasklet to drain the send work queue. */ + if (qp->s_last != qp->s_head) + ipath_schedule_send(qp); + + memset(&wc, 0, sizeof(wc)); wc.qp = &qp->ibqp; - wc.src_qp = 0; - wc.wc_flags = 0; - wc.pkey_index = 0; - wc.slid = 0; - wc.sl = 0; - wc.dlid_path_bits = 0; - wc.port_num = 0; - if (qp->r_wrid_valid) { - qp->r_wrid_valid = 0; + wc.opcode = IB_WC_RECV; + + if (test_and_clear_bit(IPATH_R_WRID_VALID, &qp->r_aflags)) { wc.wr_id = qp->r_wr_id; - wc.opcode = IB_WC_RECV; wc.status = err; ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, 1); } wc.status = IB_WC_WR_FLUSH_ERR; - while (qp->s_last != qp->s_head) { - struct ipath_swqe *wqe = get_swqe_ptr(qp, qp->s_last); - - wc.wr_id = wqe->wr.wr_id; - wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode]; - if (++qp->s_last >= qp->s_size) - qp->s_last = 0; - ipath_cq_enter(to_icq(qp->ibqp.send_cq), &wc, 1); - } - qp->s_cur = qp->s_tail = qp->s_head; - qp->s_hdrwords = 0; - qp->s_ack_state = IB_OPCODE_RC_ACKNOWLEDGE; - if (qp->r_rq.wq) { struct ipath_rwq *wq; u32 head; @@ -447,7 +420,6 @@ int ipath_error_qp(struct ipath_qp *qp, enum ib_wc_status err) tail = wq->tail; if (tail >= qp->r_rq.size) tail = 0; - wc.opcode = IB_WC_RECV; while (tail != head) { wc.wr_id = get_rwqe_ptr(&qp->r_rq, tail)->wr_id; if (++tail >= qp->r_rq.size) @@ -460,6 +432,7 @@ int ipath_error_qp(struct ipath_qp *qp, enum ib_wc_status err) } else if (qp->ibqp.event_handler) ret = 1; +bail: return ret; } @@ -478,11 +451,10 @@ int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, struct ipath_ibdev *dev = to_idev(ibqp->device); struct ipath_qp *qp = to_iqp(ibqp); enum ib_qp_state cur_state, new_state; - unsigned long flags; int lastwqe = 0; int ret; - spin_lock_irqsave(&qp->s_lock, flags); + spin_lock_irq(&qp->s_lock); cur_state = attr_mask & IB_QP_CUR_STATE ? attr->cur_qp_state : qp->state; @@ -535,16 +507,42 @@ int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, switch (new_state) { case IB_QPS_RESET: + if (qp->state != IB_QPS_RESET) { + qp->state = IB_QPS_RESET; + spin_lock(&dev->pending_lock); + if (!list_empty(&qp->timerwait)) + list_del_init(&qp->timerwait); + if (!list_empty(&qp->piowait)) + list_del_init(&qp->piowait); + spin_unlock(&dev->pending_lock); + qp->s_flags &= ~IPATH_S_ANY_WAIT; + spin_unlock_irq(&qp->s_lock); + /* Stop the sending tasklet */ + tasklet_kill(&qp->s_task); + wait_event(qp->wait_dma, !atomic_read(&qp->s_dma_busy)); + spin_lock_irq(&qp->s_lock); + } ipath_reset_qp(qp, ibqp->qp_type); break; + case IB_QPS_SQD: + qp->s_draining = qp->s_last != qp->s_cur; + qp->state = new_state; + break; + + case IB_QPS_SQE: + if (qp->ibqp.qp_type == IB_QPT_RC) + goto inval; + qp->state = new_state; + break; + case IB_QPS_ERR: lastwqe = ipath_error_qp(qp, IB_WC_WR_FLUSH_ERR); break; default: + qp->state = new_state; break; - } if (attr_mask & IB_QP_PKEY_INDEX) @@ -597,8 +595,7 @@ int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC) qp->s_max_rd_atomic = attr->max_rd_atomic; - qp->state = new_state; - spin_unlock_irqrestore(&qp->s_lock, flags); + spin_unlock_irq(&qp->s_lock); if (lastwqe) { struct ib_event ev; @@ -612,7 +609,7 @@ int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, goto bail; inval: - spin_unlock_irqrestore(&qp->s_lock, flags); + spin_unlock_irq(&qp->s_lock); ret = -EINVAL; bail: @@ -643,7 +640,7 @@ int ipath_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, attr->pkey_index = qp->s_pkey_index; attr->alt_pkey_index = 0; attr->en_sqd_async_notify = 0; - attr->sq_draining = 0; + attr->sq_draining = qp->s_draining; attr->max_rd_atomic = qp->s_max_rd_atomic; attr->max_dest_rd_atomic = qp->r_max_rd_atomic; attr->min_rnr_timer = qp->r_min_rnr_timer; @@ -833,6 +830,7 @@ struct ib_qp *ipath_create_qp(struct ib_pd *ibpd, spin_lock_init(&qp->r_rq.lock); atomic_set(&qp->refcount, 0); init_waitqueue_head(&qp->wait); + init_waitqueue_head(&qp->wait_dma); tasklet_init(&qp->s_task, ipath_do_send, (unsigned long)qp); INIT_LIST_HEAD(&qp->piowait); INIT_LIST_HEAD(&qp->timerwait); @@ -926,6 +924,7 @@ bail_ip: else vfree(qp->r_rq.wq); ipath_free_qp(&dev->qp_table, qp); + free_qpn(&dev->qp_table, qp->ibqp.qp_num); bail_qp: kfree(qp); bail_swq: @@ -947,41 +946,44 @@ int ipath_destroy_qp(struct ib_qp *ibqp) { struct ipath_qp *qp = to_iqp(ibqp); struct ipath_ibdev *dev = to_idev(ibqp->device); - unsigned long flags; - spin_lock_irqsave(&qp->s_lock, flags); - qp->state = IB_QPS_ERR; - spin_unlock_irqrestore(&qp->s_lock, flags); - spin_lock(&dev->n_qps_lock); - dev->n_qps_allocated--; - spin_unlock(&dev->n_qps_lock); + /* Make sure HW and driver activity is stopped. */ + spin_lock_irq(&qp->s_lock); + if (qp->state != IB_QPS_RESET) { + qp->state = IB_QPS_RESET; + spin_lock(&dev->pending_lock); + if (!list_empty(&qp->timerwait)) + list_del_init(&qp->timerwait); + if (!list_empty(&qp->piowait)) + list_del_init(&qp->piowait); + spin_unlock(&dev->pending_lock); + qp->s_flags &= ~IPATH_S_ANY_WAIT; + spin_unlock_irq(&qp->s_lock); + /* Stop the sending tasklet */ + tasklet_kill(&qp->s_task); + wait_event(qp->wait_dma, !atomic_read(&qp->s_dma_busy)); + } else + spin_unlock_irq(&qp->s_lock); - /* Stop the sending tasklet. */ - tasklet_kill(&qp->s_task); + ipath_free_qp(&dev->qp_table, qp); if (qp->s_tx) { atomic_dec(&qp->refcount); if (qp->s_tx->txreq.flags & IPATH_SDMA_TXREQ_F_FREEBUF) kfree(qp->s_tx->txreq.map_addr); + spin_lock_irq(&dev->pending_lock); + list_add(&qp->s_tx->txreq.list, &dev->txreq_free); + spin_unlock_irq(&dev->pending_lock); + qp->s_tx = NULL; } - /* Make sure the QP isn't on the timeout list. */ - spin_lock_irqsave(&dev->pending_lock, flags); - if (!list_empty(&qp->timerwait)) - list_del_init(&qp->timerwait); - if (!list_empty(&qp->piowait)) - list_del_init(&qp->piowait); - if (qp->s_tx) - list_add(&qp->s_tx->txreq.list, &dev->txreq_free); - spin_unlock_irqrestore(&dev->pending_lock, flags); + wait_event(qp->wait, !atomic_read(&qp->refcount)); - /* - * Make sure that the QP is not in the QPN table so receive - * interrupts will discard packets for this QP. XXX Also remove QP - * from multicast table. - */ - if (atomic_read(&qp->refcount) != 0) - ipath_free_qp(&dev->qp_table, qp); + /* all user's cleaned up, mark it available */ + free_qpn(&dev->qp_table, qp->ibqp.qp_num); + spin_lock(&dev->n_qps_lock); + dev->n_qps_allocated--; + spin_unlock(&dev->n_qps_lock); if (qp->ip) kref_put(&qp->ip->ref, ipath_release_mmap_info); @@ -1025,48 +1027,6 @@ bail: return ret; } -/** - * ipath_sqerror_qp - put a QP's send queue into an error state - * @qp: QP who's send queue will be put into an error state - * @wc: the WC responsible for putting the QP in this state - * - * Flushes the send work queue. - * The QP s_lock should be held and interrupts disabled. - */ - -void ipath_sqerror_qp(struct ipath_qp *qp, struct ib_wc *wc) -{ - struct ipath_ibdev *dev = to_idev(qp->ibqp.device); - struct ipath_swqe *wqe = get_swqe_ptr(qp, qp->s_last); - - ipath_dbg("Send queue error on QP%d/%d: err: %d\n", - qp->ibqp.qp_num, qp->remote_qpn, wc->status); - - spin_lock(&dev->pending_lock); - if (!list_empty(&qp->timerwait)) - list_del_init(&qp->timerwait); - if (!list_empty(&qp->piowait)) - list_del_init(&qp->piowait); - spin_unlock(&dev->pending_lock); - - ipath_cq_enter(to_icq(qp->ibqp.send_cq), wc, 1); - if (++qp->s_last >= qp->s_size) - qp->s_last = 0; - - wc->status = IB_WC_WR_FLUSH_ERR; - - while (qp->s_last != qp->s_head) { - wqe = get_swqe_ptr(qp, qp->s_last); - wc->wr_id = wqe->wr.wr_id; - wc->opcode = ib_ipath_wc_opcode[wqe->wr.opcode]; - ipath_cq_enter(to_icq(qp->ibqp.send_cq), wc, 1); - if (++qp->s_last >= qp->s_size) - qp->s_last = 0; - } - qp->s_cur = qp->s_tail = qp->s_head; - qp->state = IB_QPS_SQE; -} - /** * ipath_get_credit - flush the send work queue of a QP * @qp: the qp who's send work queue to flush @@ -1093,9 +1053,10 @@ void ipath_get_credit(struct ipath_qp *qp, u32 aeth) } /* Restart sending if it was blocked due to lack of credits. */ - if (qp->s_cur != qp->s_head && + if ((qp->s_flags & IPATH_S_WAIT_SSN_CREDIT) && + qp->s_cur != qp->s_head && (qp->s_lsn == (u32) -1 || ipath_cmp24(get_swqe_ptr(qp, qp->s_cur)->ssn, qp->s_lsn + 1) <= 0)) - tasklet_hi_schedule(&qp->s_task); + ipath_schedule_send(qp); } diff --git a/drivers/infiniband/hw/ipath/ipath_rc.c b/drivers/infiniband/hw/ipath/ipath_rc.c index c405dfba5531329ae4324ee7690212640522a370..108df667d2eeff235fb7d5a9d7939b755504d551 100644 --- a/drivers/infiniband/hw/ipath/ipath_rc.c +++ b/drivers/infiniband/hw/ipath/ipath_rc.c @@ -92,6 +92,10 @@ static int ipath_make_rc_ack(struct ipath_ibdev *dev, struct ipath_qp *qp, u32 bth0; u32 bth2; + /* Don't send an ACK if we aren't supposed to. */ + if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_RECV_OK)) + goto bail; + /* header size in 32-bit words LRH+BTH = (8+12)/4. */ hwords = 5; @@ -238,14 +242,25 @@ int ipath_make_rc_req(struct ipath_qp *qp) ipath_make_rc_ack(dev, qp, ohdr, pmtu)) goto done; - if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK) || - qp->s_rnr_timeout || qp->s_wait_credit) - goto bail; + if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK)) { + if (!(ib_ipath_state_ops[qp->state] & IPATH_FLUSH_SEND)) + goto bail; + /* We are in the error state, flush the work request. */ + if (qp->s_last == qp->s_head) + goto bail; + /* If DMAs are in progress, we can't flush immediately. */ + if (atomic_read(&qp->s_dma_busy)) { + qp->s_flags |= IPATH_S_WAIT_DMA; + goto bail; + } + wqe = get_swqe_ptr(qp, qp->s_last); + ipath_send_complete(qp, wqe, IB_WC_WR_FLUSH_ERR); + goto done; + } - /* Limit the number of packets sent without an ACK. */ - if (ipath_cmp24(qp->s_psn, qp->s_last_psn + IPATH_PSN_CREDIT) > 0) { - qp->s_wait_credit = 1; - dev->n_rc_stalls++; + /* Leave BUSY set until RNR timeout. */ + if (qp->s_rnr_timeout) { + qp->s_flags |= IPATH_S_WAITING; goto bail; } @@ -257,6 +272,9 @@ int ipath_make_rc_req(struct ipath_qp *qp) wqe = get_swqe_ptr(qp, qp->s_cur); switch (qp->s_state) { default: + if (!(ib_ipath_state_ops[qp->state] & + IPATH_PROCESS_NEXT_SEND_OK)) + goto bail; /* * Resend an old request or start a new one. * @@ -294,8 +312,10 @@ int ipath_make_rc_req(struct ipath_qp *qp) case IB_WR_SEND_WITH_IMM: /* If no credit, return. */ if (qp->s_lsn != (u32) -1 && - ipath_cmp24(wqe->ssn, qp->s_lsn + 1) > 0) + ipath_cmp24(wqe->ssn, qp->s_lsn + 1) > 0) { + qp->s_flags |= IPATH_S_WAIT_SSN_CREDIT; goto bail; + } wqe->lpsn = wqe->psn; if (len > pmtu) { wqe->lpsn += (len - 1) / pmtu; @@ -325,8 +345,10 @@ int ipath_make_rc_req(struct ipath_qp *qp) case IB_WR_RDMA_WRITE_WITH_IMM: /* If no credit, return. */ if (qp->s_lsn != (u32) -1 && - ipath_cmp24(wqe->ssn, qp->s_lsn + 1) > 0) + ipath_cmp24(wqe->ssn, qp->s_lsn + 1) > 0) { + qp->s_flags |= IPATH_S_WAIT_SSN_CREDIT; goto bail; + } ohdr->u.rc.reth.vaddr = cpu_to_be64(wqe->wr.wr.rdma.remote_addr); ohdr->u.rc.reth.rkey = @@ -570,7 +592,11 @@ int ipath_make_rc_req(struct ipath_qp *qp) ipath_make_ruc_header(dev, qp, ohdr, bth0 | (qp->s_state << 24), bth2); done: ret = 1; + goto unlock; + bail: + qp->s_flags &= ~IPATH_S_BUSY; +unlock: spin_unlock_irqrestore(&qp->s_lock, flags); return ret; } @@ -606,7 +632,11 @@ static void send_rc_ack(struct ipath_qp *qp) spin_unlock_irqrestore(&qp->s_lock, flags); + /* Don't try to send ACKs if the link isn't ACTIVE */ dd = dev->dd; + if (!(dd->ipath_flags & IPATH_LINKACTIVE)) + goto done; + piobuf = ipath_getpiobuf(dd, 0, NULL); if (!piobuf) { /* @@ -668,15 +698,16 @@ static void send_rc_ack(struct ipath_qp *qp) goto done; queue_ack: - dev->n_rc_qacks++; - qp->s_flags |= IPATH_S_ACK_PENDING; - qp->s_nak_state = qp->r_nak_state; - qp->s_ack_psn = qp->r_ack_psn; + if (ib_ipath_state_ops[qp->state] & IPATH_PROCESS_RECV_OK) { + dev->n_rc_qacks++; + qp->s_flags |= IPATH_S_ACK_PENDING; + qp->s_nak_state = qp->r_nak_state; + qp->s_ack_psn = qp->r_ack_psn; + + /* Schedule the send tasklet. */ + ipath_schedule_send(qp); + } spin_unlock_irqrestore(&qp->s_lock, flags); - - /* Call ipath_do_rc_send() in another thread. */ - tasklet_hi_schedule(&qp->s_task); - done: return; } @@ -735,7 +766,7 @@ static void reset_psn(struct ipath_qp *qp, u32 psn) /* * Set the state to restart in the middle of a request. * Don't change the s_sge, s_cur_sge, or s_cur_size. - * See ipath_do_rc_send(). + * See ipath_make_rc_req(). */ switch (opcode) { case IB_WR_SEND: @@ -771,27 +802,14 @@ done: * * The QP s_lock should be held and interrupts disabled. */ -void ipath_restart_rc(struct ipath_qp *qp, u32 psn, struct ib_wc *wc) +void ipath_restart_rc(struct ipath_qp *qp, u32 psn) { struct ipath_swqe *wqe = get_swqe_ptr(qp, qp->s_last); struct ipath_ibdev *dev; if (qp->s_retry == 0) { - wc->wr_id = wqe->wr.wr_id; - wc->status = IB_WC_RETRY_EXC_ERR; - wc->opcode = ib_ipath_wc_opcode[wqe->wr.opcode]; - wc->vendor_err = 0; - wc->byte_len = 0; - wc->qp = &qp->ibqp; - wc->imm_data = 0; - wc->src_qp = qp->remote_qpn; - wc->wc_flags = 0; - wc->pkey_index = 0; - wc->slid = qp->remote_ah_attr.dlid; - wc->sl = qp->remote_ah_attr.sl; - wc->dlid_path_bits = 0; - wc->port_num = 0; - ipath_sqerror_qp(qp, wc); + ipath_send_complete(qp, wqe, IB_WC_RETRY_EXC_ERR); + ipath_error_qp(qp, IB_WC_WR_FLUSH_ERR); goto bail; } qp->s_retry--; @@ -804,6 +822,8 @@ void ipath_restart_rc(struct ipath_qp *qp, u32 psn, struct ib_wc *wc) spin_lock(&dev->pending_lock); if (!list_empty(&qp->timerwait)) list_del_init(&qp->timerwait); + if (!list_empty(&qp->piowait)) + list_del_init(&qp->piowait); spin_unlock(&dev->pending_lock); if (wqe->wr.opcode == IB_WR_RDMA_READ) @@ -812,7 +832,7 @@ void ipath_restart_rc(struct ipath_qp *qp, u32 psn, struct ib_wc *wc) dev->n_rc_resends += (qp->s_psn - psn) & IPATH_PSN_MASK; reset_psn(qp, psn); - tasklet_hi_schedule(&qp->s_task); + ipath_schedule_send(qp); bail: return; @@ -820,13 +840,7 @@ bail: static inline void update_last_psn(struct ipath_qp *qp, u32 psn) { - if (qp->s_last_psn != psn) { - qp->s_last_psn = psn; - if (qp->s_wait_credit) { - qp->s_wait_credit = 0; - tasklet_hi_schedule(&qp->s_task); - } - } + qp->s_last_psn = psn; } /** @@ -845,6 +859,7 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode, { struct ipath_ibdev *dev = to_idev(qp->ibqp.device); struct ib_wc wc; + enum ib_wc_status status; struct ipath_swqe *wqe; int ret = 0; u32 ack_psn; @@ -909,7 +924,7 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode, */ update_last_psn(qp, wqe->psn - 1); /* Retry this request. */ - ipath_restart_rc(qp, wqe->psn, &wc); + ipath_restart_rc(qp, wqe->psn); /* * No need to process the ACK/NAK since we are * restarting an earlier request. @@ -925,32 +940,23 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode, wqe->wr.opcode == IB_WR_ATOMIC_FETCH_AND_ADD)) { qp->s_num_rd_atomic--; /* Restart sending task if fence is complete */ - if ((qp->s_flags & IPATH_S_FENCE_PENDING) && - !qp->s_num_rd_atomic) { - qp->s_flags &= ~IPATH_S_FENCE_PENDING; - tasklet_hi_schedule(&qp->s_task); - } else if (qp->s_flags & IPATH_S_RDMAR_PENDING) { - qp->s_flags &= ~IPATH_S_RDMAR_PENDING; - tasklet_hi_schedule(&qp->s_task); - } + if (((qp->s_flags & IPATH_S_FENCE_PENDING) && + !qp->s_num_rd_atomic) || + qp->s_flags & IPATH_S_RDMAR_PENDING) + ipath_schedule_send(qp); } /* Post a send completion queue entry if requested. */ if (!(qp->s_flags & IPATH_S_SIGNAL_REQ_WR) || (wqe->wr.send_flags & IB_SEND_SIGNALED)) { + memset(&wc, 0, sizeof wc); wc.wr_id = wqe->wr.wr_id; wc.status = IB_WC_SUCCESS; wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode]; - wc.vendor_err = 0; wc.byte_len = wqe->length; - wc.imm_data = 0; wc.qp = &qp->ibqp; wc.src_qp = qp->remote_qpn; - wc.wc_flags = 0; - wc.pkey_index = 0; wc.slid = qp->remote_ah_attr.dlid; wc.sl = qp->remote_ah_attr.sl; - wc.dlid_path_bits = 0; - wc.port_num = 0; ipath_cq_enter(to_icq(qp->ibqp.send_cq), &wc, 0); } qp->s_retry = qp->s_retry_cnt; @@ -971,6 +977,8 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode, } else { if (++qp->s_last >= qp->s_size) qp->s_last = 0; + if (qp->state == IB_QPS_SQD && qp->s_last == qp->s_cur) + qp->s_draining = 0; if (qp->s_last == qp->s_tail) break; wqe = get_swqe_ptr(qp, qp->s_last); @@ -994,7 +1002,7 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode, */ if (ipath_cmp24(qp->s_psn, psn) <= 0) { reset_psn(qp, psn + 1); - tasklet_hi_schedule(&qp->s_task); + ipath_schedule_send(qp); } } else if (ipath_cmp24(qp->s_psn, psn) <= 0) { qp->s_state = OP(SEND_LAST); @@ -1012,7 +1020,7 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode, if (qp->s_last == qp->s_tail) goto bail; if (qp->s_rnr_retry == 0) { - wc.status = IB_WC_RNR_RETRY_EXC_ERR; + status = IB_WC_RNR_RETRY_EXC_ERR; goto class_b; } if (qp->s_rnr_retry_cnt < 7) @@ -1033,6 +1041,7 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode, ib_ipath_rnr_table[(aeth >> IPATH_AETH_CREDIT_SHIFT) & IPATH_AETH_CREDIT_MASK]; ipath_insert_rnr_queue(qp); + ipath_schedule_send(qp); goto bail; case 3: /* NAK */ @@ -1050,37 +1059,25 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode, * RDMA READ response which terminates the RDMA * READ. */ - ipath_restart_rc(qp, psn, &wc); + ipath_restart_rc(qp, psn); break; case 1: /* Invalid Request */ - wc.status = IB_WC_REM_INV_REQ_ERR; + status = IB_WC_REM_INV_REQ_ERR; dev->n_other_naks++; goto class_b; case 2: /* Remote Access Error */ - wc.status = IB_WC_REM_ACCESS_ERR; + status = IB_WC_REM_ACCESS_ERR; dev->n_other_naks++; goto class_b; case 3: /* Remote Operation Error */ - wc.status = IB_WC_REM_OP_ERR; + status = IB_WC_REM_OP_ERR; dev->n_other_naks++; class_b: - wc.wr_id = wqe->wr.wr_id; - wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode]; - wc.vendor_err = 0; - wc.byte_len = 0; - wc.qp = &qp->ibqp; - wc.imm_data = 0; - wc.src_qp = qp->remote_qpn; - wc.wc_flags = 0; - wc.pkey_index = 0; - wc.slid = qp->remote_ah_attr.dlid; - wc.sl = qp->remote_ah_attr.sl; - wc.dlid_path_bits = 0; - wc.port_num = 0; - ipath_sqerror_qp(qp, &wc); + ipath_send_complete(qp, wqe, status); + ipath_error_qp(qp, IB_WC_WR_FLUSH_ERR); break; default: @@ -1126,8 +1123,8 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev, int header_in_data) { struct ipath_swqe *wqe; + enum ib_wc_status status; unsigned long flags; - struct ib_wc wc; int diff; u32 pad; u32 aeth; @@ -1135,6 +1132,10 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev, spin_lock_irqsave(&qp->s_lock, flags); + /* Double check we can process this now that we hold the s_lock. */ + if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_RECV_OK)) + goto ack_done; + /* Ignore invalid responses. */ if (ipath_cmp24(psn, qp->s_next_psn) >= 0) goto ack_done; @@ -1159,6 +1160,7 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev, if (unlikely(qp->s_last == qp->s_tail)) goto ack_done; wqe = get_swqe_ptr(qp, qp->s_last); + status = IB_WC_SUCCESS; switch (opcode) { case OP(ACKNOWLEDGE): @@ -1187,6 +1189,7 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev, wqe = get_swqe_ptr(qp, qp->s_last); if (unlikely(wqe->wr.opcode != IB_WR_RDMA_READ)) goto ack_op_err; + qp->r_flags &= ~IPATH_R_RDMAR_SEQ; /* * If this is a response to a resent RDMA read, we * have to be careful to copy the data to the right @@ -1200,7 +1203,10 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev, /* no AETH, no ACK */ if (unlikely(ipath_cmp24(psn, qp->s_last_psn + 1))) { dev->n_rdma_seq++; - ipath_restart_rc(qp, qp->s_last_psn + 1, &wc); + if (qp->r_flags & IPATH_R_RDMAR_SEQ) + goto ack_done; + qp->r_flags |= IPATH_R_RDMAR_SEQ; + ipath_restart_rc(qp, qp->s_last_psn + 1); goto ack_done; } if (unlikely(wqe->wr.opcode != IB_WR_RDMA_READ)) @@ -1261,7 +1267,10 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev, /* ACKs READ req. */ if (unlikely(ipath_cmp24(psn, qp->s_last_psn + 1))) { dev->n_rdma_seq++; - ipath_restart_rc(qp, qp->s_last_psn + 1, &wc); + if (qp->r_flags & IPATH_R_RDMAR_SEQ) + goto ack_done; + qp->r_flags |= IPATH_R_RDMAR_SEQ; + ipath_restart_rc(qp, qp->s_last_psn + 1); goto ack_done; } if (unlikely(wqe->wr.opcode != IB_WR_RDMA_READ)) @@ -1291,31 +1300,16 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev, goto ack_done; } -ack_done: - spin_unlock_irqrestore(&qp->s_lock, flags); - goto bail; - ack_op_err: - wc.status = IB_WC_LOC_QP_OP_ERR; + status = IB_WC_LOC_QP_OP_ERR; goto ack_err; ack_len_err: - wc.status = IB_WC_LOC_LEN_ERR; + status = IB_WC_LOC_LEN_ERR; ack_err: - wc.wr_id = wqe->wr.wr_id; - wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode]; - wc.vendor_err = 0; - wc.byte_len = 0; - wc.imm_data = 0; - wc.qp = &qp->ibqp; - wc.src_qp = qp->remote_qpn; - wc.wc_flags = 0; - wc.pkey_index = 0; - wc.slid = qp->remote_ah_attr.dlid; - wc.sl = qp->remote_ah_attr.sl; - wc.dlid_path_bits = 0; - wc.port_num = 0; - ipath_sqerror_qp(qp, &wc); + ipath_send_complete(qp, wqe, status); + ipath_error_qp(qp, IB_WC_WR_FLUSH_ERR); +ack_done: spin_unlock_irqrestore(&qp->s_lock, flags); bail: return; @@ -1384,7 +1378,12 @@ static inline int ipath_rc_rcv_error(struct ipath_ibdev *dev, psn &= IPATH_PSN_MASK; e = NULL; old_req = 1; + spin_lock_irqsave(&qp->s_lock, flags); + /* Double check we can process this now that we hold the s_lock. */ + if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_RECV_OK)) + goto unlock_done; + for (i = qp->r_head_ack_queue; ; i = prev) { if (i == qp->s_tail_ack_queue) old_req = 0; @@ -1512,7 +1511,7 @@ static inline int ipath_rc_rcv_error(struct ipath_ibdev *dev, break; } qp->r_nak_state = 0; - tasklet_hi_schedule(&qp->s_task); + ipath_schedule_send(qp); unlock_done: spin_unlock_irqrestore(&qp->s_lock, flags); @@ -1523,13 +1522,12 @@ send_ack: return 0; } -static void ipath_rc_error(struct ipath_qp *qp, enum ib_wc_status err) +void ipath_rc_error(struct ipath_qp *qp, enum ib_wc_status err) { unsigned long flags; int lastwqe; spin_lock_irqsave(&qp->s_lock, flags); - qp->state = IB_QPS_ERR; lastwqe = ipath_error_qp(qp, err); spin_unlock_irqrestore(&qp->s_lock, flags); @@ -1545,18 +1543,15 @@ static void ipath_rc_error(struct ipath_qp *qp, enum ib_wc_status err) static inline void ipath_update_ack_queue(struct ipath_qp *qp, unsigned n) { - unsigned long flags; unsigned next; next = n + 1; if (next > IPATH_MAX_RDMA_ATOMIC) next = 0; - spin_lock_irqsave(&qp->s_lock, flags); if (n == qp->s_tail_ack_queue) { qp->s_tail_ack_queue = next; qp->s_ack_state = OP(ACKNOWLEDGE); } - spin_unlock_irqrestore(&qp->s_lock, flags); } /** @@ -1585,6 +1580,7 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, int diff; struct ib_reth *reth; int header_in_data; + unsigned long flags; /* Validate the SLID. See Ch. 9.6.1.5 */ if (unlikely(be16_to_cpu(hdr->lrh[3]) != qp->remote_ah_attr.dlid)) @@ -1643,11 +1639,7 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, opcode == OP(SEND_LAST) || opcode == OP(SEND_LAST_WITH_IMMEDIATE)) break; - nack_inv: - ipath_rc_error(qp, IB_WC_REM_INV_REQ_ERR); - qp->r_nak_state = IB_NAK_INVALID_REQUEST; - qp->r_ack_psn = qp->r_psn; - goto send_ack; + goto nack_inv; case OP(RDMA_WRITE_FIRST): case OP(RDMA_WRITE_MIDDLE): @@ -1673,18 +1665,13 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, break; } - wc.imm_data = 0; - wc.wc_flags = 0; + memset(&wc, 0, sizeof wc); /* OK, process the packet. */ switch (opcode) { case OP(SEND_FIRST): - if (!ipath_get_rwqe(qp, 0)) { - rnr_nak: - qp->r_nak_state = IB_RNR_NAK | qp->r_min_rnr_timer; - qp->r_ack_psn = qp->r_psn; - goto send_ack; - } + if (!ipath_get_rwqe(qp, 0)) + goto rnr_nak; qp->r_rcv_len = 0; /* FALLTHROUGH */ case OP(SEND_MIDDLE): @@ -1741,20 +1728,19 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, goto nack_inv; ipath_copy_sge(&qp->r_sge, data, tlen); qp->r_msn++; - if (!qp->r_wrid_valid) + if (!test_and_clear_bit(IPATH_R_WRID_VALID, &qp->r_aflags)) break; - qp->r_wrid_valid = 0; wc.wr_id = qp->r_wr_id; wc.status = IB_WC_SUCCESS; - wc.opcode = IB_WC_RECV; - wc.vendor_err = 0; + if (opcode == OP(RDMA_WRITE_LAST_WITH_IMMEDIATE) || + opcode == OP(RDMA_WRITE_ONLY_WITH_IMMEDIATE)) + wc.opcode = IB_WC_RECV_RDMA_WITH_IMM; + else + wc.opcode = IB_WC_RECV; wc.qp = &qp->ibqp; wc.src_qp = qp->remote_qpn; - wc.pkey_index = 0; wc.slid = qp->remote_ah_attr.dlid; wc.sl = qp->remote_ah_attr.sl; - wc.dlid_path_bits = 0; - wc.port_num = 0; /* Signal completion event if the solicited bit is set. */ ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, (ohdr->bth[0] & @@ -1815,9 +1801,13 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, next = qp->r_head_ack_queue + 1; if (next > IPATH_MAX_RDMA_ATOMIC) next = 0; + spin_lock_irqsave(&qp->s_lock, flags); + /* Double check we can process this while holding the s_lock. */ + if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_RECV_OK)) + goto unlock; if (unlikely(next == qp->s_tail_ack_queue)) { if (!qp->s_ack_queue[next].sent) - goto nack_inv; + goto nack_inv_unlck; ipath_update_ack_queue(qp, next); } e = &qp->s_ack_queue[qp->r_head_ack_queue]; @@ -1838,7 +1828,7 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, ok = ipath_rkey_ok(qp, &e->rdma_sge, len, vaddr, rkey, IB_ACCESS_REMOTE_READ); if (unlikely(!ok)) - goto nack_acc; + goto nack_acc_unlck; /* * Update the next expected PSN. We add 1 later * below, so only add the remainder here. @@ -1865,13 +1855,12 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, qp->r_psn++; qp->r_state = opcode; qp->r_nak_state = 0; - barrier(); qp->r_head_ack_queue = next; - /* Call ipath_do_rc_send() in another thread. */ - tasklet_hi_schedule(&qp->s_task); + /* Schedule the send tasklet. */ + ipath_schedule_send(qp); - goto done; + goto unlock; } case OP(COMPARE_SWAP): @@ -1890,9 +1879,13 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, next = qp->r_head_ack_queue + 1; if (next > IPATH_MAX_RDMA_ATOMIC) next = 0; + spin_lock_irqsave(&qp->s_lock, flags); + /* Double check we can process this while holding the s_lock. */ + if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_RECV_OK)) + goto unlock; if (unlikely(next == qp->s_tail_ack_queue)) { if (!qp->s_ack_queue[next].sent) - goto nack_inv; + goto nack_inv_unlck; ipath_update_ack_queue(qp, next); } if (!header_in_data) @@ -1902,13 +1895,13 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, vaddr = ((u64) be32_to_cpu(ateth->vaddr[0]) << 32) | be32_to_cpu(ateth->vaddr[1]); if (unlikely(vaddr & (sizeof(u64) - 1))) - goto nack_inv; + goto nack_inv_unlck; rkey = be32_to_cpu(ateth->rkey); /* Check rkey & NAK */ if (unlikely(!ipath_rkey_ok(qp, &qp->r_sge, sizeof(u64), vaddr, rkey, IB_ACCESS_REMOTE_ATOMIC))) - goto nack_acc; + goto nack_acc_unlck; /* Perform atomic OP and save result. */ maddr = (atomic64_t *) qp->r_sge.sge.vaddr; sdata = be64_to_cpu(ateth->swap_data); @@ -1925,13 +1918,12 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, qp->r_psn++; qp->r_state = opcode; qp->r_nak_state = 0; - barrier(); qp->r_head_ack_queue = next; - /* Call ipath_do_rc_send() in another thread. */ - tasklet_hi_schedule(&qp->s_task); + /* Schedule the send tasklet. */ + ipath_schedule_send(qp); - goto done; + goto unlock; } default: @@ -1947,14 +1939,31 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, goto send_ack; goto done; +rnr_nak: + qp->r_nak_state = IB_RNR_NAK | qp->r_min_rnr_timer; + qp->r_ack_psn = qp->r_psn; + goto send_ack; + +nack_inv_unlck: + spin_unlock_irqrestore(&qp->s_lock, flags); +nack_inv: + ipath_rc_error(qp, IB_WC_LOC_QP_OP_ERR); + qp->r_nak_state = IB_NAK_INVALID_REQUEST; + qp->r_ack_psn = qp->r_psn; + goto send_ack; + +nack_acc_unlck: + spin_unlock_irqrestore(&qp->s_lock, flags); nack_acc: - ipath_rc_error(qp, IB_WC_REM_ACCESS_ERR); + ipath_rc_error(qp, IB_WC_LOC_PROT_ERR); qp->r_nak_state = IB_NAK_REMOTE_ACCESS_ERROR; qp->r_ack_psn = qp->r_psn; - send_ack: send_rc_ack(qp); + goto done; +unlock: + spin_unlock_irqrestore(&qp->s_lock, flags); done: return; } diff --git a/drivers/infiniband/hw/ipath/ipath_ruc.c b/drivers/infiniband/hw/ipath/ipath_ruc.c index 8ac5c1d82ccdb9cdb49b1b01db264c38e9f04fd0..a4b5521567fe6bbb9fc62cf4340163ac14bf8a79 100644 --- a/drivers/infiniband/hw/ipath/ipath_ruc.c +++ b/drivers/infiniband/hw/ipath/ipath_ruc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved. + * Copyright (c) 2006, 2007, 2008 QLogic Corporation. All rights reserved. * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved. * * This software is available to you under a choice of one of two @@ -78,6 +78,7 @@ const u32 ib_ipath_rnr_table[32] = { * ipath_insert_rnr_queue - put QP on the RNR timeout list for the device * @qp: the QP * + * Called with the QP s_lock held and interrupts disabled. * XXX Use a simple list for now. We might need a priority * queue if we have lots of QPs waiting for RNR timeouts * but that should be rare. @@ -85,9 +86,9 @@ const u32 ib_ipath_rnr_table[32] = { void ipath_insert_rnr_queue(struct ipath_qp *qp) { struct ipath_ibdev *dev = to_idev(qp->ibqp.device); - unsigned long flags; - spin_lock_irqsave(&dev->pending_lock, flags); + /* We already did a spin_lock_irqsave(), so just use spin_lock */ + spin_lock(&dev->pending_lock); if (list_empty(&dev->rnrwait)) list_add(&qp->timerwait, &dev->rnrwait); else { @@ -109,7 +110,7 @@ void ipath_insert_rnr_queue(struct ipath_qp *qp) nqp->s_rnr_timeout -= qp->s_rnr_timeout; list_add(&qp->timerwait, l); } - spin_unlock_irqrestore(&dev->pending_lock, flags); + spin_unlock(&dev->pending_lock); } /** @@ -140,20 +141,11 @@ int ipath_init_sge(struct ipath_qp *qp, struct ipath_rwqe *wqe, goto bail; bad_lkey: + memset(&wc, 0, sizeof(wc)); wc.wr_id = wqe->wr_id; wc.status = IB_WC_LOC_PROT_ERR; wc.opcode = IB_WC_RECV; - wc.vendor_err = 0; - wc.byte_len = 0; - wc.imm_data = 0; wc.qp = &qp->ibqp; - wc.src_qp = 0; - wc.wc_flags = 0; - wc.pkey_index = 0; - wc.slid = 0; - wc.sl = 0; - wc.dlid_path_bits = 0; - wc.port_num = 0; /* Signal solicited completion event. */ ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, 1); ret = 0; @@ -194,6 +186,11 @@ int ipath_get_rwqe(struct ipath_qp *qp, int wr_id_only) } spin_lock_irqsave(&rq->lock, flags); + if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_RECV_OK)) { + ret = 0; + goto unlock; + } + wq = rq->wq; tail = wq->tail; /* Validate tail before using it since it is user writable. */ @@ -201,9 +198,8 @@ int ipath_get_rwqe(struct ipath_qp *qp, int wr_id_only) tail = 0; do { if (unlikely(tail == wq->head)) { - spin_unlock_irqrestore(&rq->lock, flags); ret = 0; - goto bail; + goto unlock; } /* Make sure entry is read after head index is read. */ smp_rmb(); @@ -216,7 +212,7 @@ int ipath_get_rwqe(struct ipath_qp *qp, int wr_id_only) wq->tail = tail; ret = 1; - qp->r_wrid_valid = 1; + set_bit(IPATH_R_WRID_VALID, &qp->r_aflags); if (handler) { u32 n; @@ -243,8 +239,8 @@ int ipath_get_rwqe(struct ipath_qp *qp, int wr_id_only) goto bail; } } +unlock: spin_unlock_irqrestore(&rq->lock, flags); - bail: return ret; } @@ -270,38 +266,63 @@ static void ipath_ruc_loopback(struct ipath_qp *sqp) struct ib_wc wc; u64 sdata; atomic64_t *maddr; + enum ib_wc_status send_status; + /* + * Note that we check the responder QP state after + * checking the requester's state. + */ qp = ipath_lookup_qpn(&dev->qp_table, sqp->remote_qpn); - if (!qp) { - dev->n_pkt_drops++; - return; - } -again: spin_lock_irqsave(&sqp->s_lock, flags); - if (!(ib_ipath_state_ops[sqp->state] & IPATH_PROCESS_SEND_OK) || - sqp->s_rnr_timeout) { - spin_unlock_irqrestore(&sqp->s_lock, flags); - goto done; - } + /* Return if we are already busy processing a work request. */ + if ((sqp->s_flags & (IPATH_S_BUSY | IPATH_S_ANY_WAIT)) || + !(ib_ipath_state_ops[sqp->state] & IPATH_PROCESS_OR_FLUSH_SEND)) + goto unlock; - /* Get the next send request. */ - if (sqp->s_last == sqp->s_head) { - /* Send work queue is empty. */ - spin_unlock_irqrestore(&sqp->s_lock, flags); - goto done; + sqp->s_flags |= IPATH_S_BUSY; + +again: + if (sqp->s_last == sqp->s_head) + goto clr_busy; + wqe = get_swqe_ptr(sqp, sqp->s_last); + + /* Return if it is not OK to start a new work reqeust. */ + if (!(ib_ipath_state_ops[sqp->state] & IPATH_PROCESS_NEXT_SEND_OK)) { + if (!(ib_ipath_state_ops[sqp->state] & IPATH_FLUSH_SEND)) + goto clr_busy; + /* We are in the error state, flush the work request. */ + send_status = IB_WC_WR_FLUSH_ERR; + goto flush_send; } /* * We can rely on the entry not changing without the s_lock * being held until we update s_last. + * We increment s_cur to indicate s_last is in progress. */ - wqe = get_swqe_ptr(sqp, sqp->s_last); + if (sqp->s_last == sqp->s_cur) { + if (++sqp->s_cur >= sqp->s_size) + sqp->s_cur = 0; + } spin_unlock_irqrestore(&sqp->s_lock, flags); - wc.wc_flags = 0; - wc.imm_data = 0; + if (!qp || !(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_RECV_OK)) { + dev->n_pkt_drops++; + /* + * For RC, the requester would timeout and retry so + * shortcut the timeouts and just signal too many retries. + */ + if (sqp->ibqp.qp_type == IB_QPT_RC) + send_status = IB_WC_RETRY_EXC_ERR; + else + send_status = IB_WC_SUCCESS; + goto serr; + } + + memset(&wc, 0, sizeof wc); + send_status = IB_WC_SUCCESS; sqp->s_sge.sge = wqe->sg_list[0]; sqp->s_sge.sg_list = wqe->sg_list + 1; @@ -313,75 +334,33 @@ again: wc.imm_data = wqe->wr.ex.imm_data; /* FALLTHROUGH */ case IB_WR_SEND: - if (!ipath_get_rwqe(qp, 0)) { - rnr_nak: - /* Handle RNR NAK */ - if (qp->ibqp.qp_type == IB_QPT_UC) - goto send_comp; - if (sqp->s_rnr_retry == 0) { - wc.status = IB_WC_RNR_RETRY_EXC_ERR; - goto err; - } - if (sqp->s_rnr_retry_cnt < 7) - sqp->s_rnr_retry--; - dev->n_rnr_naks++; - sqp->s_rnr_timeout = - ib_ipath_rnr_table[qp->r_min_rnr_timer]; - ipath_insert_rnr_queue(sqp); - goto done; - } + if (!ipath_get_rwqe(qp, 0)) + goto rnr_nak; break; case IB_WR_RDMA_WRITE_WITH_IMM: - if (unlikely(!(qp->qp_access_flags & - IB_ACCESS_REMOTE_WRITE))) { - wc.status = IB_WC_REM_INV_REQ_ERR; - goto err; - } + if (unlikely(!(qp->qp_access_flags & IB_ACCESS_REMOTE_WRITE))) + goto inv_err; wc.wc_flags = IB_WC_WITH_IMM; wc.imm_data = wqe->wr.ex.imm_data; if (!ipath_get_rwqe(qp, 1)) goto rnr_nak; /* FALLTHROUGH */ case IB_WR_RDMA_WRITE: - if (unlikely(!(qp->qp_access_flags & - IB_ACCESS_REMOTE_WRITE))) { - wc.status = IB_WC_REM_INV_REQ_ERR; - goto err; - } + if (unlikely(!(qp->qp_access_flags & IB_ACCESS_REMOTE_WRITE))) + goto inv_err; if (wqe->length == 0) break; if (unlikely(!ipath_rkey_ok(qp, &qp->r_sge, wqe->length, wqe->wr.wr.rdma.remote_addr, wqe->wr.wr.rdma.rkey, - IB_ACCESS_REMOTE_WRITE))) { - acc_err: - wc.status = IB_WC_REM_ACCESS_ERR; - err: - wc.wr_id = wqe->wr.wr_id; - wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode]; - wc.vendor_err = 0; - wc.byte_len = 0; - wc.qp = &sqp->ibqp; - wc.src_qp = sqp->remote_qpn; - wc.pkey_index = 0; - wc.slid = sqp->remote_ah_attr.dlid; - wc.sl = sqp->remote_ah_attr.sl; - wc.dlid_path_bits = 0; - wc.port_num = 0; - spin_lock_irqsave(&sqp->s_lock, flags); - ipath_sqerror_qp(sqp, &wc); - spin_unlock_irqrestore(&sqp->s_lock, flags); - goto done; - } + IB_ACCESS_REMOTE_WRITE))) + goto acc_err; break; case IB_WR_RDMA_READ: - if (unlikely(!(qp->qp_access_flags & - IB_ACCESS_REMOTE_READ))) { - wc.status = IB_WC_REM_INV_REQ_ERR; - goto err; - } + if (unlikely(!(qp->qp_access_flags & IB_ACCESS_REMOTE_READ))) + goto inv_err; if (unlikely(!ipath_rkey_ok(qp, &sqp->s_sge, wqe->length, wqe->wr.wr.rdma.remote_addr, wqe->wr.wr.rdma.rkey, @@ -394,11 +373,8 @@ again: case IB_WR_ATOMIC_CMP_AND_SWP: case IB_WR_ATOMIC_FETCH_AND_ADD: - if (unlikely(!(qp->qp_access_flags & - IB_ACCESS_REMOTE_ATOMIC))) { - wc.status = IB_WC_REM_INV_REQ_ERR; - goto err; - } + if (unlikely(!(qp->qp_access_flags & IB_ACCESS_REMOTE_ATOMIC))) + goto inv_err; if (unlikely(!ipath_rkey_ok(qp, &qp->r_sge, sizeof(u64), wqe->wr.wr.atomic.remote_addr, wqe->wr.wr.atomic.rkey, @@ -415,7 +391,8 @@ again: goto send_comp; default: - goto done; + send_status = IB_WC_LOC_QP_OP_ERR; + goto serr; } sge = &sqp->s_sge.sge; @@ -448,8 +425,7 @@ again: sqp->s_len -= len; } - if (wqe->wr.opcode == IB_WR_RDMA_WRITE || - wqe->wr.opcode == IB_WR_RDMA_READ) + if (!test_and_clear_bit(IPATH_R_WRID_VALID, &qp->r_aflags)) goto send_comp; if (wqe->wr.opcode == IB_WR_RDMA_WRITE_WITH_IMM) @@ -458,32 +434,89 @@ again: wc.opcode = IB_WC_RECV; wc.wr_id = qp->r_wr_id; wc.status = IB_WC_SUCCESS; - wc.vendor_err = 0; wc.byte_len = wqe->length; wc.qp = &qp->ibqp; wc.src_qp = qp->remote_qpn; - wc.pkey_index = 0; wc.slid = qp->remote_ah_attr.dlid; wc.sl = qp->remote_ah_attr.sl; - wc.dlid_path_bits = 0; wc.port_num = 1; /* Signal completion event if the solicited bit is set. */ ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, wqe->wr.send_flags & IB_SEND_SOLICITED); send_comp: + spin_lock_irqsave(&sqp->s_lock, flags); +flush_send: sqp->s_rnr_retry = sqp->s_rnr_retry_cnt; - ipath_send_complete(sqp, wqe, IB_WC_SUCCESS); + ipath_send_complete(sqp, wqe, send_status); goto again; +rnr_nak: + /* Handle RNR NAK */ + if (qp->ibqp.qp_type == IB_QPT_UC) + goto send_comp; + /* + * Note: we don't need the s_lock held since the BUSY flag + * makes this single threaded. + */ + if (sqp->s_rnr_retry == 0) { + send_status = IB_WC_RNR_RETRY_EXC_ERR; + goto serr; + } + if (sqp->s_rnr_retry_cnt < 7) + sqp->s_rnr_retry--; + spin_lock_irqsave(&sqp->s_lock, flags); + if (!(ib_ipath_state_ops[sqp->state] & IPATH_PROCESS_RECV_OK)) + goto clr_busy; + sqp->s_flags |= IPATH_S_WAITING; + dev->n_rnr_naks++; + sqp->s_rnr_timeout = ib_ipath_rnr_table[qp->r_min_rnr_timer]; + ipath_insert_rnr_queue(sqp); + goto clr_busy; + +inv_err: + send_status = IB_WC_REM_INV_REQ_ERR; + wc.status = IB_WC_LOC_QP_OP_ERR; + goto err; + +acc_err: + send_status = IB_WC_REM_ACCESS_ERR; + wc.status = IB_WC_LOC_PROT_ERR; +err: + /* responder goes to error state */ + ipath_rc_error(qp, wc.status); + +serr: + spin_lock_irqsave(&sqp->s_lock, flags); + ipath_send_complete(sqp, wqe, send_status); + if (sqp->ibqp.qp_type == IB_QPT_RC) { + int lastwqe = ipath_error_qp(sqp, IB_WC_WR_FLUSH_ERR); + + sqp->s_flags &= ~IPATH_S_BUSY; + spin_unlock_irqrestore(&sqp->s_lock, flags); + if (lastwqe) { + struct ib_event ev; + + ev.device = sqp->ibqp.device; + ev.element.qp = &sqp->ibqp; + ev.event = IB_EVENT_QP_LAST_WQE_REACHED; + sqp->ibqp.event_handler(&ev, sqp->ibqp.qp_context); + } + goto done; + } +clr_busy: + sqp->s_flags &= ~IPATH_S_BUSY; +unlock: + spin_unlock_irqrestore(&sqp->s_lock, flags); done: - if (atomic_dec_and_test(&qp->refcount)) + if (qp && atomic_dec_and_test(&qp->refcount)) wake_up(&qp->wait); } -static void want_buffer(struct ipath_devdata *dd) +static void want_buffer(struct ipath_devdata *dd, struct ipath_qp *qp) { - if (!(dd->ipath_flags & IPATH_HAS_SEND_DMA)) { + if (!(dd->ipath_flags & IPATH_HAS_SEND_DMA) || + qp->ibqp.qp_type == IB_QPT_SMI) { unsigned long flags; spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags); @@ -501,26 +534,36 @@ static void want_buffer(struct ipath_devdata *dd) * @dev: the device we ran out of buffers on * * Called when we run out of PIO buffers. + * If we are now in the error state, return zero to flush the + * send work request. */ -static void ipath_no_bufs_available(struct ipath_qp *qp, +static int ipath_no_bufs_available(struct ipath_qp *qp, struct ipath_ibdev *dev) { unsigned long flags; + int ret = 1; /* * Note that as soon as want_buffer() is called and * possibly before it returns, ipath_ib_piobufavail() - * could be called. If we are still in the tasklet function, - * tasklet_hi_schedule() will not call us until the next time - * tasklet_hi_schedule() is called. - * We leave the busy flag set so that another post send doesn't - * try to put the same QP on the piowait list again. + * could be called. Therefore, put QP on the piowait list before + * enabling the PIO avail interrupt. */ - spin_lock_irqsave(&dev->pending_lock, flags); - list_add_tail(&qp->piowait, &dev->piowait); - spin_unlock_irqrestore(&dev->pending_lock, flags); - want_buffer(dev->dd); - dev->n_piowait++; + spin_lock_irqsave(&qp->s_lock, flags); + if (ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK) { + dev->n_piowait++; + qp->s_flags |= IPATH_S_WAITING; + qp->s_flags &= ~IPATH_S_BUSY; + spin_lock(&dev->pending_lock); + if (list_empty(&qp->piowait)) + list_add_tail(&qp->piowait, &dev->piowait); + spin_unlock(&dev->pending_lock); + } else + ret = 0; + spin_unlock_irqrestore(&qp->s_lock, flags); + if (ret) + want_buffer(dev->dd, qp); + return ret; } /** @@ -596,15 +639,13 @@ void ipath_do_send(unsigned long data) struct ipath_qp *qp = (struct ipath_qp *)data; struct ipath_ibdev *dev = to_idev(qp->ibqp.device); int (*make_req)(struct ipath_qp *qp); - - if (test_and_set_bit(IPATH_S_BUSY, &qp->s_busy)) - goto bail; + unsigned long flags; if ((qp->ibqp.qp_type == IB_QPT_RC || qp->ibqp.qp_type == IB_QPT_UC) && qp->remote_ah_attr.dlid == dev->dd->ipath_lid) { ipath_ruc_loopback(qp); - goto clear; + goto bail; } if (qp->ibqp.qp_type == IB_QPT_RC) @@ -614,6 +655,19 @@ void ipath_do_send(unsigned long data) else make_req = ipath_make_ud_req; + spin_lock_irqsave(&qp->s_lock, flags); + + /* Return if we are already busy processing a work request. */ + if ((qp->s_flags & (IPATH_S_BUSY | IPATH_S_ANY_WAIT)) || + !(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_OR_FLUSH_SEND)) { + spin_unlock_irqrestore(&qp->s_lock, flags); + goto bail; + } + + qp->s_flags |= IPATH_S_BUSY; + + spin_unlock_irqrestore(&qp->s_lock, flags); + again: /* Check for a constructed packet to be sent. */ if (qp->s_hdrwords != 0) { @@ -623,8 +677,8 @@ again: */ if (ipath_verbs_send(qp, &qp->s_hdr, qp->s_hdrwords, qp->s_cur_sge, qp->s_cur_size)) { - ipath_no_bufs_available(qp, dev); - goto bail; + if (ipath_no_bufs_available(qp, dev)) + goto bail; } dev->n_unicast_xmit++; /* Record that we sent the packet and s_hdr is empty. */ @@ -633,16 +687,20 @@ again: if (make_req(qp)) goto again; -clear: - clear_bit(IPATH_S_BUSY, &qp->s_busy); + bail:; } +/* + * This should be called with s_lock held. + */ void ipath_send_complete(struct ipath_qp *qp, struct ipath_swqe *wqe, enum ib_wc_status status) { - unsigned long flags; - u32 last; + u32 old_last, last; + + if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_OR_FLUSH_SEND)) + return; /* See ch. 11.2.4.1 and 10.7.3.1 */ if (!(qp->s_flags & IPATH_S_SIGNAL_REQ_WR) || @@ -650,27 +708,25 @@ void ipath_send_complete(struct ipath_qp *qp, struct ipath_swqe *wqe, status != IB_WC_SUCCESS) { struct ib_wc wc; + memset(&wc, 0, sizeof wc); wc.wr_id = wqe->wr.wr_id; wc.status = status; wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode]; - wc.vendor_err = 0; - wc.byte_len = wqe->length; - wc.imm_data = 0; wc.qp = &qp->ibqp; - wc.src_qp = 0; - wc.wc_flags = 0; - wc.pkey_index = 0; - wc.slid = 0; - wc.sl = 0; - wc.dlid_path_bits = 0; - wc.port_num = 0; - ipath_cq_enter(to_icq(qp->ibqp.send_cq), &wc, 0); + if (status == IB_WC_SUCCESS) + wc.byte_len = wqe->length; + ipath_cq_enter(to_icq(qp->ibqp.send_cq), &wc, + status != IB_WC_SUCCESS); } - spin_lock_irqsave(&qp->s_lock, flags); - last = qp->s_last; + old_last = last = qp->s_last; if (++last >= qp->s_size) last = 0; qp->s_last = last; - spin_unlock_irqrestore(&qp->s_lock, flags); + if (qp->s_cur == old_last) + qp->s_cur = last; + if (qp->s_tail == old_last) + qp->s_tail = last; + if (qp->state == IB_QPS_SQD && last == qp->s_cur) + qp->s_draining = 0; } diff --git a/drivers/infiniband/hw/ipath/ipath_sdma.c b/drivers/infiniband/hw/ipath/ipath_sdma.c index 1974df7a9f789e6e19568876f59c9a4c5f5783ae..3697449c1ba4e7042d89f34ac334b66ff4872e2a 100644 --- a/drivers/infiniband/hw/ipath/ipath_sdma.c +++ b/drivers/infiniband/hw/ipath/ipath_sdma.c @@ -308,13 +308,15 @@ static void sdma_abort_task(unsigned long opaque) spin_unlock_irqrestore(&dd->ipath_sdma_lock, flags); /* - * Don't restart sdma here. Wait until link is up to ACTIVE. - * VL15 MADs used to bring the link up use PIO, and multiple - * link transitions otherwise cause the sdma engine to be + * Don't restart sdma here (with the exception + * below). Wait until link is up to ACTIVE. VL15 MADs + * used to bring the link up use PIO, and multiple link + * transitions otherwise cause the sdma engine to be * stopped and started multiple times. - * The disable is done here, including the shadow, so the - * state is kept consistent. - * See ipath_restart_sdma() for the actual starting of sdma. + * The disable is done here, including the shadow, + * so the state is kept consistent. + * See ipath_restart_sdma() for the actual starting + * of sdma. */ spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags); dd->ipath_sendctrl &= ~INFINIPATH_S_SDMAENABLE; @@ -326,6 +328,13 @@ static void sdma_abort_task(unsigned long opaque) /* make sure I see next message */ dd->ipath_sdma_abort_jiffies = 0; + /* + * Not everything that takes SDMA offline is a link + * status change. If the link was up, restart SDMA. + */ + if (dd->ipath_flags & IPATH_LINKACTIVE) + ipath_restart_sdma(dd); + goto done; } @@ -427,7 +436,12 @@ int setup_sdma(struct ipath_devdata *dd) goto done; } - dd->ipath_sdma_status = 0; + /* + * Set initial status as if we had been up, then gone down. + * This lets initial start on transition to ACTIVE be the + * same as restart after link flap. + */ + dd->ipath_sdma_status = IPATH_SDMA_ABORT_ABORTED; dd->ipath_sdma_abort_jiffies = 0; dd->ipath_sdma_generation = 0; dd->ipath_sdma_descq_tail = 0; @@ -449,16 +463,19 @@ int setup_sdma(struct ipath_devdata *dd) ipath_write_kreg(dd, dd->ipath_kregs->kr_senddmaheadaddr, dd->ipath_sdma_head_phys); - /* Reserve all the former "kernel" piobufs */ - n = dd->ipath_piobcnt2k + dd->ipath_piobcnt4k - dd->ipath_pioreserved; - for (i = dd->ipath_lastport_piobuf; i < n; ++i) { + /* + * Reserve all the former "kernel" piobufs, using high number range + * so we get as many 4K buffers as possible + */ + n = dd->ipath_piobcnt2k + dd->ipath_piobcnt4k; + i = dd->ipath_lastport_piobuf + dd->ipath_pioreserved; + ipath_chg_pioavailkernel(dd, i, n - i , 0); + for (; i < n; ++i) { unsigned word = i / 64; unsigned bit = i & 63; BUG_ON(word >= 3); senddmabufmask[word] |= 1ULL << bit; } - ipath_chg_pioavailkernel(dd, dd->ipath_lastport_piobuf, - n - dd->ipath_lastport_piobuf, 0); ipath_write_kreg(dd, dd->ipath_kregs->kr_senddmabufmask0, senddmabufmask[0]); ipath_write_kreg(dd, dd->ipath_kregs->kr_senddmabufmask1, @@ -615,6 +632,9 @@ void ipath_restart_sdma(struct ipath_devdata *dd) ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags); + /* notify upper layers */ + ipath_ib_piobufavail(dd->verbs_dev); + bail: return; } diff --git a/drivers/infiniband/hw/ipath/ipath_uc.c b/drivers/infiniband/hw/ipath/ipath_uc.c index bfe8926b5514a7a9e4b3bd6c5b67ab63768bf6c7..7fd18e833907dda4ae8a117c3ce6e145a57c0a43 100644 --- a/drivers/infiniband/hw/ipath/ipath_uc.c +++ b/drivers/infiniband/hw/ipath/ipath_uc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved. + * Copyright (c) 2006, 2007, 2008 QLogic Corporation. All rights reserved. * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved. * * This software is available to you under a choice of one of two @@ -47,14 +47,30 @@ int ipath_make_uc_req(struct ipath_qp *qp) { struct ipath_other_headers *ohdr; struct ipath_swqe *wqe; + unsigned long flags; u32 hwords; u32 bth0; u32 len; u32 pmtu = ib_mtu_enum_to_int(qp->path_mtu); int ret = 0; - if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK)) + spin_lock_irqsave(&qp->s_lock, flags); + + if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK)) { + if (!(ib_ipath_state_ops[qp->state] & IPATH_FLUSH_SEND)) + goto bail; + /* We are in the error state, flush the work request. */ + if (qp->s_last == qp->s_head) + goto bail; + /* If DMAs are in progress, we can't flush immediately. */ + if (atomic_read(&qp->s_dma_busy)) { + qp->s_flags |= IPATH_S_WAIT_DMA; + goto bail; + } + wqe = get_swqe_ptr(qp, qp->s_last); + ipath_send_complete(qp, wqe, IB_WC_WR_FLUSH_ERR); goto done; + } ohdr = &qp->s_hdr.u.oth; if (qp->remote_ah_attr.ah_flags & IB_AH_GRH) @@ -69,9 +85,12 @@ int ipath_make_uc_req(struct ipath_qp *qp) qp->s_wqe = NULL; switch (qp->s_state) { default: + if (!(ib_ipath_state_ops[qp->state] & + IPATH_PROCESS_NEXT_SEND_OK)) + goto bail; /* Check if send work queue is empty. */ if (qp->s_cur == qp->s_head) - goto done; + goto bail; /* * Start a new request. */ @@ -134,7 +153,7 @@ int ipath_make_uc_req(struct ipath_qp *qp) break; default: - goto done; + goto bail; } break; @@ -194,9 +213,14 @@ int ipath_make_uc_req(struct ipath_qp *qp) ipath_make_ruc_header(to_idev(qp->ibqp.device), qp, ohdr, bth0 | (qp->s_state << 24), qp->s_next_psn++ & IPATH_PSN_MASK); +done: ret = 1; + goto unlock; -done: +bail: + qp->s_flags &= ~IPATH_S_BUSY; +unlock: + spin_unlock_irqrestore(&qp->s_lock, flags); return ret; } @@ -258,8 +282,7 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, */ opcode = be32_to_cpu(ohdr->bth[0]) >> 24; - wc.imm_data = 0; - wc.wc_flags = 0; + memset(&wc, 0, sizeof wc); /* Compare the PSN verses the expected PSN. */ if (unlikely(ipath_cmp24(psn, qp->r_psn) != 0)) { @@ -322,8 +345,8 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, case OP(SEND_ONLY): case OP(SEND_ONLY_WITH_IMMEDIATE): send_first: - if (qp->r_reuse_sge) { - qp->r_reuse_sge = 0; + if (qp->r_flags & IPATH_R_REUSE_SGE) { + qp->r_flags &= ~IPATH_R_REUSE_SGE; qp->r_sge = qp->s_rdma_read_sge; } else if (!ipath_get_rwqe(qp, 0)) { dev->n_pkt_drops++; @@ -340,13 +363,13 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, case OP(SEND_MIDDLE): /* Check for invalid length PMTU or posted rwqe len. */ if (unlikely(tlen != (hdrsize + pmtu + 4))) { - qp->r_reuse_sge = 1; + qp->r_flags |= IPATH_R_REUSE_SGE; dev->n_pkt_drops++; goto done; } qp->r_rcv_len += pmtu; if (unlikely(qp->r_rcv_len > qp->r_len)) { - qp->r_reuse_sge = 1; + qp->r_flags |= IPATH_R_REUSE_SGE; dev->n_pkt_drops++; goto done; } @@ -372,7 +395,7 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, /* Check for invalid length. */ /* XXX LAST len should be >= 1 */ if (unlikely(tlen < (hdrsize + pad + 4))) { - qp->r_reuse_sge = 1; + qp->r_flags |= IPATH_R_REUSE_SGE; dev->n_pkt_drops++; goto done; } @@ -380,7 +403,7 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, tlen -= (hdrsize + pad + 4); wc.byte_len = tlen + qp->r_rcv_len; if (unlikely(wc.byte_len > qp->r_len)) { - qp->r_reuse_sge = 1; + qp->r_flags |= IPATH_R_REUSE_SGE; dev->n_pkt_drops++; goto done; } @@ -390,14 +413,10 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, wc.wr_id = qp->r_wr_id; wc.status = IB_WC_SUCCESS; wc.opcode = IB_WC_RECV; - wc.vendor_err = 0; wc.qp = &qp->ibqp; wc.src_qp = qp->remote_qpn; - wc.pkey_index = 0; wc.slid = qp->remote_ah_attr.dlid; wc.sl = qp->remote_ah_attr.sl; - wc.dlid_path_bits = 0; - wc.port_num = 0; /* Signal completion event if the solicited bit is set. */ ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, (ohdr->bth[0] & @@ -488,8 +507,8 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, dev->n_pkt_drops++; goto done; } - if (qp->r_reuse_sge) - qp->r_reuse_sge = 0; + if (qp->r_flags & IPATH_R_REUSE_SGE) + qp->r_flags &= ~IPATH_R_REUSE_SGE; else if (!ipath_get_rwqe(qp, 1)) { dev->n_pkt_drops++; goto done; diff --git a/drivers/infiniband/hw/ipath/ipath_ud.c b/drivers/infiniband/hw/ipath/ipath_ud.c index 8b6a261c89e328de7f9c4a230aa528d5e980eff0..77ca8ca74e788a064ab9471d0704083bc802251a 100644 --- a/drivers/infiniband/hw/ipath/ipath_ud.c +++ b/drivers/infiniband/hw/ipath/ipath_ud.c @@ -65,9 +65,9 @@ static void ipath_ud_loopback(struct ipath_qp *sqp, struct ipath_swqe *swqe) u32 length; qp = ipath_lookup_qpn(&dev->qp_table, swqe->wr.wr.ud.remote_qpn); - if (!qp) { + if (!qp || !(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_RECV_OK)) { dev->n_pkt_drops++; - goto send_comp; + goto done; } rsge.sg_list = NULL; @@ -91,14 +91,12 @@ static void ipath_ud_loopback(struct ipath_qp *sqp, struct ipath_swqe *swqe) * present on the wire. */ length = swqe->length; + memset(&wc, 0, sizeof wc); wc.byte_len = length + sizeof(struct ib_grh); if (swqe->wr.opcode == IB_WR_SEND_WITH_IMM) { wc.wc_flags = IB_WC_WITH_IMM; wc.imm_data = swqe->wr.ex.imm_data; - } else { - wc.wc_flags = 0; - wc.imm_data = 0; } /* @@ -229,7 +227,6 @@ static void ipath_ud_loopback(struct ipath_qp *sqp, struct ipath_swqe *swqe) } wc.status = IB_WC_SUCCESS; wc.opcode = IB_WC_RECV; - wc.vendor_err = 0; wc.qp = &qp->ibqp; wc.src_qp = sqp->ibqp.qp_num; /* XXX do we know which pkey matched? Only needed for GSI. */ @@ -248,8 +245,7 @@ drop: kfree(rsge.sg_list); if (atomic_dec_and_test(&qp->refcount)) wake_up(&qp->wait); -send_comp: - ipath_send_complete(sqp, swqe, IB_WC_SUCCESS); +done:; } /** @@ -264,6 +260,7 @@ int ipath_make_ud_req(struct ipath_qp *qp) struct ipath_other_headers *ohdr; struct ib_ah_attr *ah_attr; struct ipath_swqe *wqe; + unsigned long flags; u32 nwords; u32 extra_bytes; u32 bth0; @@ -271,13 +268,30 @@ int ipath_make_ud_req(struct ipath_qp *qp) u16 lid; int ret = 0; - if (unlikely(!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK))) - goto bail; + spin_lock_irqsave(&qp->s_lock, flags); + + if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_NEXT_SEND_OK)) { + if (!(ib_ipath_state_ops[qp->state] & IPATH_FLUSH_SEND)) + goto bail; + /* We are in the error state, flush the work request. */ + if (qp->s_last == qp->s_head) + goto bail; + /* If DMAs are in progress, we can't flush immediately. */ + if (atomic_read(&qp->s_dma_busy)) { + qp->s_flags |= IPATH_S_WAIT_DMA; + goto bail; + } + wqe = get_swqe_ptr(qp, qp->s_last); + ipath_send_complete(qp, wqe, IB_WC_WR_FLUSH_ERR); + goto done; + } if (qp->s_cur == qp->s_head) goto bail; wqe = get_swqe_ptr(qp, qp->s_cur); + if (++qp->s_cur >= qp->s_size) + qp->s_cur = 0; /* Construct the header. */ ah_attr = &to_iah(wqe->wr.wr.ud.ah)->attr; @@ -288,10 +302,23 @@ int ipath_make_ud_req(struct ipath_qp *qp) dev->n_unicast_xmit++; } else { dev->n_unicast_xmit++; - lid = ah_attr->dlid & - ~((1 << dev->dd->ipath_lmc) - 1); + lid = ah_attr->dlid & ~((1 << dev->dd->ipath_lmc) - 1); if (unlikely(lid == dev->dd->ipath_lid)) { + /* + * If DMAs are in progress, we can't generate + * a completion for the loopback packet since + * it would be out of order. + * XXX Instead of waiting, we could queue a + * zero length descriptor so we get a callback. + */ + if (atomic_read(&qp->s_dma_busy)) { + qp->s_flags |= IPATH_S_WAIT_DMA; + goto bail; + } + spin_unlock_irqrestore(&qp->s_lock, flags); ipath_ud_loopback(qp, wqe); + spin_lock_irqsave(&qp->s_lock, flags); + ipath_send_complete(qp, wqe, IB_WC_SUCCESS); goto done; } } @@ -368,11 +395,13 @@ int ipath_make_ud_req(struct ipath_qp *qp) ohdr->u.ud.deth[1] = cpu_to_be32(qp->ibqp.qp_num); done: - if (++qp->s_cur >= qp->s_size) - qp->s_cur = 0; ret = 1; + goto unlock; bail: + qp->s_flags &= ~IPATH_S_BUSY; +unlock: + spin_unlock_irqrestore(&qp->s_lock, flags); return ret; } @@ -506,8 +535,8 @@ void ipath_ud_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, /* * Get the next work request entry to find where to put the data. */ - if (qp->r_reuse_sge) - qp->r_reuse_sge = 0; + if (qp->r_flags & IPATH_R_REUSE_SGE) + qp->r_flags &= ~IPATH_R_REUSE_SGE; else if (!ipath_get_rwqe(qp, 0)) { /* * Count VL15 packets dropped due to no receive buffer. @@ -523,7 +552,7 @@ void ipath_ud_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, } /* Silently drop packets which are too big. */ if (wc.byte_len > qp->r_len) { - qp->r_reuse_sge = 1; + qp->r_flags |= IPATH_R_REUSE_SGE; dev->n_pkt_drops++; goto bail; } @@ -535,7 +564,8 @@ void ipath_ud_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, ipath_skip_sge(&qp->r_sge, sizeof(struct ib_grh)); ipath_copy_sge(&qp->r_sge, data, wc.byte_len - sizeof(struct ib_grh)); - qp->r_wrid_valid = 0; + if (!test_and_clear_bit(IPATH_R_WRID_VALID, &qp->r_aflags)) + goto bail; wc.wr_id = qp->r_wr_id; wc.status = IB_WC_SUCCESS; wc.opcode = IB_WC_RECV; diff --git a/drivers/infiniband/hw/ipath/ipath_user_sdma.h b/drivers/infiniband/hw/ipath/ipath_user_sdma.h index e70946c1428ccb9e0879277678d2dd8a3e2dfbbc..fc76316c4a582ee73fdbfa2758edcd89bb3082e9 100644 --- a/drivers/infiniband/hw/ipath/ipath_user_sdma.h +++ b/drivers/infiniband/hw/ipath/ipath_user_sdma.h @@ -45,8 +45,6 @@ int ipath_user_sdma_writev(struct ipath_devdata *dd, int ipath_user_sdma_make_progress(struct ipath_devdata *dd, struct ipath_user_sdma_queue *pq); -int ipath_user_sdma_pkt_sent(const struct ipath_user_sdma_queue *pq, - u32 counter); void ipath_user_sdma_queue_drain(struct ipath_devdata *dd, struct ipath_user_sdma_queue *pq); diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.c b/drivers/infiniband/hw/ipath/ipath_verbs.c index e63927cce5b52180563bb4d03ffe2a41537959dc..e0ec540042bfc8e098e3abd9e27e15549c834527 100644 --- a/drivers/infiniband/hw/ipath/ipath_verbs.c +++ b/drivers/infiniband/hw/ipath/ipath_verbs.c @@ -111,16 +111,24 @@ static unsigned int ib_ipath_disable_sma; module_param_named(disable_sma, ib_ipath_disable_sma, uint, S_IWUSR | S_IRUGO); MODULE_PARM_DESC(disable_sma, "Disable the SMA"); +/* + * Note that it is OK to post send work requests in the SQE and ERR + * states; ipath_do_send() will process them and generate error + * completions as per IB 1.2 C10-96. + */ const int ib_ipath_state_ops[IB_QPS_ERR + 1] = { [IB_QPS_RESET] = 0, [IB_QPS_INIT] = IPATH_POST_RECV_OK, [IB_QPS_RTR] = IPATH_POST_RECV_OK | IPATH_PROCESS_RECV_OK, [IB_QPS_RTS] = IPATH_POST_RECV_OK | IPATH_PROCESS_RECV_OK | - IPATH_POST_SEND_OK | IPATH_PROCESS_SEND_OK, + IPATH_POST_SEND_OK | IPATH_PROCESS_SEND_OK | + IPATH_PROCESS_NEXT_SEND_OK, [IB_QPS_SQD] = IPATH_POST_RECV_OK | IPATH_PROCESS_RECV_OK | - IPATH_POST_SEND_OK, - [IB_QPS_SQE] = IPATH_POST_RECV_OK | IPATH_PROCESS_RECV_OK, - [IB_QPS_ERR] = 0, + IPATH_POST_SEND_OK | IPATH_PROCESS_SEND_OK, + [IB_QPS_SQE] = IPATH_POST_RECV_OK | IPATH_PROCESS_RECV_OK | + IPATH_POST_SEND_OK | IPATH_FLUSH_SEND, + [IB_QPS_ERR] = IPATH_POST_RECV_OK | IPATH_FLUSH_RECV | + IPATH_POST_SEND_OK | IPATH_FLUSH_SEND, }; struct ipath_ucontext { @@ -230,18 +238,6 @@ void ipath_skip_sge(struct ipath_sge_state *ss, u32 length) } } -static void ipath_flush_wqe(struct ipath_qp *qp, struct ib_send_wr *wr) -{ - struct ib_wc wc; - - memset(&wc, 0, sizeof(wc)); - wc.wr_id = wr->wr_id; - wc.status = IB_WC_WR_FLUSH_ERR; - wc.opcode = ib_ipath_wc_opcode[wr->opcode]; - wc.qp = &qp->ibqp; - ipath_cq_enter(to_icq(qp->ibqp.send_cq), &wc, 1); -} - /* * Count the number of DMA descriptors needed to send length bytes of data. * Don't modify the ipath_sge_state to get the count. @@ -347,14 +343,8 @@ static int ipath_post_one_send(struct ipath_qp *qp, struct ib_send_wr *wr) spin_lock_irqsave(&qp->s_lock, flags); /* Check that state is OK to post send. */ - if (unlikely(!(ib_ipath_state_ops[qp->state] & IPATH_POST_SEND_OK))) { - if (qp->state != IB_QPS_SQE && qp->state != IB_QPS_ERR) - goto bail_inval; - /* C10-96 says generate a flushed completion entry. */ - ipath_flush_wqe(qp, wr); - ret = 0; - goto bail; - } + if (unlikely(!(ib_ipath_state_ops[qp->state] & IPATH_POST_SEND_OK))) + goto bail_inval; /* IB spec says that num_sge == 0 is OK. */ if (wr->num_sge > qp->s_max_sge) @@ -396,7 +386,6 @@ static int ipath_post_one_send(struct ipath_qp *qp, struct ib_send_wr *wr) wqe = get_swqe_ptr(qp, qp->s_head); wqe->wr = *wr; - wqe->ssn = qp->s_ssn++; wqe->length = 0; if (wr->num_sge) { acc = wr->opcode >= IB_WR_RDMA_READ ? @@ -422,6 +411,7 @@ static int ipath_post_one_send(struct ipath_qp *qp, struct ib_send_wr *wr) goto bail_inval; } else if (wqe->length > to_idev(qp->ibqp.device)->dd->ipath_ibmtu) goto bail_inval; + wqe->ssn = qp->s_ssn++; qp->s_head = next; ret = 0; @@ -677,6 +667,7 @@ bail:; static void ipath_ib_timer(struct ipath_ibdev *dev) { struct ipath_qp *resend = NULL; + struct ipath_qp *rnr = NULL; struct list_head *last; struct ipath_qp *qp; unsigned long flags; @@ -703,7 +694,9 @@ static void ipath_ib_timer(struct ipath_ibdev *dev) if (--qp->s_rnr_timeout == 0) { do { list_del_init(&qp->timerwait); - tasklet_hi_schedule(&qp->s_task); + qp->timer_next = rnr; + rnr = qp; + atomic_inc(&qp->refcount); if (list_empty(last)) break; qp = list_entry(last->next, struct ipath_qp, @@ -743,16 +736,31 @@ static void ipath_ib_timer(struct ipath_ibdev *dev) spin_unlock_irqrestore(&dev->pending_lock, flags); /* XXX What if timer fires again while this is running? */ - for (qp = resend; qp != NULL; qp = qp->timer_next) { - struct ib_wc wc; + while (resend != NULL) { + qp = resend; + resend = qp->timer_next; spin_lock_irqsave(&qp->s_lock, flags); - if (qp->s_last != qp->s_tail && qp->state == IB_QPS_RTS) { + if (qp->s_last != qp->s_tail && + ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK) { dev->n_timeouts++; - ipath_restart_rc(qp, qp->s_last_psn + 1, &wc); + ipath_restart_rc(qp, qp->s_last_psn + 1); } spin_unlock_irqrestore(&qp->s_lock, flags); + /* Notify ipath_destroy_qp() if it is waiting. */ + if (atomic_dec_and_test(&qp->refcount)) + wake_up(&qp->wait); + } + while (rnr != NULL) { + qp = rnr; + rnr = qp->timer_next; + + spin_lock_irqsave(&qp->s_lock, flags); + if (ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK) + ipath_schedule_send(qp); + spin_unlock_irqrestore(&qp->s_lock, flags); + /* Notify ipath_destroy_qp() if it is waiting. */ if (atomic_dec_and_test(&qp->refcount)) wake_up(&qp->wait); @@ -1012,13 +1020,24 @@ static void sdma_complete(void *cookie, int status) struct ipath_verbs_txreq *tx = cookie; struct ipath_qp *qp = tx->qp; struct ipath_ibdev *dev = to_idev(qp->ibqp.device); + unsigned int flags; + enum ib_wc_status ibs = status == IPATH_SDMA_TXREQ_S_OK ? + IB_WC_SUCCESS : IB_WC_WR_FLUSH_ERR; - /* Generate a completion queue entry if needed */ - if (qp->ibqp.qp_type != IB_QPT_RC && tx->wqe) { - enum ib_wc_status ibs = status == IPATH_SDMA_TXREQ_S_OK ? - IB_WC_SUCCESS : IB_WC_WR_FLUSH_ERR; - + if (atomic_dec_and_test(&qp->s_dma_busy)) { + spin_lock_irqsave(&qp->s_lock, flags); + if (tx->wqe) + ipath_send_complete(qp, tx->wqe, ibs); + if ((ib_ipath_state_ops[qp->state] & IPATH_FLUSH_SEND && + qp->s_last != qp->s_head) || + (qp->s_flags & IPATH_S_WAIT_DMA)) + ipath_schedule_send(qp); + spin_unlock_irqrestore(&qp->s_lock, flags); + wake_up(&qp->wait_dma); + } else if (tx->wqe) { + spin_lock_irqsave(&qp->s_lock, flags); ipath_send_complete(qp, tx->wqe, ibs); + spin_unlock_irqrestore(&qp->s_lock, flags); } if (tx->txreq.flags & IPATH_SDMA_TXREQ_F_FREEBUF) @@ -1029,6 +1048,21 @@ static void sdma_complete(void *cookie, int status) wake_up(&qp->wait); } +static void decrement_dma_busy(struct ipath_qp *qp) +{ + unsigned int flags; + + if (atomic_dec_and_test(&qp->s_dma_busy)) { + spin_lock_irqsave(&qp->s_lock, flags); + if ((ib_ipath_state_ops[qp->state] & IPATH_FLUSH_SEND && + qp->s_last != qp->s_head) || + (qp->s_flags & IPATH_S_WAIT_DMA)) + ipath_schedule_send(qp); + spin_unlock_irqrestore(&qp->s_lock, flags); + wake_up(&qp->wait_dma); + } +} + /* * Compute the number of clock cycles of delay before sending the next packet. * The multipliers reflect the number of clocks for the fastest rate so @@ -1067,9 +1101,12 @@ static int ipath_verbs_send_dma(struct ipath_qp *qp, if (tx) { qp->s_tx = NULL; /* resend previously constructed packet */ + atomic_inc(&qp->s_dma_busy); ret = ipath_sdma_verbs_send(dd, tx->ss, tx->len, tx); - if (ret) + if (ret) { qp->s_tx = tx; + decrement_dma_busy(qp); + } goto bail; } @@ -1120,12 +1157,14 @@ static int ipath_verbs_send_dma(struct ipath_qp *qp, tx->txreq.sg_count = ndesc; tx->map_len = (hdrwords + 2) << 2; tx->txreq.map_addr = &tx->hdr; + atomic_inc(&qp->s_dma_busy); ret = ipath_sdma_verbs_send(dd, ss, dwords, tx); if (ret) { /* save ss and length in dwords */ tx->ss = ss; tx->len = dwords; qp->s_tx = tx; + decrement_dma_busy(qp); } goto bail; } @@ -1146,6 +1185,7 @@ static int ipath_verbs_send_dma(struct ipath_qp *qp, memcpy(piobuf, hdr, hdrwords << 2); ipath_copy_from_sge(piobuf + hdrwords, ss, len); + atomic_inc(&qp->s_dma_busy); ret = ipath_sdma_verbs_send(dd, NULL, 0, tx); /* * If we couldn't queue the DMA request, save the info @@ -1156,6 +1196,7 @@ static int ipath_verbs_send_dma(struct ipath_qp *qp, tx->ss = NULL; tx->len = 0; qp->s_tx = tx; + decrement_dma_busy(qp); } dev->n_unaligned++; goto bail; @@ -1179,6 +1220,7 @@ static int ipath_verbs_send_pio(struct ipath_qp *qp, unsigned flush_wc; u32 control; int ret; + unsigned int flags; piobuf = ipath_getpiobuf(dd, plen, NULL); if (unlikely(piobuf == NULL)) { @@ -1249,8 +1291,11 @@ static int ipath_verbs_send_pio(struct ipath_qp *qp, } copy_io(piobuf, ss, len, flush_wc); done: - if (qp->s_wqe) + if (qp->s_wqe) { + spin_lock_irqsave(&qp->s_lock, flags); ipath_send_complete(qp, qp->s_wqe, IB_WC_SUCCESS); + spin_unlock_irqrestore(&qp->s_lock, flags); + } ret = 0; bail: return ret; @@ -1283,19 +1328,12 @@ int ipath_verbs_send(struct ipath_qp *qp, struct ipath_ib_header *hdr, * can defer SDMA restart until link goes ACTIVE without * worrying about just how we got there. */ - if (qp->ibqp.qp_type == IB_QPT_SMI) + if (qp->ibqp.qp_type == IB_QPT_SMI || + !(dd->ipath_flags & IPATH_HAS_SEND_DMA)) ret = ipath_verbs_send_pio(qp, hdr, hdrwords, ss, len, plen, dwords); - /* All non-VL15 packets are dropped if link is not ACTIVE */ - else if (!(dd->ipath_flags & IPATH_LINKACTIVE)) { - if (qp->s_wqe) - ipath_send_complete(qp, qp->s_wqe, IB_WC_SUCCESS); - ret = 0; - } else if (dd->ipath_flags & IPATH_HAS_SEND_DMA) - ret = ipath_verbs_send_dma(qp, hdr, hdrwords, ss, len, - plen, dwords); else - ret = ipath_verbs_send_pio(qp, hdr, hdrwords, ss, len, + ret = ipath_verbs_send_dma(qp, hdr, hdrwords, ss, len, plen, dwords); return ret; @@ -1403,27 +1441,46 @@ bail: * This is called from ipath_intr() at interrupt level when a PIO buffer is * available after ipath_verbs_send() returned an error that no buffers were * available. Return 1 if we consumed all the PIO buffers and we still have - * QPs waiting for buffers (for now, just do a tasklet_hi_schedule and + * QPs waiting for buffers (for now, just restart the send tasklet and * return zero). */ int ipath_ib_piobufavail(struct ipath_ibdev *dev) { + struct list_head *list; + struct ipath_qp *qplist; struct ipath_qp *qp; unsigned long flags; if (dev == NULL) goto bail; + list = &dev->piowait; + qplist = NULL; + spin_lock_irqsave(&dev->pending_lock, flags); - while (!list_empty(&dev->piowait)) { - qp = list_entry(dev->piowait.next, struct ipath_qp, - piowait); + while (!list_empty(list)) { + qp = list_entry(list->next, struct ipath_qp, piowait); list_del_init(&qp->piowait); - clear_bit(IPATH_S_BUSY, &qp->s_busy); - tasklet_hi_schedule(&qp->s_task); + qp->pio_next = qplist; + qplist = qp; + atomic_inc(&qp->refcount); } spin_unlock_irqrestore(&dev->pending_lock, flags); + while (qplist != NULL) { + qp = qplist; + qplist = qp->pio_next; + + spin_lock_irqsave(&qp->s_lock, flags); + if (ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK) + ipath_schedule_send(qp); + spin_unlock_irqrestore(&qp->s_lock, flags); + + /* Notify ipath_destroy_qp() if it is waiting. */ + if (atomic_dec_and_test(&qp->refcount)) + wake_up(&qp->wait); + } + bail: return 0; } @@ -2145,11 +2202,12 @@ bail: void ipath_unregister_ib_device(struct ipath_ibdev *dev) { struct ib_device *ibdev = &dev->ibdev; - - disable_timer(dev->dd); + u32 qps_inuse; ib_unregister_device(ibdev); + disable_timer(dev->dd); + if (!list_empty(&dev->pending[0]) || !list_empty(&dev->pending[1]) || !list_empty(&dev->pending[2])) @@ -2164,7 +2222,10 @@ void ipath_unregister_ib_device(struct ipath_ibdev *dev) * Note that ipath_unregister_ib_device() can be called before all * the QPs are destroyed! */ - ipath_free_all_qps(&dev->qp_table); + qps_inuse = ipath_free_all_qps(&dev->qp_table); + if (qps_inuse) + ipath_dev_err(dev->dd, "QP memory leak! %u still in use\n", + qps_inuse); kfree(dev->qp_table.table); kfree(dev->lk_table.table); kfree(dev->txreq_bufs); @@ -2215,17 +2276,14 @@ static ssize_t show_stats(struct device *device, struct device_attribute *attr, "RC OTH NAKs %d\n" "RC timeouts %d\n" "RC RDMA dup %d\n" - "RC stalls %d\n" "piobuf wait %d\n" - "no piobuf %d\n" "unaligned %d\n" "PKT drops %d\n" "WQE errs %d\n", dev->n_rc_resends, dev->n_rc_qacks, dev->n_rc_acks, dev->n_seq_naks, dev->n_rdma_seq, dev->n_rnr_naks, dev->n_other_naks, dev->n_timeouts, - dev->n_rdma_dup_busy, dev->n_rc_stalls, dev->n_piowait, - dev->n_no_piobuf, dev->n_unaligned, + dev->n_rdma_dup_busy, dev->n_piowait, dev->n_unaligned, dev->n_pkt_drops, dev->n_wqe_errs); for (i = 0; i < ARRAY_SIZE(dev->opstats); i++) { const struct ipath_opcode_stats *si = &dev->opstats[i]; diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.h b/drivers/infiniband/hw/ipath/ipath_verbs.h index 6514aa8306cd570a9a1d2ba7fc5eb13ea14fcd3a..9d12ae8a778eba131e5936e9e37e22a3390bfe10 100644 --- a/drivers/infiniband/hw/ipath/ipath_verbs.h +++ b/drivers/infiniband/hw/ipath/ipath_verbs.h @@ -74,6 +74,11 @@ #define IPATH_POST_RECV_OK 0x02 #define IPATH_PROCESS_RECV_OK 0x04 #define IPATH_PROCESS_SEND_OK 0x08 +#define IPATH_PROCESS_NEXT_SEND_OK 0x10 +#define IPATH_FLUSH_SEND 0x20 +#define IPATH_FLUSH_RECV 0x40 +#define IPATH_PROCESS_OR_FLUSH_SEND \ + (IPATH_PROCESS_SEND_OK | IPATH_FLUSH_SEND) /* IB Performance Manager status values */ #define IB_PMA_SAMPLE_STATUS_DONE 0x00 @@ -353,12 +358,14 @@ struct ipath_qp { struct ib_qp ibqp; struct ipath_qp *next; /* link list for QPN hash table */ struct ipath_qp *timer_next; /* link list for ipath_ib_timer() */ + struct ipath_qp *pio_next; /* link for ipath_ib_piobufavail() */ struct list_head piowait; /* link for wait PIO buf */ struct list_head timerwait; /* link for waiting for timeouts */ struct ib_ah_attr remote_ah_attr; struct ipath_ib_header s_hdr; /* next packet header to send */ atomic_t refcount; wait_queue_head_t wait; + wait_queue_head_t wait_dma; struct tasklet_struct s_task; struct ipath_mmap_info *ip; struct ipath_sge_state *s_cur_sge; @@ -369,7 +376,7 @@ struct ipath_qp { struct ipath_sge_state s_rdma_read_sge; struct ipath_sge_state r_sge; /* current receive data */ spinlock_t s_lock; - unsigned long s_busy; + atomic_t s_dma_busy; u16 s_pkt_delay; u16 s_hdrwords; /* size of s_hdr in 32 bit words */ u32 s_cur_size; /* size of send packet in bytes */ @@ -383,6 +390,7 @@ struct ipath_qp { u32 s_rnr_timeout; /* number of milliseconds for RNR timeout */ u32 r_ack_psn; /* PSN for next ACK or atomic ACK */ u64 r_wr_id; /* ID for current receive WQE */ + unsigned long r_aflags; u32 r_len; /* total length of r_sge */ u32 r_rcv_len; /* receive data len processed */ u32 r_psn; /* expected rcv packet sequence number */ @@ -394,8 +402,7 @@ struct ipath_qp { u8 r_state; /* opcode of last packet received */ u8 r_nak_state; /* non-zero if NAK is pending */ u8 r_min_rnr_timer; /* retry timeout value for RNR NAKs */ - u8 r_reuse_sge; /* for UC receive errors */ - u8 r_wrid_valid; /* r_wrid set but CQ entry not yet made */ + u8 r_flags; u8 r_max_rd_atomic; /* max number of RDMA read/atomic to receive */ u8 r_head_ack_queue; /* index into s_ack_queue[] */ u8 qp_access_flags; @@ -404,13 +411,13 @@ struct ipath_qp { u8 s_rnr_retry_cnt; u8 s_retry; /* requester retry counter */ u8 s_rnr_retry; /* requester RNR retry counter */ - u8 s_wait_credit; /* limit number of unacked packets sent */ u8 s_pkey_index; /* PKEY index to use */ u8 s_max_rd_atomic; /* max number of RDMA read/atomic to send */ u8 s_num_rd_atomic; /* number of RDMA read/atomic pending */ u8 s_tail_ack_queue; /* index into s_ack_queue[] */ u8 s_flags; u8 s_dmult; + u8 s_draining; u8 timeout; /* Timeout for this QP */ enum ib_mtu path_mtu; u32 remote_qpn; @@ -428,16 +435,40 @@ struct ipath_qp { struct ipath_sge r_sg_list[0]; /* verified SGEs */ }; -/* Bit definition for s_busy. */ -#define IPATH_S_BUSY 0 +/* + * Atomic bit definitions for r_aflags. + */ +#define IPATH_R_WRID_VALID 0 + +/* + * Bit definitions for r_flags. + */ +#define IPATH_R_REUSE_SGE 0x01 +#define IPATH_R_RDMAR_SEQ 0x02 /* * Bit definitions for s_flags. + * + * IPATH_S_FENCE_PENDING - waiting for all prior RDMA read or atomic SWQEs + * before processing the next SWQE + * IPATH_S_RDMAR_PENDING - waiting for any RDMA read or atomic SWQEs + * before processing the next SWQE + * IPATH_S_WAITING - waiting for RNR timeout or send buffer available. + * IPATH_S_WAIT_SSN_CREDIT - waiting for RC credits to process next SWQE + * IPATH_S_WAIT_DMA - waiting for send DMA queue to drain before generating + * next send completion entry not via send DMA. */ #define IPATH_S_SIGNAL_REQ_WR 0x01 #define IPATH_S_FENCE_PENDING 0x02 #define IPATH_S_RDMAR_PENDING 0x04 #define IPATH_S_ACK_PENDING 0x08 +#define IPATH_S_BUSY 0x10 +#define IPATH_S_WAITING 0x20 +#define IPATH_S_WAIT_SSN_CREDIT 0x40 +#define IPATH_S_WAIT_DMA 0x80 + +#define IPATH_S_ANY_WAIT (IPATH_S_FENCE_PENDING | IPATH_S_RDMAR_PENDING | \ + IPATH_S_WAITING | IPATH_S_WAIT_SSN_CREDIT | IPATH_S_WAIT_DMA) #define IPATH_PSN_CREDIT 512 @@ -573,13 +604,11 @@ struct ipath_ibdev { u32 n_rnr_naks; u32 n_other_naks; u32 n_timeouts; - u32 n_rc_stalls; u32 n_pkt_drops; u32 n_vl15_dropped; u32 n_wqe_errs; u32 n_rdma_dup_busy; u32 n_piowait; - u32 n_no_piobuf; u32 n_unaligned; u32 port_cap_flags; u32 pma_sample_start; @@ -657,6 +686,17 @@ static inline struct ipath_ibdev *to_idev(struct ib_device *ibdev) return container_of(ibdev, struct ipath_ibdev, ibdev); } +/* + * This must be called with s_lock held. + */ +static inline void ipath_schedule_send(struct ipath_qp *qp) +{ + if (qp->s_flags & IPATH_S_ANY_WAIT) + qp->s_flags &= ~IPATH_S_ANY_WAIT; + if (!(qp->s_flags & IPATH_S_BUSY)) + tasklet_hi_schedule(&qp->s_task); +} + int ipath_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num, @@ -706,12 +746,10 @@ int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int ipath_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask, struct ib_qp_init_attr *init_attr); -void ipath_free_all_qps(struct ipath_qp_table *qpt); +unsigned ipath_free_all_qps(struct ipath_qp_table *qpt); int ipath_init_qp_table(struct ipath_ibdev *idev, int size); -void ipath_sqerror_qp(struct ipath_qp *qp, struct ib_wc *wc); - void ipath_get_credit(struct ipath_qp *qp, u32 aeth); unsigned ipath_ib_rate_to_mult(enum ib_rate rate); @@ -729,7 +767,9 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, int has_grh, void *data, u32 tlen, struct ipath_qp *qp); -void ipath_restart_rc(struct ipath_qp *qp, u32 psn, struct ib_wc *wc); +void ipath_restart_rc(struct ipath_qp *qp, u32 psn); + +void ipath_rc_error(struct ipath_qp *qp, enum ib_wc_status err); int ipath_post_ud_send(struct ipath_qp *qp, struct ib_send_wr *wr); diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c index 9f7364a9096d3d5b5ab42d07ee39ab4617f188cf..a4e9269a29bd106b604d1c8012efc25b4f1ab9c9 100644 --- a/drivers/infiniband/hw/nes/nes.c +++ b/drivers/infiniband/hw/nes/nes.c @@ -91,10 +91,6 @@ unsigned int nes_debug_level = 0; module_param_named(debug_level, nes_debug_level, uint, 0644); MODULE_PARM_DESC(debug_level, "Enable debug output level"); -unsigned int nes_lro_max_aggr = NES_LRO_MAX_AGGR; -module_param(nes_lro_max_aggr, int, NES_LRO_MAX_AGGR); -MODULE_PARM_DESC(nes_mro_max_aggr, " nic LRO MAX packet aggregation"); - LIST_HEAD(nes_adapter_list); static LIST_HEAD(nes_dev_list); diff --git a/drivers/infiniband/hw/nes/nes.h b/drivers/infiniband/hw/nes/nes.h index 1f9f7bf73862a44d1cf0a4a2ac7d1e5099ef70bf..61b46e9c7d2d5ed079acad11ec9ec3f836263280 100644 --- a/drivers/infiniband/hw/nes/nes.h +++ b/drivers/infiniband/hw/nes/nes.h @@ -173,7 +173,6 @@ extern int disable_mpa_crc; extern unsigned int send_first; extern unsigned int nes_drv_opt; extern unsigned int nes_debug_level; -extern unsigned int nes_lro_max_aggr; extern struct list_head nes_adapter_list; diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c index 8dc70f9bad2f49f828b95dca4544ec46c1aa95b2..d3278f111ca7dcba33bf5b12de3c01d337309122 100644 --- a/drivers/infiniband/hw/nes/nes_hw.c +++ b/drivers/infiniband/hw/nes/nes_hw.c @@ -42,6 +42,10 @@ #include "nes.h" +static unsigned int nes_lro_max_aggr = NES_LRO_MAX_AGGR; +module_param(nes_lro_max_aggr, uint, 0444); +MODULE_PARM_DESC(nes_lro_max_aggr, "NIC LRO max packet aggregation"); + static u32 crit_err_count; u32 int_mod_timer_init; u32 int_mod_cq_depth_256; @@ -1738,7 +1742,7 @@ int nes_init_nic_qp(struct nes_device *nesdev, struct net_device *netdev) jumbomode = 1; nes_nic_init_timer_defaults(nesdev, jumbomode); } - nesvnic->lro_mgr.max_aggr = NES_LRO_MAX_AGGR; + nesvnic->lro_mgr.max_aggr = nes_lro_max_aggr; nesvnic->lro_mgr.max_desc = NES_MAX_LRO_DESCRIPTORS; nesvnic->lro_mgr.lro_arr = nesvnic->lro_desc; nesvnic->lro_mgr.get_skb_header = nes_lro_get_skb_hdr; diff --git a/drivers/input/keyboard/hilkbd.c b/drivers/input/keyboard/hilkbd.c index 50d80ecf0b80915ee81d2ab5c59b01be9cb1c4b7..aacf71f3cd44b0557af0af0549a4fee2e81dfdf3 100644 --- a/drivers/input/keyboard/hilkbd.c +++ b/drivers/input/keyboard/hilkbd.c @@ -217,6 +217,10 @@ hil_keyb_init(void) return -ENOMEM; #if defined(CONFIG_HP300) + if (!MACH_IS_HP300) { + err = -ENODEV; + goto err1; + } if (!hwreg_present((void *)(HILBASE + HIL_DATA))) { printk(KERN_ERR "HIL: hardware register was not found\n"); err = -ENODEV; diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 92b683411d5ab293cf27d34c0a9c07e1fafa2cf5..3ad8bd9f75436efd29fd3054a79e89a668219b4a 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -14,7 +14,7 @@ if INPUT_MISC config INPUT_PCSPKR tristate "PC Speaker support" - depends on ALPHA || X86 || MIPS || PPC_PREP || PPC_CHRP || PPC_PSERIES + depends on PCSPKR_PLATFORM depends on SND_PCSP=n help Say Y here if you want the standard PC Speaker to be used for diff --git a/drivers/input/misc/hp_sdc_rtc.c b/drivers/input/misc/hp_sdc_rtc.c index ab76ea442fa56140a89d58df87cc934e1073ab2f..45e5d05b01dee4cfd674bf9beae2c5b55cf48808 100644 --- a/drivers/input/misc/hp_sdc_rtc.c +++ b/drivers/input/misc/hp_sdc_rtc.c @@ -691,6 +691,11 @@ static int __init hp_sdc_rtc_init(void) { int ret; +#ifdef __mc68000__ + if (!MACH_IS_HP300) + return -ENODEV; +#endif + init_MUTEX(&i8042tregs); if ((ret = hp_sdc_request_timer_irq(&hp_sdc_rtc_isr))) diff --git a/drivers/input/serio/hp_sdc_mlc.c b/drivers/input/serio/hp_sdc_mlc.c index f1fd3b638a379edecc0fb70a2d575498d2f09b64..587398f5c9df30efd0a5735056ec0eac2eb7b227 100644 --- a/drivers/input/serio/hp_sdc_mlc.c +++ b/drivers/input/serio/hp_sdc_mlc.c @@ -306,6 +306,11 @@ static int __init hp_sdc_mlc_init(void) { hil_mlc *mlc = &hp_sdc_mlc; +#ifdef __mc68000__ + if (!MACH_IS_HP300) + return -ENODEV; +#endif + printk(KERN_INFO PREFIX "Registering the System Domain Controller's HIL MLC.\n"); hp_sdc_mlc_priv.emtestmode = 0; diff --git a/drivers/input/serio/i8042-io.h b/drivers/input/serio/i8042-io.h index 3b4e13b9ce1b9ac7317335c49f7b5bed8f854524..f451c7351a9da1b0614e1e04412f65e07116a37c 100644 --- a/drivers/input/serio/i8042-io.h +++ b/drivers/input/serio/i8042-io.h @@ -25,7 +25,7 @@ #elif defined(__arm__) /* defined in include/asm-arm/arch-xxx/irqs.h */ #include -#elif defined(CONFIG_SUPERH64) +#elif defined(CONFIG_SH_CAYMAN) #include #else # define I8042_KBD_IRQ 1 diff --git a/drivers/input/serio/q40kbd.c b/drivers/input/serio/q40kbd.c index cb89aff2e1603c30711a7900a6bbbb39b5fd83e6..d962a8d78b144fc7ac3f17af6107d111f4fb31aa 100644 --- a/drivers/input/serio/q40kbd.c +++ b/drivers/input/serio/q40kbd.c @@ -156,7 +156,7 @@ static int __init q40kbd_init(void) int error; if (!MACH_IS_Q40) - return -EIO; + return -ENODEV; error = platform_driver_register(&q40kbd_driver); if (error) diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c index b8b9e44f7f4ee9e478ebe07f45ae58ac6ae9a24b..dbaad39020a1bc75b5ef48bc3c837d9c45431c2b 100644 --- a/drivers/macintosh/adb.c +++ b/drivers/macintosh/adb.c @@ -334,7 +334,7 @@ int __init adb_init(void) return 0; } -__initcall(adb_init); +device_initcall(adb_init); static int do_adb_reset_bus(void) diff --git a/drivers/md/linear.c b/drivers/md/linear.c index 0b8511776b3e75276e9a472ea759e0aa304fff48..10748240cb2fde2bd8942dbb19e300cc6c32961c 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c @@ -250,6 +250,7 @@ static int linear_run (mddev_t *mddev) { linear_conf_t *conf; + mddev->queue->queue_lock = &mddev->queue->__queue_lock; conf = linear_conf(mddev, mddev->raid_disks); if (!conf) diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index 42ee1a2dc144fc88954c45a3509903633f00028e..4f4d1f383842c9ca41cb3e89e914cdace48e60c1 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c @@ -417,6 +417,7 @@ static int multipath_run (mddev_t *mddev) * bookkeeping area. [whatever we allocate in multipath_run(), * should be freed in multipath_stop()] */ + mddev->queue->queue_lock = &mddev->queue->__queue_lock; conf = kzalloc(sizeof(multipath_conf_t), GFP_KERNEL); mddev->private = conf; diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index 818b4828409667d5a40b53efb734575dd00ee3a2..914c04ddec7c64690cdb24a4b77c83172d4d38ab 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -280,6 +280,7 @@ static int raid0_run (mddev_t *mddev) (mddev->chunk_size>>1)-1); blk_queue_max_sectors(mddev->queue, mddev->chunk_size >> 9); blk_queue_segment_boundary(mddev->queue, (mddev->chunk_size>>1) - 1); + mddev->queue->queue_lock = &mddev->queue->__queue_lock; conf = kmalloc(sizeof (raid0_conf_t), GFP_KERNEL); if (!conf) diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 6778b7cb39bd5dd94eb719683267a6bef926e3cf..ac409b7d83f59fff5ec116fe59bfd125e50d8612 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1935,6 +1935,9 @@ static int run(mddev_t *mddev) if (!conf->r1bio_pool) goto out_no_mem; + spin_lock_init(&conf->device_lock); + mddev->queue->queue_lock = &conf->device_lock; + rdev_for_each(rdev, tmp, mddev) { disk_idx = rdev->raid_disk; if (disk_idx >= mddev->raid_disks @@ -1958,7 +1961,6 @@ static int run(mddev_t *mddev) } conf->raid_disks = mddev->raid_disks; conf->mddev = mddev; - spin_lock_init(&conf->device_lock); INIT_LIST_HEAD(&conf->retry_list); spin_lock_init(&conf->resync_lock); diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 5938fa9629221145e6b4249d4996ca6c67e08516..8536ede1e7129c37fc30303e15577c383e68569c 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -886,7 +886,7 @@ static int make_request(struct request_queue *q, struct bio * bio) */ raid10_find_phys(conf, r10_bio); retry_write: - blocked_rdev = 0; + blocked_rdev = NULL; rcu_read_lock(); for (i = 0; i < conf->copies; i++) { int d = r10_bio->devs[i].devnum; @@ -2082,6 +2082,9 @@ static int run(mddev_t *mddev) goto out_free_conf; } + spin_lock_init(&conf->device_lock); + mddev->queue->queue_lock = &conf->device_lock; + rdev_for_each(rdev, tmp, mddev) { disk_idx = rdev->raid_disk; if (disk_idx >= mddev->raid_disks @@ -2103,7 +2106,6 @@ static int run(mddev_t *mddev) disk->head_position = 0; } - spin_lock_init(&conf->device_lock); INIT_LIST_HEAD(&conf->retry_list); spin_lock_init(&conf->resync_lock); diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 087eee0cb80913fabc692187eed59e981c5eb95e..93fde48c0f42e52cbedad8be994d00362e6198b6 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -2369,8 +2369,8 @@ static void handle_parity_checks5(raid5_conf_t *conf, struct stripe_head *sh, /* complete a check operation */ if (test_and_clear_bit(STRIPE_OP_CHECK, &sh->ops.complete)) { - clear_bit(STRIPE_OP_CHECK, &sh->ops.ack); - clear_bit(STRIPE_OP_CHECK, &sh->ops.pending); + clear_bit(STRIPE_OP_CHECK, &sh->ops.ack); + clear_bit(STRIPE_OP_CHECK, &sh->ops.pending); if (s->failed == 0) { if (sh->ops.zero_sum_result == 0) /* parity is correct (on disc, @@ -2400,16 +2400,6 @@ static void handle_parity_checks5(raid5_conf_t *conf, struct stripe_head *sh, canceled_check = 1; /* STRIPE_INSYNC is not set */ } - /* check if we can clear a parity disk reconstruct */ - if (test_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.complete) && - test_bit(STRIPE_OP_MOD_REPAIR_PD, &sh->ops.pending)) { - - clear_bit(STRIPE_OP_MOD_REPAIR_PD, &sh->ops.pending); - clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.complete); - clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.ack); - clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending); - } - /* start a new check operation if there are no failures, the stripe is * not insync, and a repair is not in flight */ @@ -2424,6 +2414,17 @@ static void handle_parity_checks5(raid5_conf_t *conf, struct stripe_head *sh, } } + /* check if we can clear a parity disk reconstruct */ + if (test_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.complete) && + test_bit(STRIPE_OP_MOD_REPAIR_PD, &sh->ops.pending)) { + + clear_bit(STRIPE_OP_MOD_REPAIR_PD, &sh->ops.pending); + clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.complete); + clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.ack); + clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending); + } + + /* Wait for check parity and compute block operations to complete * before write-back. If a failure occurred while the check operation * was in flight we need to cycle this stripe through handle_stripe @@ -4256,6 +4257,7 @@ static int run(mddev_t *mddev) goto abort; } spin_lock_init(&conf->device_lock); + mddev->queue->queue_lock = &conf->device_lock; init_waitqueue_head(&conf->wait_for_stripe); init_waitqueue_head(&conf->wait_for_overlap); INIT_LIST_HEAD(&conf->handle_list); diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig index ddf57e135c6c61633fa030dd623a67d5072491c0..7a7803b5d4976353b8a475a9eebf98a9e94da52a 100644 --- a/drivers/media/Kconfig +++ b/drivers/media/Kconfig @@ -89,8 +89,7 @@ config DVB_CORE config VIDEO_MEDIA tristate - default DVB_CORE || VIDEO_DEV - depends on DVB_CORE || VIDEO_DEV + default (DVB_CORE && (VIDEO_DEV = n)) || (VIDEO_DEV && (DVB_CORE = n)) || (DVB_CORE && VIDEO_DEV) comment "Multimedia drivers" diff --git a/drivers/media/Makefile b/drivers/media/Makefile index 73f742c7e818428f1965d880a3c442e71154a957..cc11c4c0e7e7afaf585e3866c0119a0601275164 100644 --- a/drivers/media/Makefile +++ b/drivers/media/Makefile @@ -2,6 +2,8 @@ # Makefile for the kernel multimedia device drivers. # +obj-y := common/ + obj-$(CONFIG_VIDEO_MEDIA) += common/ # Since hybrid devices are here, should be compiled if DVB and/or V4L diff --git a/drivers/media/common/tuners/Kconfig b/drivers/media/common/tuners/Kconfig index 5be85ff53e12bcb8ed17df65ea05434f406ce35c..d6206540476bcad9c1f63fed08a5dbc49722dc7d 100644 --- a/drivers/media/common/tuners/Kconfig +++ b/drivers/media/common/tuners/Kconfig @@ -1,6 +1,6 @@ config MEDIA_ATTACH bool "Load and attach frontend and tuner driver modules as needed" - depends on DVB_CORE + depends on VIDEO_MEDIA depends on MODULES help Remove the static dependency of DVB card drivers on all @@ -19,10 +19,10 @@ config MEDIA_ATTACH config MEDIA_TUNER tristate - default DVB_CORE || VIDEO_DEV - depends on DVB_CORE || VIDEO_DEV - select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE - select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMIZE + default VIDEO_MEDIA && I2C + depends on VIDEO_MEDIA && I2C + select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE && HOTPLUG + select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMIZE && HOTPLUG select MEDIA_TUNER_MT20XX if !MEDIA_TUNER_CUSTOMIZE select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMIZE select MEDIA_TUNER_TEA5761 if !MEDIA_TUNER_CUSTOMIZE @@ -46,7 +46,7 @@ if MEDIA_TUNER_CUSTOMIZE config MEDIA_TUNER_SIMPLE tristate "Simple tuner support" - depends on I2C + depends on VIDEO_MEDIA && I2C select MEDIA_TUNER_TDA9887 default m if MEDIA_TUNER_CUSTOMIZE help @@ -54,7 +54,7 @@ config MEDIA_TUNER_SIMPLE config MEDIA_TUNER_TDA8290 tristate "TDA 8290/8295 + 8275(a)/18271 tuner combo" - depends on I2C + depends on VIDEO_MEDIA && I2C select MEDIA_TUNER_TDA827X select MEDIA_TUNER_TDA18271 default m if MEDIA_TUNER_CUSTOMIZE @@ -63,21 +63,21 @@ config MEDIA_TUNER_TDA8290 config MEDIA_TUNER_TDA827X tristate "Philips TDA827X silicon tuner" - depends on DVB_CORE && I2C + depends on VIDEO_MEDIA && I2C default m if DVB_FE_CUSTOMISE help A DVB-T silicon tuner module. Say Y when you want to support this tuner. config MEDIA_TUNER_TDA18271 tristate "NXP TDA18271 silicon tuner" - depends on I2C + depends on VIDEO_MEDIA && I2C default m if DVB_FE_CUSTOMISE help A silicon tuner module. Say Y when you want to support this tuner. config MEDIA_TUNER_TDA9887 tristate "TDA 9885/6/7 analog IF demodulator" - depends on I2C + depends on VIDEO_MEDIA && I2C default m if MEDIA_TUNER_CUSTOMIZE help Say Y here to include support for Philips TDA9885/6/7 @@ -85,67 +85,79 @@ config MEDIA_TUNER_TDA9887 config MEDIA_TUNER_TEA5761 tristate "TEA 5761 radio tuner (EXPERIMENTAL)" - depends on I2C && EXPERIMENTAL + depends on VIDEO_MEDIA && I2C + depends on EXPERIMENTAL default m if MEDIA_TUNER_CUSTOMIZE help Say Y here to include support for the Philips TEA5761 radio tuner. config MEDIA_TUNER_TEA5767 tristate "TEA 5767 radio tuner" - depends on I2C + depends on VIDEO_MEDIA && I2C default m if MEDIA_TUNER_CUSTOMIZE help Say Y here to include support for the Philips TEA5767 radio tuner. config MEDIA_TUNER_MT20XX tristate "Microtune 2032 / 2050 tuners" - depends on I2C + depends on VIDEO_MEDIA && I2C default m if MEDIA_TUNER_CUSTOMIZE help Say Y here to include support for the MT2032 / MT2050 tuner. config MEDIA_TUNER_MT2060 tristate "Microtune MT2060 silicon IF tuner" - depends on I2C + depends on VIDEO_MEDIA && I2C default m if DVB_FE_CUSTOMISE help A driver for the silicon IF tuner MT2060 from Microtune. config MEDIA_TUNER_MT2266 tristate "Microtune MT2266 silicon tuner" - depends on I2C + depends on VIDEO_MEDIA && I2C default m if DVB_FE_CUSTOMISE help A driver for the silicon baseband tuner MT2266 from Microtune. config MEDIA_TUNER_MT2131 tristate "Microtune MT2131 silicon tuner" - depends on I2C + depends on VIDEO_MEDIA && I2C default m if DVB_FE_CUSTOMISE help A driver for the silicon baseband tuner MT2131 from Microtune. config MEDIA_TUNER_QT1010 tristate "Quantek QT1010 silicon tuner" - depends on DVB_CORE && I2C + depends on VIDEO_MEDIA && I2C default m if DVB_FE_CUSTOMISE help A driver for the silicon tuner QT1010 from Quantek. config MEDIA_TUNER_XC2028 tristate "XCeive xc2028/xc3028 tuners" - depends on I2C && FW_LOADER + depends on VIDEO_MEDIA && I2C + depends on HOTPLUG + select FW_LOADER default m if MEDIA_TUNER_CUSTOMIZE help Say Y here to include support for the xc2028/xc3028 tuners. config MEDIA_TUNER_XC5000 tristate "Xceive XC5000 silicon tuner" - depends on I2C + depends on VIDEO_MEDIA && I2C + depends on HOTPLUG + select FW_LOADER default m if DVB_FE_CUSTOMISE help A driver for the silicon tuner XC5000 from Xceive. This device is only used inside a SiP called togther with a demodulator for now. +config MEDIA_TUNER_MXL5005S + tristate "MaxLinear MSL5005S silicon tuner" + depends on VIDEO_MEDIA && I2C + default m if DVB_FE_CUSTOMISE + help + A driver for the silicon tuner MXL5005S from MaxLinear. + endif # MEDIA_TUNER_CUSTOMIZE diff --git a/drivers/media/common/tuners/Makefile b/drivers/media/common/tuners/Makefile index 236d9932fd922190ddd55c953aa135369c65c705..55f7e6706297106558a0c372c6b28fb5e6ff02b0 100644 --- a/drivers/media/common/tuners/Makefile +++ b/drivers/media/common/tuners/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_MEDIA_TUNER_MT2060) += mt2060.o obj-$(CONFIG_MEDIA_TUNER_MT2266) += mt2266.o obj-$(CONFIG_MEDIA_TUNER_QT1010) += qt1010.o obj-$(CONFIG_MEDIA_TUNER_MT2131) += mt2131.o +obj-$(CONFIG_MEDIA_TUNER_MXL5005S) += mxl5005s.o EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core EXTRA_CFLAGS += -Idrivers/media/dvb/frontends diff --git a/drivers/media/common/tuners/mxl5005s.c b/drivers/media/common/tuners/mxl5005s.c new file mode 100644 index 0000000000000000000000000000000000000000..5d05b5390f66f48cc2e95c6f4d2f3bb7884a9156 --- /dev/null +++ b/drivers/media/common/tuners/mxl5005s.c @@ -0,0 +1,4110 @@ +/* + MaxLinear MXL5005S VSB/QAM/DVBT tuner driver + + Copyright (C) 2008 MaxLinear + Copyright (C) 2006 Steven Toth + Functions: + mxl5005s_reset() + mxl5005s_writereg() + mxl5005s_writeregs() + mxl5005s_init() + mxl5005s_reconfigure() + mxl5005s_AssignTunerMode() + mxl5005s_set_params() + mxl5005s_get_frequency() + mxl5005s_get_bandwidth() + mxl5005s_release() + mxl5005s_attach() + + Copyright (C) 2008 Realtek + Copyright (C) 2008 Jan Hoogenraad + Functions: + mxl5005s_SetRfFreqHz() + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +/* + History of this driver (Steven Toth): + I was given a public release of a linux driver that included + support for the MaxLinear MXL5005S silicon tuner. Analysis of + the tuner driver showed clearly three things. + + 1. The tuner driver didn't support the LinuxTV tuner API + so the code Realtek added had to be removed. + + 2. A significant amount of the driver is reference driver code + from MaxLinear, I felt it was important to identify and + preserve this. + + 3. New code has to be added to interface correctly with the + LinuxTV API, as a regular kernel module. + + Other than the reference driver enum's, I've clearly marked + sections of the code and retained the copyright of the + respective owners. +*/ +#include +#include +#include +#include +#include +#include +#include "dvb_frontend.h" +#include "mxl5005s.h" + +static int debug; + +#define dprintk(level, arg...) do { \ + if (level <= debug) \ + printk(arg); \ + } while (0) + +#define TUNER_REGS_NUM 104 +#define INITCTRL_NUM 40 + +#ifdef _MXL_PRODUCTION +#define CHCTRL_NUM 39 +#else +#define CHCTRL_NUM 36 +#endif + +#define MXLCTRL_NUM 189 +#define MASTER_CONTROL_ADDR 9 + +/* Enumeration of Master Control Register State */ +enum master_control_state { + MC_LOAD_START = 1, + MC_POWER_DOWN, + MC_SYNTH_RESET, + MC_SEQ_OFF +}; + +/* Enumeration of MXL5005 Tuner Modulation Type */ +enum { + MXL_DEFAULT_MODULATION = 0, + MXL_DVBT, + MXL_ATSC, + MXL_QAM, + MXL_ANALOG_CABLE, + MXL_ANALOG_OTA +} tuner_modu_type; + +/* MXL5005 Tuner Register Struct */ +struct TunerReg { + u16 Reg_Num; /* Tuner Register Address */ + u16 Reg_Val; /* Current sw programmed value waiting to be writen */ +}; + +enum { + /* Initialization Control Names */ + DN_IQTN_AMP_CUT = 1, /* 1 */ + BB_MODE, /* 2 */ + BB_BUF, /* 3 */ + BB_BUF_OA, /* 4 */ + BB_ALPF_BANDSELECT, /* 5 */ + BB_IQSWAP, /* 6 */ + BB_DLPF_BANDSEL, /* 7 */ + RFSYN_CHP_GAIN, /* 8 */ + RFSYN_EN_CHP_HIGAIN, /* 9 */ + AGC_IF, /* 10 */ + AGC_RF, /* 11 */ + IF_DIVVAL, /* 12 */ + IF_VCO_BIAS, /* 13 */ + CHCAL_INT_MOD_IF, /* 14 */ + CHCAL_FRAC_MOD_IF, /* 15 */ + DRV_RES_SEL, /* 16 */ + I_DRIVER, /* 17 */ + EN_AAF, /* 18 */ + EN_3P, /* 19 */ + EN_AUX_3P, /* 20 */ + SEL_AAF_BAND, /* 21 */ + SEQ_ENCLK16_CLK_OUT, /* 22 */ + SEQ_SEL4_16B, /* 23 */ + XTAL_CAPSELECT, /* 24 */ + IF_SEL_DBL, /* 25 */ + RFSYN_R_DIV, /* 26 */ + SEQ_EXTSYNTHCALIF, /* 27 */ + SEQ_EXTDCCAL, /* 28 */ + AGC_EN_RSSI, /* 29 */ + RFA_ENCLKRFAGC, /* 30 */ + RFA_RSSI_REFH, /* 31 */ + RFA_RSSI_REF, /* 32 */ + RFA_RSSI_REFL, /* 33 */ + RFA_FLR, /* 34 */ + RFA_CEIL, /* 35 */ + SEQ_EXTIQFSMPULSE, /* 36 */ + OVERRIDE_1, /* 37 */ + BB_INITSTATE_DLPF_TUNE, /* 38 */ + TG_R_DIV, /* 39 */ + EN_CHP_LIN_B, /* 40 */ + + /* Channel Change Control Names */ + DN_POLY = 51, /* 51 */ + DN_RFGAIN, /* 52 */ + DN_CAP_RFLPF, /* 53 */ + DN_EN_VHFUHFBAR, /* 54 */ + DN_GAIN_ADJUST, /* 55 */ + DN_IQTNBUF_AMP, /* 56 */ + DN_IQTNGNBFBIAS_BST, /* 57 */ + RFSYN_EN_OUTMUX, /* 58 */ + RFSYN_SEL_VCO_OUT, /* 59 */ + RFSYN_SEL_VCO_HI, /* 60 */ + RFSYN_SEL_DIVM, /* 61 */ + RFSYN_RF_DIV_BIAS, /* 62 */ + DN_SEL_FREQ, /* 63 */ + RFSYN_VCO_BIAS, /* 64 */ + CHCAL_INT_MOD_RF, /* 65 */ + CHCAL_FRAC_MOD_RF, /* 66 */ + RFSYN_LPF_R, /* 67 */ + CHCAL_EN_INT_RF, /* 68 */ + TG_LO_DIVVAL, /* 69 */ + TG_LO_SELVAL, /* 70 */ + TG_DIV_VAL, /* 71 */ + TG_VCO_BIAS, /* 72 */ + SEQ_EXTPOWERUP, /* 73 */ + OVERRIDE_2, /* 74 */ + OVERRIDE_3, /* 75 */ + OVERRIDE_4, /* 76 */ + SEQ_FSM_PULSE, /* 77 */ + GPIO_4B, /* 78 */ + GPIO_3B, /* 79 */ + GPIO_4, /* 80 */ + GPIO_3, /* 81 */ + GPIO_1B, /* 82 */ + DAC_A_ENABLE, /* 83 */ + DAC_B_ENABLE, /* 84 */ + DAC_DIN_A, /* 85 */ + DAC_DIN_B, /* 86 */ +#ifdef _MXL_PRODUCTION + RFSYN_EN_DIV, /* 87 */ + RFSYN_DIVM, /* 88 */ + DN_BYPASS_AGC_I2C /* 89 */ +#endif +} MXL5005_ControlName; + +/* + * The following context is source code provided by MaxLinear. + * MaxLinear source code - Common_MXL.h (?) + */ + +/* Constants */ +#define MXL5005S_REG_WRITING_TABLE_LEN_MAX 104 +#define MXL5005S_LATCH_BYTE 0xfe + +/* Register address, MSB, and LSB */ +#define MXL5005S_BB_IQSWAP_ADDR 59 +#define MXL5005S_BB_IQSWAP_MSB 0 +#define MXL5005S_BB_IQSWAP_LSB 0 + +#define MXL5005S_BB_DLPF_BANDSEL_ADDR 53 +#define MXL5005S_BB_DLPF_BANDSEL_MSB 4 +#define MXL5005S_BB_DLPF_BANDSEL_LSB 3 + +/* Standard modes */ +enum { + MXL5005S_STANDARD_DVBT, + MXL5005S_STANDARD_ATSC, +}; +#define MXL5005S_STANDARD_MODE_NUM 2 + +/* Bandwidth modes */ +enum { + MXL5005S_BANDWIDTH_6MHZ = 6000000, + MXL5005S_BANDWIDTH_7MHZ = 7000000, + MXL5005S_BANDWIDTH_8MHZ = 8000000, +}; +#define MXL5005S_BANDWIDTH_MODE_NUM 3 + +/* MXL5005 Tuner Control Struct */ +struct TunerControl { + u16 Ctrl_Num; /* Control Number */ + u16 size; /* Number of bits to represent Value */ + u16 addr[25]; /* Array of Tuner Register Address for each bit pos */ + u16 bit[25]; /* Array of bit pos in Reg Addr for each bit pos */ + u16 val[25]; /* Binary representation of Value */ +}; + +/* MXL5005 Tuner Struct */ +struct mxl5005s_state { + u8 Mode; /* 0: Analog Mode ; 1: Digital Mode */ + u8 IF_Mode; /* for Analog Mode, 0: zero IF; 1: low IF */ + u32 Chan_Bandwidth; /* filter channel bandwidth (6, 7, 8) */ + u32 IF_OUT; /* Desired IF Out Frequency */ + u16 IF_OUT_LOAD; /* IF Out Load Resistor (200/300 Ohms) */ + u32 RF_IN; /* RF Input Frequency */ + u32 Fxtal; /* XTAL Frequency */ + u8 AGC_Mode; /* AGC Mode 0: Dual AGC; 1: Single AGC */ + u16 TOP; /* Value: take over point */ + u8 CLOCK_OUT; /* 0: turn off clk out; 1: turn on clock out */ + u8 DIV_OUT; /* 4MHz or 16MHz */ + u8 CAPSELECT; /* 0: disable On-Chip pulling cap; 1: enable */ + u8 EN_RSSI; /* 0: disable RSSI; 1: enable RSSI */ + + /* Modulation Type; */ + /* 0 - Default; 1 - DVB-T; 2 - ATSC; 3 - QAM; 4 - Analog Cable */ + u8 Mod_Type; + + /* Tracking Filter Type */ + /* 0 - Default; 1 - Off; 2 - Type C; 3 - Type C-H */ + u8 TF_Type; + + /* Calculated Settings */ + u32 RF_LO; /* Synth RF LO Frequency */ + u32 IF_LO; /* Synth IF LO Frequency */ + u32 TG_LO; /* Synth TG_LO Frequency */ + + /* Pointers to ControlName Arrays */ + u16 Init_Ctrl_Num; /* Number of INIT Control Names */ + struct TunerControl + Init_Ctrl[INITCTRL_NUM]; /* INIT Control Names Array Pointer */ + + u16 CH_Ctrl_Num; /* Number of CH Control Names */ + struct TunerControl + CH_Ctrl[CHCTRL_NUM]; /* CH Control Name Array Pointer */ + + u16 MXL_Ctrl_Num; /* Number of MXL Control Names */ + struct TunerControl + MXL_Ctrl[MXLCTRL_NUM]; /* MXL Control Name Array Pointer */ + + /* Pointer to Tuner Register Array */ + u16 TunerRegs_Num; /* Number of Tuner Registers */ + struct TunerReg + TunerRegs[TUNER_REGS_NUM]; /* Tuner Register Array Pointer */ + + /* Linux driver framework specific */ + struct mxl5005s_config *config; + struct dvb_frontend *frontend; + struct i2c_adapter *i2c; + + /* Cache values */ + u32 current_mode; + +}; + +static u16 MXL_GetMasterControl(u8 *MasterReg, int state); +static u16 MXL_ControlWrite(struct dvb_frontend *fe, u16 ControlNum, u32 value); +static u16 MXL_ControlRead(struct dvb_frontend *fe, u16 controlNum, u32 *value); +static void MXL_RegWriteBit(struct dvb_frontend *fe, u8 address, u8 bit, + u8 bitVal); +static u16 MXL_GetCHRegister(struct dvb_frontend *fe, u8 *RegNum, + u8 *RegVal, int *count); +static u32 MXL_Ceiling(u32 value, u32 resolution); +static u16 MXL_RegRead(struct dvb_frontend *fe, u8 RegNum, u8 *RegVal); +static u16 MXL_ControlWrite_Group(struct dvb_frontend *fe, u16 controlNum, + u32 value, u16 controlGroup); +static u16 MXL_SetGPIO(struct dvb_frontend *fe, u8 GPIO_Num, u8 GPIO_Val); +static u16 MXL_GetInitRegister(struct dvb_frontend *fe, u8 *RegNum, + u8 *RegVal, int *count); +static u32 MXL_GetXtalInt(u32 Xtal_Freq); +static u16 MXL_TuneRF(struct dvb_frontend *fe, u32 RF_Freq); +static void MXL_SynthIFLO_Calc(struct dvb_frontend *fe); +static void MXL_SynthRFTGLO_Calc(struct dvb_frontend *fe); +static u16 MXL_GetCHRegister_ZeroIF(struct dvb_frontend *fe, u8 *RegNum, + u8 *RegVal, int *count); +static int mxl5005s_writeregs(struct dvb_frontend *fe, u8 *addrtable, + u8 *datatable, u8 len); +static u16 MXL_IFSynthInit(struct dvb_frontend *fe); +static int mxl5005s_AssignTunerMode(struct dvb_frontend *fe, u32 mod_type, + u32 bandwidth); +static int mxl5005s_reconfigure(struct dvb_frontend *fe, u32 mod_type, + u32 bandwidth); + +/* ---------------------------------------------------------------- + * Begin: Custom code salvaged from the Realtek driver. + * Copyright (C) 2008 Realtek + * Copyright (C) 2008 Jan Hoogenraad + * This code is placed under the terms of the GNU General Public License + * + * Released by Realtek under GPLv2. + * Thanks to Realtek for a lot of support we received ! + * + * Revision: 080314 - original version + */ + +static int mxl5005s_SetRfFreqHz(struct dvb_frontend *fe, unsigned long RfFreqHz) +{ + struct mxl5005s_state *state = fe->tuner_priv; + unsigned char AddrTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX]; + unsigned char ByteTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX]; + int TableLen; + + u32 IfDivval = 0; + unsigned char MasterControlByte; + + dprintk(1, "%s() freq=%ld\n", __func__, RfFreqHz); + + /* Set MxL5005S tuner RF frequency according to example code. */ + + /* Tuner RF frequency setting stage 0 */ + MXL_GetMasterControl(ByteTable, MC_SYNTH_RESET); + AddrTable[0] = MASTER_CONTROL_ADDR; + ByteTable[0] |= state->config->AgcMasterByte; + + mxl5005s_writeregs(fe, AddrTable, ByteTable, 1); + + /* Tuner RF frequency setting stage 1 */ + MXL_TuneRF(fe, RfFreqHz); + + MXL_ControlRead(fe, IF_DIVVAL, &IfDivval); + + MXL_ControlWrite(fe, SEQ_FSM_PULSE, 0); + MXL_ControlWrite(fe, SEQ_EXTPOWERUP, 1); + MXL_ControlWrite(fe, IF_DIVVAL, 8); + MXL_GetCHRegister(fe, AddrTable, ByteTable, &TableLen); + + MXL_GetMasterControl(&MasterControlByte, MC_LOAD_START); + AddrTable[TableLen] = MASTER_CONTROL_ADDR ; + ByteTable[TableLen] = MasterControlByte | + state->config->AgcMasterByte; + TableLen += 1; + + mxl5005s_writeregs(fe, AddrTable, ByteTable, TableLen); + + /* Wait 30 ms. */ + msleep(150); + + /* Tuner RF frequency setting stage 2 */ + MXL_ControlWrite(fe, SEQ_FSM_PULSE, 1); + MXL_ControlWrite(fe, IF_DIVVAL, IfDivval); + MXL_GetCHRegister_ZeroIF(fe, AddrTable, ByteTable, &TableLen); + + MXL_GetMasterControl(&MasterControlByte, MC_LOAD_START); + AddrTable[TableLen] = MASTER_CONTROL_ADDR ; + ByteTable[TableLen] = MasterControlByte | + state->config->AgcMasterByte ; + TableLen += 1; + + mxl5005s_writeregs(fe, AddrTable, ByteTable, TableLen); + + msleep(100); + + return 0; +} +/* End: Custom code taken from the Realtek driver */ + +/* ---------------------------------------------------------------- + * Begin: Reference driver code found in the Realtek driver. + * Copyright (C) 2008 MaxLinear + */ +static u16 MXL5005_RegisterInit(struct dvb_frontend *fe) +{ + struct mxl5005s_state *state = fe->tuner_priv; + state->TunerRegs_Num = TUNER_REGS_NUM ; + + state->TunerRegs[0].Reg_Num = 9 ; + state->TunerRegs[0].Reg_Val = 0x40 ; + + state->TunerRegs[1].Reg_Num = 11 ; + state->TunerRegs[1].Reg_Val = 0x19 ; + + state->TunerRegs[2].Reg_Num = 12 ; + state->TunerRegs[2].Reg_Val = 0x60 ; + + state->TunerRegs[3].Reg_Num = 13 ; + state->TunerRegs[3].Reg_Val = 0x00 ; + + state->TunerRegs[4].Reg_Num = 14 ; + state->TunerRegs[4].Reg_Val = 0x00 ; + + state->TunerRegs[5].Reg_Num = 15 ; + state->TunerRegs[5].Reg_Val = 0xC0 ; + + state->TunerRegs[6].Reg_Num = 16 ; + state->TunerRegs[6].Reg_Val = 0x00 ; + + state->TunerRegs[7].Reg_Num = 17 ; + state->TunerRegs[7].Reg_Val = 0x00 ; + + state->TunerRegs[8].Reg_Num = 18 ; + state->TunerRegs[8].Reg_Val = 0x00 ; + + state->TunerRegs[9].Reg_Num = 19 ; + state->TunerRegs[9].Reg_Val = 0x34 ; + + state->TunerRegs[10].Reg_Num = 21 ; + state->TunerRegs[10].Reg_Val = 0x00 ; + + state->TunerRegs[11].Reg_Num = 22 ; + state->TunerRegs[11].Reg_Val = 0x6B ; + + state->TunerRegs[12].Reg_Num = 23 ; + state->TunerRegs[12].Reg_Val = 0x35 ; + + state->TunerRegs[13].Reg_Num = 24 ; + state->TunerRegs[13].Reg_Val = 0x70 ; + + state->TunerRegs[14].Reg_Num = 25 ; + state->TunerRegs[14].Reg_Val = 0x3E ; + + state->TunerRegs[15].Reg_Num = 26 ; + state->TunerRegs[15].Reg_Val = 0x82 ; + + state->TunerRegs[16].Reg_Num = 31 ; + state->TunerRegs[16].Reg_Val = 0x00 ; + + state->TunerRegs[17].Reg_Num = 32 ; + state->TunerRegs[17].Reg_Val = 0x40 ; + + state->TunerRegs[18].Reg_Num = 33 ; + state->TunerRegs[18].Reg_Val = 0x53 ; + + state->TunerRegs[19].Reg_Num = 34 ; + state->TunerRegs[19].Reg_Val = 0x81 ; + + state->TunerRegs[20].Reg_Num = 35 ; + state->TunerRegs[20].Reg_Val = 0xC9 ; + + state->TunerRegs[21].Reg_Num = 36 ; + state->TunerRegs[21].Reg_Val = 0x01 ; + + state->TunerRegs[22].Reg_Num = 37 ; + state->TunerRegs[22].Reg_Val = 0x00 ; + + state->TunerRegs[23].Reg_Num = 41 ; + state->TunerRegs[23].Reg_Val = 0x00 ; + + state->TunerRegs[24].Reg_Num = 42 ; + state->TunerRegs[24].Reg_Val = 0xF8 ; + + state->TunerRegs[25].Reg_Num = 43 ; + state->TunerRegs[25].Reg_Val = 0x43 ; + + state->TunerRegs[26].Reg_Num = 44 ; + state->TunerRegs[26].Reg_Val = 0x20 ; + + state->TunerRegs[27].Reg_Num = 45 ; + state->TunerRegs[27].Reg_Val = 0x80 ; + + state->TunerRegs[28].Reg_Num = 46 ; + state->TunerRegs[28].Reg_Val = 0x88 ; + + state->TunerRegs[29].Reg_Num = 47 ; + state->TunerRegs[29].Reg_Val = 0x86 ; + + state->TunerRegs[30].Reg_Num = 48 ; + state->TunerRegs[30].Reg_Val = 0x00 ; + + state->TunerRegs[31].Reg_Num = 49 ; + state->TunerRegs[31].Reg_Val = 0x00 ; + + state->TunerRegs[32].Reg_Num = 53 ; + state->TunerRegs[32].Reg_Val = 0x94 ; + + state->TunerRegs[33].Reg_Num = 54 ; + state->TunerRegs[33].Reg_Val = 0xFA ; + + state->TunerRegs[34].Reg_Num = 55 ; + state->TunerRegs[34].Reg_Val = 0x92 ; + + state->TunerRegs[35].Reg_Num = 56 ; + state->TunerRegs[35].Reg_Val = 0x80 ; + + state->TunerRegs[36].Reg_Num = 57 ; + state->TunerRegs[36].Reg_Val = 0x41 ; + + state->TunerRegs[37].Reg_Num = 58 ; + state->TunerRegs[37].Reg_Val = 0xDB ; + + state->TunerRegs[38].Reg_Num = 59 ; + state->TunerRegs[38].Reg_Val = 0x00 ; + + state->TunerRegs[39].Reg_Num = 60 ; + state->TunerRegs[39].Reg_Val = 0x00 ; + + state->TunerRegs[40].Reg_Num = 61 ; + state->TunerRegs[40].Reg_Val = 0x00 ; + + state->TunerRegs[41].Reg_Num = 62 ; + state->TunerRegs[41].Reg_Val = 0x00 ; + + state->TunerRegs[42].Reg_Num = 65 ; + state->TunerRegs[42].Reg_Val = 0xF8 ; + + state->TunerRegs[43].Reg_Num = 66 ; + state->TunerRegs[43].Reg_Val = 0xE4 ; + + state->TunerRegs[44].Reg_Num = 67 ; + state->TunerRegs[44].Reg_Val = 0x90 ; + + state->TunerRegs[45].Reg_Num = 68 ; + state->TunerRegs[45].Reg_Val = 0xC0 ; + + state->TunerRegs[46].Reg_Num = 69 ; + state->TunerRegs[46].Reg_Val = 0x01 ; + + state->TunerRegs[47].Reg_Num = 70 ; + state->TunerRegs[47].Reg_Val = 0x50 ; + + state->TunerRegs[48].Reg_Num = 71 ; + state->TunerRegs[48].Reg_Val = 0x06 ; + + state->TunerRegs[49].Reg_Num = 72 ; + state->TunerRegs[49].Reg_Val = 0x00 ; + + state->TunerRegs[50].Reg_Num = 73 ; + state->TunerRegs[50].Reg_Val = 0x20 ; + + state->TunerRegs[51].Reg_Num = 76 ; + state->TunerRegs[51].Reg_Val = 0xBB ; + + state->TunerRegs[52].Reg_Num = 77 ; + state->TunerRegs[52].Reg_Val = 0x13 ; + + state->TunerRegs[53].Reg_Num = 81 ; + state->TunerRegs[53].Reg_Val = 0x04 ; + + state->TunerRegs[54].Reg_Num = 82 ; + state->TunerRegs[54].Reg_Val = 0x75 ; + + state->TunerRegs[55].Reg_Num = 83 ; + state->TunerRegs[55].Reg_Val = 0x00 ; + + state->TunerRegs[56].Reg_Num = 84 ; + state->TunerRegs[56].Reg_Val = 0x00 ; + + state->TunerRegs[57].Reg_Num = 85 ; + state->TunerRegs[57].Reg_Val = 0x00 ; + + state->TunerRegs[58].Reg_Num = 91 ; + state->TunerRegs[58].Reg_Val = 0x70 ; + + state->TunerRegs[59].Reg_Num = 92 ; + state->TunerRegs[59].Reg_Val = 0x00 ; + + state->TunerRegs[60].Reg_Num = 93 ; + state->TunerRegs[60].Reg_Val = 0x00 ; + + state->TunerRegs[61].Reg_Num = 94 ; + state->TunerRegs[61].Reg_Val = 0x00 ; + + state->TunerRegs[62].Reg_Num = 95 ; + state->TunerRegs[62].Reg_Val = 0x0C ; + + state->TunerRegs[63].Reg_Num = 96 ; + state->TunerRegs[63].Reg_Val = 0x00 ; + + state->TunerRegs[64].Reg_Num = 97 ; + state->TunerRegs[64].Reg_Val = 0x00 ; + + state->TunerRegs[65].Reg_Num = 98 ; + state->TunerRegs[65].Reg_Val = 0xE2 ; + + state->TunerRegs[66].Reg_Num = 99 ; + state->TunerRegs[66].Reg_Val = 0x00 ; + + state->TunerRegs[67].Reg_Num = 100 ; + state->TunerRegs[67].Reg_Val = 0x00 ; + + state->TunerRegs[68].Reg_Num = 101 ; + state->TunerRegs[68].Reg_Val = 0x12 ; + + state->TunerRegs[69].Reg_Num = 102 ; + state->TunerRegs[69].Reg_Val = 0x80 ; + + state->TunerRegs[70].Reg_Num = 103 ; + state->TunerRegs[70].Reg_Val = 0x32 ; + + state->TunerRegs[71].Reg_Num = 104 ; + state->TunerRegs[71].Reg_Val = 0xB4 ; + + state->TunerRegs[72].Reg_Num = 105 ; + state->TunerRegs[72].Reg_Val = 0x60 ; + + state->TunerRegs[73].Reg_Num = 106 ; + state->TunerRegs[73].Reg_Val = 0x83 ; + + state->TunerRegs[74].Reg_Num = 107 ; + state->TunerRegs[74].Reg_Val = 0x84 ; + + state->TunerRegs[75].Reg_Num = 108 ; + state->TunerRegs[75].Reg_Val = 0x9C ; + + state->TunerRegs[76].Reg_Num = 109 ; + state->TunerRegs[76].Reg_Val = 0x02 ; + + state->TunerRegs[77].Reg_Num = 110 ; + state->TunerRegs[77].Reg_Val = 0x81 ; + + state->TunerRegs[78].Reg_Num = 111 ; + state->TunerRegs[78].Reg_Val = 0xC0 ; + + state->TunerRegs[79].Reg_Num = 112 ; + state->TunerRegs[79].Reg_Val = 0x10 ; + + state->TunerRegs[80].Reg_Num = 131 ; + state->TunerRegs[80].Reg_Val = 0x8A ; + + state->TunerRegs[81].Reg_Num = 132 ; + state->TunerRegs[81].Reg_Val = 0x10 ; + + state->TunerRegs[82].Reg_Num = 133 ; + state->TunerRegs[82].Reg_Val = 0x24 ; + + state->TunerRegs[83].Reg_Num = 134 ; + state->TunerRegs[83].Reg_Val = 0x00 ; + + state->TunerRegs[84].Reg_Num = 135 ; + state->TunerRegs[84].Reg_Val = 0x00 ; + + state->TunerRegs[85].Reg_Num = 136 ; + state->TunerRegs[85].Reg_Val = 0x7E ; + + state->TunerRegs[86].Reg_Num = 137 ; + state->TunerRegs[86].Reg_Val = 0x40 ; + + state->TunerRegs[87].Reg_Num = 138 ; + state->TunerRegs[87].Reg_Val = 0x38 ; + + state->TunerRegs[88].Reg_Num = 146 ; + state->TunerRegs[88].Reg_Val = 0xF6 ; + + state->TunerRegs[89].Reg_Num = 147 ; + state->TunerRegs[89].Reg_Val = 0x1A ; + + state->TunerRegs[90].Reg_Num = 148 ; + state->TunerRegs[90].Reg_Val = 0x62 ; + + state->TunerRegs[91].Reg_Num = 149 ; + state->TunerRegs[91].Reg_Val = 0x33 ; + + state->TunerRegs[92].Reg_Num = 150 ; + state->TunerRegs[92].Reg_Val = 0x80 ; + + state->TunerRegs[93].Reg_Num = 156 ; + state->TunerRegs[93].Reg_Val = 0x56 ; + + state->TunerRegs[94].Reg_Num = 157 ; + state->TunerRegs[94].Reg_Val = 0x17 ; + + state->TunerRegs[95].Reg_Num = 158 ; + state->TunerRegs[95].Reg_Val = 0xA9 ; + + state->TunerRegs[96].Reg_Num = 159 ; + state->TunerRegs[96].Reg_Val = 0x00 ; + + state->TunerRegs[97].Reg_Num = 160 ; + state->TunerRegs[97].Reg_Val = 0x00 ; + + state->TunerRegs[98].Reg_Num = 161 ; + state->TunerRegs[98].Reg_Val = 0x00 ; + + state->TunerRegs[99].Reg_Num = 162 ; + state->TunerRegs[99].Reg_Val = 0x40 ; + + state->TunerRegs[100].Reg_Num = 166 ; + state->TunerRegs[100].Reg_Val = 0xAE ; + + state->TunerRegs[101].Reg_Num = 167 ; + state->TunerRegs[101].Reg_Val = 0x1B ; + + state->TunerRegs[102].Reg_Num = 168 ; + state->TunerRegs[102].Reg_Val = 0xF2 ; + + state->TunerRegs[103].Reg_Num = 195 ; + state->TunerRegs[103].Reg_Val = 0x00 ; + + return 0 ; +} + +static u16 MXL5005_ControlInit(struct dvb_frontend *fe) +{ + struct mxl5005s_state *state = fe->tuner_priv; + state->Init_Ctrl_Num = INITCTRL_NUM; + + state->Init_Ctrl[0].Ctrl_Num = DN_IQTN_AMP_CUT ; + state->Init_Ctrl[0].size = 1 ; + state->Init_Ctrl[0].addr[0] = 73; + state->Init_Ctrl[0].bit[0] = 7; + state->Init_Ctrl[0].val[0] = 0; + + state->Init_Ctrl[1].Ctrl_Num = BB_MODE ; + state->Init_Ctrl[1].size = 1 ; + state->Init_Ctrl[1].addr[0] = 53; + state->Init_Ctrl[1].bit[0] = 2; + state->Init_Ctrl[1].val[0] = 1; + + state->Init_Ctrl[2].Ctrl_Num = BB_BUF ; + state->Init_Ctrl[2].size = 2 ; + state->Init_Ctrl[2].addr[0] = 53; + state->Init_Ctrl[2].bit[0] = 1; + state->Init_Ctrl[2].val[0] = 0; + state->Init_Ctrl[2].addr[1] = 57; + state->Init_Ctrl[2].bit[1] = 0; + state->Init_Ctrl[2].val[1] = 1; + + state->Init_Ctrl[3].Ctrl_Num = BB_BUF_OA ; + state->Init_Ctrl[3].size = 1 ; + state->Init_Ctrl[3].addr[0] = 53; + state->Init_Ctrl[3].bit[0] = 0; + state->Init_Ctrl[3].val[0] = 0; + + state->Init_Ctrl[4].Ctrl_Num = BB_ALPF_BANDSELECT ; + state->Init_Ctrl[4].size = 3 ; + state->Init_Ctrl[4].addr[0] = 53; + state->Init_Ctrl[4].bit[0] = 5; + state->Init_Ctrl[4].val[0] = 0; + state->Init_Ctrl[4].addr[1] = 53; + state->Init_Ctrl[4].bit[1] = 6; + state->Init_Ctrl[4].val[1] = 0; + state->Init_Ctrl[4].addr[2] = 53; + state->Init_Ctrl[4].bit[2] = 7; + state->Init_Ctrl[4].val[2] = 1; + + state->Init_Ctrl[5].Ctrl_Num = BB_IQSWAP ; + state->Init_Ctrl[5].size = 1 ; + state->Init_Ctrl[5].addr[0] = 59; + state->Init_Ctrl[5].bit[0] = 0; + state->Init_Ctrl[5].val[0] = 0; + + state->Init_Ctrl[6].Ctrl_Num = BB_DLPF_BANDSEL ; + state->Init_Ctrl[6].size = 2 ; + state->Init_Ctrl[6].addr[0] = 53; + state->Init_Ctrl[6].bit[0] = 3; + state->Init_Ctrl[6].val[0] = 0; + state->Init_Ctrl[6].addr[1] = 53; + state->Init_Ctrl[6].bit[1] = 4; + state->Init_Ctrl[6].val[1] = 1; + + state->Init_Ctrl[7].Ctrl_Num = RFSYN_CHP_GAIN ; + state->Init_Ctrl[7].size = 4 ; + state->Init_Ctrl[7].addr[0] = 22; + state->Init_Ctrl[7].bit[0] = 4; + state->Init_Ctrl[7].val[0] = 0; + state->Init_Ctrl[7].addr[1] = 22; + state->Init_Ctrl[7].bit[1] = 5; + state->Init_Ctrl[7].val[1] = 1; + state->Init_Ctrl[7].addr[2] = 22; + state->Init_Ctrl[7].bit[2] = 6; + state->Init_Ctrl[7].val[2] = 1; + state->Init_Ctrl[7].addr[3] = 22; + state->Init_Ctrl[7].bit[3] = 7; + state->Init_Ctrl[7].val[3] = 0; + + state->Init_Ctrl[8].Ctrl_Num = RFSYN_EN_CHP_HIGAIN ; + state->Init_Ctrl[8].size = 1 ; + state->Init_Ctrl[8].addr[0] = 22; + state->Init_Ctrl[8].bit[0] = 2; + state->Init_Ctrl[8].val[0] = 0; + + state->Init_Ctrl[9].Ctrl_Num = AGC_IF ; + state->Init_Ctrl[9].size = 4 ; + state->Init_Ctrl[9].addr[0] = 76; + state->Init_Ctrl[9].bit[0] = 0; + state->Init_Ctrl[9].val[0] = 1; + state->Init_Ctrl[9].addr[1] = 76; + state->Init_Ctrl[9].bit[1] = 1; + state->Init_Ctrl[9].val[1] = 1; + state->Init_Ctrl[9].addr[2] = 76; + state->Init_Ctrl[9].bit[2] = 2; + state->Init_Ctrl[9].val[2] = 0; + state->Init_Ctrl[9].addr[3] = 76; + state->Init_Ctrl[9].bit[3] = 3; + state->Init_Ctrl[9].val[3] = 1; + + state->Init_Ctrl[10].Ctrl_Num = AGC_RF ; + state->Init_Ctrl[10].size = 4 ; + state->Init_Ctrl[10].addr[0] = 76; + state->Init_Ctrl[10].bit[0] = 4; + state->Init_Ctrl[10].val[0] = 1; + state->Init_Ctrl[10].addr[1] = 76; + state->Init_Ctrl[10].bit[1] = 5; + state->Init_Ctrl[10].val[1] = 1; + state->Init_Ctrl[10].addr[2] = 76; + state->Init_Ctrl[10].bit[2] = 6; + state->Init_Ctrl[10].val[2] = 0; + state->Init_Ctrl[10].addr[3] = 76; + state->Init_Ctrl[10].bit[3] = 7; + state->Init_Ctrl[10].val[3] = 1; + + state->Init_Ctrl[11].Ctrl_Num = IF_DIVVAL ; + state->Init_Ctrl[11].size = 5 ; + state->Init_Ctrl[11].addr[0] = 43; + state->Init_Ctrl[11].bit[0] = 3; + state->Init_Ctrl[11].val[0] = 0; + state->Init_Ctrl[11].addr[1] = 43; + state->Init_Ctrl[11].bit[1] = 4; + state->Init_Ctrl[11].val[1] = 0; + state->Init_Ctrl[11].addr[2] = 43; + state->Init_Ctrl[11].bit[2] = 5; + state->Init_Ctrl[11].val[2] = 0; + state->Init_Ctrl[11].addr[3] = 43; + state->Init_Ctrl[11].bit[3] = 6; + state->Init_Ctrl[11].val[3] = 1; + state->Init_Ctrl[11].addr[4] = 43; + state->Init_Ctrl[11].bit[4] = 7; + state->Init_Ctrl[11].val[4] = 0; + + state->Init_Ctrl[12].Ctrl_Num = IF_VCO_BIAS ; + state->Init_Ctrl[12].size = 6 ; + state->Init_Ctrl[12].addr[0] = 44; + state->Init_Ctrl[12].bit[0] = 2; + state->Init_Ctrl[12].val[0] = 0; + state->Init_Ctrl[12].addr[1] = 44; + state->Init_Ctrl[12].bit[1] = 3; + state->Init_Ctrl[12].val[1] = 0; + state->Init_Ctrl[12].addr[2] = 44; + state->Init_Ctrl[12].bit[2] = 4; + state->Init_Ctrl[12].val[2] = 0; + state->Init_Ctrl[12].addr[3] = 44; + state->Init_Ctrl[12].bit[3] = 5; + state->Init_Ctrl[12].val[3] = 1; + state->Init_Ctrl[12].addr[4] = 44; + state->Init_Ctrl[12].bit[4] = 6; + state->Init_Ctrl[12].val[4] = 0; + state->Init_Ctrl[12].addr[5] = 44; + state->Init_Ctrl[12].bit[5] = 7; + state->Init_Ctrl[12].val[5] = 0; + + state->Init_Ctrl[13].Ctrl_Num = CHCAL_INT_MOD_IF ; + state->Init_Ctrl[13].size = 7 ; + state->Init_Ctrl[13].addr[0] = 11; + state->Init_Ctrl[13].bit[0] = 0; + state->Init_Ctrl[13].val[0] = 1; + state->Init_Ctrl[13].addr[1] = 11; + state->Init_Ctrl[13].bit[1] = 1; + state->Init_Ctrl[13].val[1] = 0; + state->Init_Ctrl[13].addr[2] = 11; + state->Init_Ctrl[13].bit[2] = 2; + state->Init_Ctrl[13].val[2] = 0; + state->Init_Ctrl[13].addr[3] = 11; + state->Init_Ctrl[13].bit[3] = 3; + state->Init_Ctrl[13].val[3] = 1; + state->Init_Ctrl[13].addr[4] = 11; + state->Init_Ctrl[13].bit[4] = 4; + state->Init_Ctrl[13].val[4] = 1; + state->Init_Ctrl[13].addr[5] = 11; + state->Init_Ctrl[13].bit[5] = 5; + state->Init_Ctrl[13].val[5] = 0; + state->Init_Ctrl[13].addr[6] = 11; + state->Init_Ctrl[13].bit[6] = 6; + state->Init_Ctrl[13].val[6] = 0; + + state->Init_Ctrl[14].Ctrl_Num = CHCAL_FRAC_MOD_IF ; + state->Init_Ctrl[14].size = 16 ; + state->Init_Ctrl[14].addr[0] = 13; + state->Init_Ctrl[14].bit[0] = 0; + state->Init_Ctrl[14].val[0] = 0; + state->Init_Ctrl[14].addr[1] = 13; + state->Init_Ctrl[14].bit[1] = 1; + state->Init_Ctrl[14].val[1] = 0; + state->Init_Ctrl[14].addr[2] = 13; + state->Init_Ctrl[14].bit[2] = 2; + state->Init_Ctrl[14].val[2] = 0; + state->Init_Ctrl[14].addr[3] = 13; + state->Init_Ctrl[14].bit[3] = 3; + state->Init_Ctrl[14].val[3] = 0; + state->Init_Ctrl[14].addr[4] = 13; + state->Init_Ctrl[14].bit[4] = 4; + state->Init_Ctrl[14].val[4] = 0; + state->Init_Ctrl[14].addr[5] = 13; + state->Init_Ctrl[14].bit[5] = 5; + state->Init_Ctrl[14].val[5] = 0; + state->Init_Ctrl[14].addr[6] = 13; + state->Init_Ctrl[14].bit[6] = 6; + state->Init_Ctrl[14].val[6] = 0; + state->Init_Ctrl[14].addr[7] = 13; + state->Init_Ctrl[14].bit[7] = 7; + state->Init_Ctrl[14].val[7] = 0; + state->Init_Ctrl[14].addr[8] = 12; + state->Init_Ctrl[14].bit[8] = 0; + state->Init_Ctrl[14].val[8] = 0; + state->Init_Ctrl[14].addr[9] = 12; + state->Init_Ctrl[14].bit[9] = 1; + state->Init_Ctrl[14].val[9] = 0; + state->Init_Ctrl[14].addr[10] = 12; + state->Init_Ctrl[14].bit[10] = 2; + state->Init_Ctrl[14].val[10] = 0; + state->Init_Ctrl[14].addr[11] = 12; + state->Init_Ctrl[14].bit[11] = 3; + state->Init_Ctrl[14].val[11] = 0; + state->Init_Ctrl[14].addr[12] = 12; + state->Init_Ctrl[14].bit[12] = 4; + state->Init_Ctrl[14].val[12] = 0; + state->Init_Ctrl[14].addr[13] = 12; + state->Init_Ctrl[14].bit[13] = 5; + state->Init_Ctrl[14].val[13] = 1; + state->Init_Ctrl[14].addr[14] = 12; + state->Init_Ctrl[14].bit[14] = 6; + state->Init_Ctrl[14].val[14] = 1; + state->Init_Ctrl[14].addr[15] = 12; + state->Init_Ctrl[14].bit[15] = 7; + state->Init_Ctrl[14].val[15] = 0; + + state->Init_Ctrl[15].Ctrl_Num = DRV_RES_SEL ; + state->Init_Ctrl[15].size = 3 ; + state->Init_Ctrl[15].addr[0] = 147; + state->Init_Ctrl[15].bit[0] = 2; + state->Init_Ctrl[15].val[0] = 0; + state->Init_Ctrl[15].addr[1] = 147; + state->Init_Ctrl[15].bit[1] = 3; + state->Init_Ctrl[15].val[1] = 1; + state->Init_Ctrl[15].addr[2] = 147; + state->Init_Ctrl[15].bit[2] = 4; + state->Init_Ctrl[15].val[2] = 1; + + state->Init_Ctrl[16].Ctrl_Num = I_DRIVER ; + state->Init_Ctrl[16].size = 2 ; + state->Init_Ctrl[16].addr[0] = 147; + state->Init_Ctrl[16].bit[0] = 0; + state->Init_Ctrl[16].val[0] = 0; + state->Init_Ctrl[16].addr[1] = 147; + state->Init_Ctrl[16].bit[1] = 1; + state->Init_Ctrl[16].val[1] = 1; + + state->Init_Ctrl[17].Ctrl_Num = EN_AAF ; + state->Init_Ctrl[17].size = 1 ; + state->Init_Ctrl[17].addr[0] = 147; + state->Init_Ctrl[17].bit[0] = 7; + state->Init_Ctrl[17].val[0] = 0; + + state->Init_Ctrl[18].Ctrl_Num = EN_3P ; + state->Init_Ctrl[18].size = 1 ; + state->Init_Ctrl[18].addr[0] = 147; + state->Init_Ctrl[18].bit[0] = 6; + state->Init_Ctrl[18].val[0] = 0; + + state->Init_Ctrl[19].Ctrl_Num = EN_AUX_3P ; + state->Init_Ctrl[19].size = 1 ; + state->Init_Ctrl[19].addr[0] = 156; + state->Init_Ctrl[19].bit[0] = 0; + state->Init_Ctrl[19].val[0] = 0; + + state->Init_Ctrl[20].Ctrl_Num = SEL_AAF_BAND ; + state->Init_Ctrl[20].size = 1 ; + state->Init_Ctrl[20].addr[0] = 147; + state->Init_Ctrl[20].bit[0] = 5; + state->Init_Ctrl[20].val[0] = 0; + + state->Init_Ctrl[21].Ctrl_Num = SEQ_ENCLK16_CLK_OUT ; + state->Init_Ctrl[21].size = 1 ; + state->Init_Ctrl[21].addr[0] = 137; + state->Init_Ctrl[21].bit[0] = 4; + state->Init_Ctrl[21].val[0] = 0; + + state->Init_Ctrl[22].Ctrl_Num = SEQ_SEL4_16B ; + state->Init_Ctrl[22].size = 1 ; + state->Init_Ctrl[22].addr[0] = 137; + state->Init_Ctrl[22].bit[0] = 7; + state->Init_Ctrl[22].val[0] = 0; + + state->Init_Ctrl[23].Ctrl_Num = XTAL_CAPSELECT ; + state->Init_Ctrl[23].size = 1 ; + state->Init_Ctrl[23].addr[0] = 91; + state->Init_Ctrl[23].bit[0] = 5; + state->Init_Ctrl[23].val[0] = 1; + + state->Init_Ctrl[24].Ctrl_Num = IF_SEL_DBL ; + state->Init_Ctrl[24].size = 1 ; + state->Init_Ctrl[24].addr[0] = 43; + state->Init_Ctrl[24].bit[0] = 0; + state->Init_Ctrl[24].val[0] = 1; + + state->Init_Ctrl[25].Ctrl_Num = RFSYN_R_DIV ; + state->Init_Ctrl[25].size = 2 ; + state->Init_Ctrl[25].addr[0] = 22; + state->Init_Ctrl[25].bit[0] = 0; + state->Init_Ctrl[25].val[0] = 1; + state->Init_Ctrl[25].addr[1] = 22; + state->Init_Ctrl[25].bit[1] = 1; + state->Init_Ctrl[25].val[1] = 1; + + state->Init_Ctrl[26].Ctrl_Num = SEQ_EXTSYNTHCALIF ; + state->Init_Ctrl[26].size = 1 ; + state->Init_Ctrl[26].addr[0] = 134; + state->Init_Ctrl[26].bit[0] = 2; + state->Init_Ctrl[26].val[0] = 0; + + state->Init_Ctrl[27].Ctrl_Num = SEQ_EXTDCCAL ; + state->Init_Ctrl[27].size = 1 ; + state->Init_Ctrl[27].addr[0] = 137; + state->Init_Ctrl[27].bit[0] = 3; + state->Init_Ctrl[27].val[0] = 0; + + state->Init_Ctrl[28].Ctrl_Num = AGC_EN_RSSI ; + state->Init_Ctrl[28].size = 1 ; + state->Init_Ctrl[28].addr[0] = 77; + state->Init_Ctrl[28].bit[0] = 7; + state->Init_Ctrl[28].val[0] = 0; + + state->Init_Ctrl[29].Ctrl_Num = RFA_ENCLKRFAGC ; + state->Init_Ctrl[29].size = 1 ; + state->Init_Ctrl[29].addr[0] = 166; + state->Init_Ctrl[29].bit[0] = 7; + state->Init_Ctrl[29].val[0] = 1; + + state->Init_Ctrl[30].Ctrl_Num = RFA_RSSI_REFH ; + state->Init_Ctrl[30].size = 3 ; + state->Init_Ctrl[30].addr[0] = 166; + state->Init_Ctrl[30].bit[0] = 0; + state->Init_Ctrl[30].val[0] = 0; + state->Init_Ctrl[30].addr[1] = 166; + state->Init_Ctrl[30].bit[1] = 1; + state->Init_Ctrl[30].val[1] = 1; + state->Init_Ctrl[30].addr[2] = 166; + state->Init_Ctrl[30].bit[2] = 2; + state->Init_Ctrl[30].val[2] = 1; + + state->Init_Ctrl[31].Ctrl_Num = RFA_RSSI_REF ; + state->Init_Ctrl[31].size = 3 ; + state->Init_Ctrl[31].addr[0] = 166; + state->Init_Ctrl[31].bit[0] = 3; + state->Init_Ctrl[31].val[0] = 1; + state->Init_Ctrl[31].addr[1] = 166; + state->Init_Ctrl[31].bit[1] = 4; + state->Init_Ctrl[31].val[1] = 0; + state->Init_Ctrl[31].addr[2] = 166; + state->Init_Ctrl[31].bit[2] = 5; + state->Init_Ctrl[31].val[2] = 1; + + state->Init_Ctrl[32].Ctrl_Num = RFA_RSSI_REFL ; + state->Init_Ctrl[32].size = 3 ; + state->Init_Ctrl[32].addr[0] = 167; + state->Init_Ctrl[32].bit[0] = 0; + state->Init_Ctrl[32].val[0] = 1; + state->Init_Ctrl[32].addr[1] = 167; + state->Init_Ctrl[32].bit[1] = 1; + state->Init_Ctrl[32].val[1] = 1; + state->Init_Ctrl[32].addr[2] = 167; + state->Init_Ctrl[32].bit[2] = 2; + state->Init_Ctrl[32].val[2] = 0; + + state->Init_Ctrl[33].Ctrl_Num = RFA_FLR ; + state->Init_Ctrl[33].size = 4 ; + state->Init_Ctrl[33].addr[0] = 168; + state->Init_Ctrl[33].bit[0] = 0; + state->Init_Ctrl[33].val[0] = 0; + state->Init_Ctrl[33].addr[1] = 168; + state->Init_Ctrl[33].bit[1] = 1; + state->Init_Ctrl[33].val[1] = 1; + state->Init_Ctrl[33].addr[2] = 168; + state->Init_Ctrl[33].bit[2] = 2; + state->Init_Ctrl[33].val[2] = 0; + state->Init_Ctrl[33].addr[3] = 168; + state->Init_Ctrl[33].bit[3] = 3; + state->Init_Ctrl[33].val[3] = 0; + + state->Init_Ctrl[34].Ctrl_Num = RFA_CEIL ; + state->Init_Ctrl[34].size = 4 ; + state->Init_Ctrl[34].addr[0] = 168; + state->Init_Ctrl[34].bit[0] = 4; + state->Init_Ctrl[34].val[0] = 1; + state->Init_Ctrl[34].addr[1] = 168; + state->Init_Ctrl[34].bit[1] = 5; + state->Init_Ctrl[34].val[1] = 1; + state->Init_Ctrl[34].addr[2] = 168; + state->Init_Ctrl[34].bit[2] = 6; + state->Init_Ctrl[34].val[2] = 1; + state->Init_Ctrl[34].addr[3] = 168; + state->Init_Ctrl[34].bit[3] = 7; + state->Init_Ctrl[34].val[3] = 1; + + state->Init_Ctrl[35].Ctrl_Num = SEQ_EXTIQFSMPULSE ; + state->Init_Ctrl[35].size = 1 ; + state->Init_Ctrl[35].addr[0] = 135; + state->Init_Ctrl[35].bit[0] = 0; + state->Init_Ctrl[35].val[0] = 0; + + state->Init_Ctrl[36].Ctrl_Num = OVERRIDE_1 ; + state->Init_Ctrl[36].size = 1 ; + state->Init_Ctrl[36].addr[0] = 56; + state->Init_Ctrl[36].bit[0] = 3; + state->Init_Ctrl[36].val[0] = 0; + + state->Init_Ctrl[37].Ctrl_Num = BB_INITSTATE_DLPF_TUNE ; + state->Init_Ctrl[37].size = 7 ; + state->Init_Ctrl[37].addr[0] = 59; + state->Init_Ctrl[37].bit[0] = 1; + state->Init_Ctrl[37].val[0] = 0; + state->Init_Ctrl[37].addr[1] = 59; + state->Init_Ctrl[37].bit[1] = 2; + state->Init_Ctrl[37].val[1] = 0; + state->Init_Ctrl[37].addr[2] = 59; + state->Init_Ctrl[37].bit[2] = 3; + state->Init_Ctrl[37].val[2] = 0; + state->Init_Ctrl[37].addr[3] = 59; + state->Init_Ctrl[37].bit[3] = 4; + state->Init_Ctrl[37].val[3] = 0; + state->Init_Ctrl[37].addr[4] = 59; + state->Init_Ctrl[37].bit[4] = 5; + state->Init_Ctrl[37].val[4] = 0; + state->Init_Ctrl[37].addr[5] = 59; + state->Init_Ctrl[37].bit[5] = 6; + state->Init_Ctrl[37].val[5] = 0; + state->Init_Ctrl[37].addr[6] = 59; + state->Init_Ctrl[37].bit[6] = 7; + state->Init_Ctrl[37].val[6] = 0; + + state->Init_Ctrl[38].Ctrl_Num = TG_R_DIV ; + state->Init_Ctrl[38].size = 6 ; + state->Init_Ctrl[38].addr[0] = 32; + state->Init_Ctrl[38].bit[0] = 2; + state->Init_Ctrl[38].val[0] = 0; + state->Init_Ctrl[38].addr[1] = 32; + state->Init_Ctrl[38].bit[1] = 3; + state->Init_Ctrl[38].val[1] = 0; + state->Init_Ctrl[38].addr[2] = 32; + state->Init_Ctrl[38].bit[2] = 4; + state->Init_Ctrl[38].val[2] = 0; + state->Init_Ctrl[38].addr[3] = 32; + state->Init_Ctrl[38].bit[3] = 5; + state->Init_Ctrl[38].val[3] = 0; + state->Init_Ctrl[38].addr[4] = 32; + state->Init_Ctrl[38].bit[4] = 6; + state->Init_Ctrl[38].val[4] = 1; + state->Init_Ctrl[38].addr[5] = 32; + state->Init_Ctrl[38].bit[5] = 7; + state->Init_Ctrl[38].val[5] = 0; + + state->Init_Ctrl[39].Ctrl_Num = EN_CHP_LIN_B ; + state->Init_Ctrl[39].size = 1 ; + state->Init_Ctrl[39].addr[0] = 25; + state->Init_Ctrl[39].bit[0] = 3; + state->Init_Ctrl[39].val[0] = 1; + + + state->CH_Ctrl_Num = CHCTRL_NUM ; + + state->CH_Ctrl[0].Ctrl_Num = DN_POLY ; + state->CH_Ctrl[0].size = 2 ; + state->CH_Ctrl[0].addr[0] = 68; + state->CH_Ctrl[0].bit[0] = 6; + state->CH_Ctrl[0].val[0] = 1; + state->CH_Ctrl[0].addr[1] = 68; + state->CH_Ctrl[0].bit[1] = 7; + state->CH_Ctrl[0].val[1] = 1; + + state->CH_Ctrl[1].Ctrl_Num = DN_RFGAIN ; + state->CH_Ctrl[1].size = 2 ; + state->CH_Ctrl[1].addr[0] = 70; + state->CH_Ctrl[1].bit[0] = 6; + state->CH_Ctrl[1].val[0] = 1; + state->CH_Ctrl[1].addr[1] = 70; + state->CH_Ctrl[1].bit[1] = 7; + state->CH_Ctrl[1].val[1] = 0; + + state->CH_Ctrl[2].Ctrl_Num = DN_CAP_RFLPF ; + state->CH_Ctrl[2].size = 9 ; + state->CH_Ctrl[2].addr[0] = 69; + state->CH_Ctrl[2].bit[0] = 5; + state->CH_Ctrl[2].val[0] = 0; + state->CH_Ctrl[2].addr[1] = 69; + state->CH_Ctrl[2].bit[1] = 6; + state->CH_Ctrl[2].val[1] = 0; + state->CH_Ctrl[2].addr[2] = 69; + state->CH_Ctrl[2].bit[2] = 7; + state->CH_Ctrl[2].val[2] = 0; + state->CH_Ctrl[2].addr[3] = 68; + state->CH_Ctrl[2].bit[3] = 0; + state->CH_Ctrl[2].val[3] = 0; + state->CH_Ctrl[2].addr[4] = 68; + state->CH_Ctrl[2].bit[4] = 1; + state->CH_Ctrl[2].val[4] = 0; + state->CH_Ctrl[2].addr[5] = 68; + state->CH_Ctrl[2].bit[5] = 2; + state->CH_Ctrl[2].val[5] = 0; + state->CH_Ctrl[2].addr[6] = 68; + state->CH_Ctrl[2].bit[6] = 3; + state->CH_Ctrl[2].val[6] = 0; + state->CH_Ctrl[2].addr[7] = 68; + state->CH_Ctrl[2].bit[7] = 4; + state->CH_Ctrl[2].val[7] = 0; + state->CH_Ctrl[2].addr[8] = 68; + state->CH_Ctrl[2].bit[8] = 5; + state->CH_Ctrl[2].val[8] = 0; + + state->CH_Ctrl[3].Ctrl_Num = DN_EN_VHFUHFBAR ; + state->CH_Ctrl[3].size = 1 ; + state->CH_Ctrl[3].addr[0] = 70; + state->CH_Ctrl[3].bit[0] = 5; + state->CH_Ctrl[3].val[0] = 0; + + state->CH_Ctrl[4].Ctrl_Num = DN_GAIN_ADJUST ; + state->CH_Ctrl[4].size = 3 ; + state->CH_Ctrl[4].addr[0] = 73; + state->CH_Ctrl[4].bit[0] = 4; + state->CH_Ctrl[4].val[0] = 0; + state->CH_Ctrl[4].addr[1] = 73; + state->CH_Ctrl[4].bit[1] = 5; + state->CH_Ctrl[4].val[1] = 1; + state->CH_Ctrl[4].addr[2] = 73; + state->CH_Ctrl[4].bit[2] = 6; + state->CH_Ctrl[4].val[2] = 0; + + state->CH_Ctrl[5].Ctrl_Num = DN_IQTNBUF_AMP ; + state->CH_Ctrl[5].size = 4 ; + state->CH_Ctrl[5].addr[0] = 70; + state->CH_Ctrl[5].bit[0] = 0; + state->CH_Ctrl[5].val[0] = 0; + state->CH_Ctrl[5].addr[1] = 70; + state->CH_Ctrl[5].bit[1] = 1; + state->CH_Ctrl[5].val[1] = 0; + state->CH_Ctrl[5].addr[2] = 70; + state->CH_Ctrl[5].bit[2] = 2; + state->CH_Ctrl[5].val[2] = 0; + state->CH_Ctrl[5].addr[3] = 70; + state->CH_Ctrl[5].bit[3] = 3; + state->CH_Ctrl[5].val[3] = 0; + + state->CH_Ctrl[6].Ctrl_Num = DN_IQTNGNBFBIAS_BST ; + state->CH_Ctrl[6].size = 1 ; + state->CH_Ctrl[6].addr[0] = 70; + state->CH_Ctrl[6].bit[0] = 4; + state->CH_Ctrl[6].val[0] = 1; + + state->CH_Ctrl[7].Ctrl_Num = RFSYN_EN_OUTMUX ; + state->CH_Ctrl[7].size = 1 ; + state->CH_Ctrl[7].addr[0] = 111; + state->CH_Ctrl[7].bit[0] = 4; + state->CH_Ctrl[7].val[0] = 0; + + state->CH_Ctrl[8].Ctrl_Num = RFSYN_SEL_VCO_OUT ; + state->CH_Ctrl[8].size = 1 ; + state->CH_Ctrl[8].addr[0] = 111; + state->CH_Ctrl[8].bit[0] = 7; + state->CH_Ctrl[8].val[0] = 1; + + state->CH_Ctrl[9].Ctrl_Num = RFSYN_SEL_VCO_HI ; + state->CH_Ctrl[9].size = 1 ; + state->CH_Ctrl[9].addr[0] = 111; + state->CH_Ctrl[9].bit[0] = 6; + state->CH_Ctrl[9].val[0] = 1; + + state->CH_Ctrl[10].Ctrl_Num = RFSYN_SEL_DIVM ; + state->CH_Ctrl[10].size = 1 ; + state->CH_Ctrl[10].addr[0] = 111; + state->CH_Ctrl[10].bit[0] = 5; + state->CH_Ctrl[10].val[0] = 0; + + state->CH_Ctrl[11].Ctrl_Num = RFSYN_RF_DIV_BIAS ; + state->CH_Ctrl[11].size = 2 ; + state->CH_Ctrl[11].addr[0] = 110; + state->CH_Ctrl[11].bit[0] = 0; + state->CH_Ctrl[11].val[0] = 1; + state->CH_Ctrl[11].addr[1] = 110; + state->CH_Ctrl[11].bit[1] = 1; + state->CH_Ctrl[11].val[1] = 0; + + state->CH_Ctrl[12].Ctrl_Num = DN_SEL_FREQ ; + state->CH_Ctrl[12].size = 3 ; + state->CH_Ctrl[12].addr[0] = 69; + state->CH_Ctrl[12].bit[0] = 2; + state->CH_Ctrl[12].val[0] = 0; + state->CH_Ctrl[12].addr[1] = 69; + state->CH_Ctrl[12].bit[1] = 3; + state->CH_Ctrl[12].val[1] = 0; + state->CH_Ctrl[12].addr[2] = 69; + state->CH_Ctrl[12].bit[2] = 4; + state->CH_Ctrl[12].val[2] = 0; + + state->CH_Ctrl[13].Ctrl_Num = RFSYN_VCO_BIAS ; + state->CH_Ctrl[13].size = 6 ; + state->CH_Ctrl[13].addr[0] = 110; + state->CH_Ctrl[13].bit[0] = 2; + state->CH_Ctrl[13].val[0] = 0; + state->CH_Ctrl[13].addr[1] = 110; + state->CH_Ctrl[13].bit[1] = 3; + state->CH_Ctrl[13].val[1] = 0; + state->CH_Ctrl[13].addr[2] = 110; + state->CH_Ctrl[13].bit[2] = 4; + state->CH_Ctrl[13].val[2] = 0; + state->CH_Ctrl[13].addr[3] = 110; + state->CH_Ctrl[13].bit[3] = 5; + state->CH_Ctrl[13].val[3] = 0; + state->CH_Ctrl[13].addr[4] = 110; + state->CH_Ctrl[13].bit[4] = 6; + state->CH_Ctrl[13].val[4] = 0; + state->CH_Ctrl[13].addr[5] = 110; + state->CH_Ctrl[13].bit[5] = 7; + state->CH_Ctrl[13].val[5] = 1; + + state->CH_Ctrl[14].Ctrl_Num = CHCAL_INT_MOD_RF ; + state->CH_Ctrl[14].size = 7 ; + state->CH_Ctrl[14].addr[0] = 14; + state->CH_Ctrl[14].bit[0] = 0; + state->CH_Ctrl[14].val[0] = 0; + state->CH_Ctrl[14].addr[1] = 14; + state->CH_Ctrl[14].bit[1] = 1; + state->CH_Ctrl[14].val[1] = 0; + state->CH_Ctrl[14].addr[2] = 14; + state->CH_Ctrl[14].bit[2] = 2; + state->CH_Ctrl[14].val[2] = 0; + state->CH_Ctrl[14].addr[3] = 14; + state->CH_Ctrl[14].bit[3] = 3; + state->CH_Ctrl[14].val[3] = 0; + state->CH_Ctrl[14].addr[4] = 14; + state->CH_Ctrl[14].bit[4] = 4; + state->CH_Ctrl[14].val[4] = 0; + state->CH_Ctrl[14].addr[5] = 14; + state->CH_Ctrl[14].bit[5] = 5; + state->CH_Ctrl[14].val[5] = 0; + state->CH_Ctrl[14].addr[6] = 14; + state->CH_Ctrl[14].bit[6] = 6; + state->CH_Ctrl[14].val[6] = 0; + + state->CH_Ctrl[15].Ctrl_Num = CHCAL_FRAC_MOD_RF ; + state->CH_Ctrl[15].size = 18 ; + state->CH_Ctrl[15].addr[0] = 17; + state->CH_Ctrl[15].bit[0] = 6; + state->CH_Ctrl[15].val[0] = 0; + state->CH_Ctrl[15].addr[1] = 17; + state->CH_Ctrl[15].bit[1] = 7; + state->CH_Ctrl[15].val[1] = 0; + state->CH_Ctrl[15].addr[2] = 16; + state->CH_Ctrl[15].bit[2] = 0; + state->CH_Ctrl[15].val[2] = 0; + state->CH_Ctrl[15].addr[3] = 16; + state->CH_Ctrl[15].bit[3] = 1; + state->CH_Ctrl[15].val[3] = 0; + state->CH_Ctrl[15].addr[4] = 16; + state->CH_Ctrl[15].bit[4] = 2; + state->CH_Ctrl[15].val[4] = 0; + state->CH_Ctrl[15].addr[5] = 16; + state->CH_Ctrl[15].bit[5] = 3; + state->CH_Ctrl[15].val[5] = 0; + state->CH_Ctrl[15].addr[6] = 16; + state->CH_Ctrl[15].bit[6] = 4; + state->CH_Ctrl[15].val[6] = 0; + state->CH_Ctrl[15].addr[7] = 16; + state->CH_Ctrl[15].bit[7] = 5; + state->CH_Ctrl[15].val[7] = 0; + state->CH_Ctrl[15].addr[8] = 16; + state->CH_Ctrl[15].bit[8] = 6; + state->CH_Ctrl[15].val[8] = 0; + state->CH_Ctrl[15].addr[9] = 16; + state->CH_Ctrl[15].bit[9] = 7; + state->CH_Ctrl[15].val[9] = 0; + state->CH_Ctrl[15].addr[10] = 15; + state->CH_Ctrl[15].bit[10] = 0; + state->CH_Ctrl[15].val[10] = 0; + state->CH_Ctrl[15].addr[11] = 15; + state->CH_Ctrl[15].bit[11] = 1; + state->CH_Ctrl[15].val[11] = 0; + state->CH_Ctrl[15].addr[12] = 15; + state->CH_Ctrl[15].bit[12] = 2; + state->CH_Ctrl[15].val[12] = 0; + state->CH_Ctrl[15].addr[13] = 15; + state->CH_Ctrl[15].bit[13] = 3; + state->CH_Ctrl[15].val[13] = 0; + state->CH_Ctrl[15].addr[14] = 15; + state->CH_Ctrl[15].bit[14] = 4; + state->CH_Ctrl[15].val[14] = 0; + state->CH_Ctrl[15].addr[15] = 15; + state->CH_Ctrl[15].bit[15] = 5; + state->CH_Ctrl[15].val[15] = 0; + state->CH_Ctrl[15].addr[16] = 15; + state->CH_Ctrl[15].bit[16] = 6; + state->CH_Ctrl[15].val[16] = 1; + state->CH_Ctrl[15].addr[17] = 15; + state->CH_Ctrl[15].bit[17] = 7; + state->CH_Ctrl[15].val[17] = 1; + + state->CH_Ctrl[16].Ctrl_Num = RFSYN_LPF_R ; + state->CH_Ctrl[16].size = 5 ; + state->CH_Ctrl[16].addr[0] = 112; + state->CH_Ctrl[16].bit[0] = 0; + state->CH_Ctrl[16].val[0] = 0; + state->CH_Ctrl[16].addr[1] = 112; + state->CH_Ctrl[16].bit[1] = 1; + state->CH_Ctrl[16].val[1] = 0; + state->CH_Ctrl[16].addr[2] = 112; + state->CH_Ctrl[16].bit[2] = 2; + state->CH_Ctrl[16].val[2] = 0; + state->CH_Ctrl[16].addr[3] = 112; + state->CH_Ctrl[16].bit[3] = 3; + state->CH_Ctrl[16].val[3] = 0; + state->CH_Ctrl[16].addr[4] = 112; + state->CH_Ctrl[16].bit[4] = 4; + state->CH_Ctrl[16].val[4] = 1; + + state->CH_Ctrl[17].Ctrl_Num = CHCAL_EN_INT_RF ; + state->CH_Ctrl[17].size = 1 ; + state->CH_Ctrl[17].addr[0] = 14; + state->CH_Ctrl[17].bit[0] = 7; + state->CH_Ctrl[17].val[0] = 0; + + state->CH_Ctrl[18].Ctrl_Num = TG_LO_DIVVAL ; + state->CH_Ctrl[18].size = 4 ; + state->CH_Ctrl[18].addr[0] = 107; + state->CH_Ctrl[18].bit[0] = 3; + state->CH_Ctrl[18].val[0] = 0; + state->CH_Ctrl[18].addr[1] = 107; + state->CH_Ctrl[18].bit[1] = 4; + state->CH_Ctrl[18].val[1] = 0; + state->CH_Ctrl[18].addr[2] = 107; + state->CH_Ctrl[18].bit[2] = 5; + state->CH_Ctrl[18].val[2] = 0; + state->CH_Ctrl[18].addr[3] = 107; + state->CH_Ctrl[18].bit[3] = 6; + state->CH_Ctrl[18].val[3] = 0; + + state->CH_Ctrl[19].Ctrl_Num = TG_LO_SELVAL ; + state->CH_Ctrl[19].size = 3 ; + state->CH_Ctrl[19].addr[0] = 107; + state->CH_Ctrl[19].bit[0] = 7; + state->CH_Ctrl[19].val[0] = 1; + state->CH_Ctrl[19].addr[1] = 106; + state->CH_Ctrl[19].bit[1] = 0; + state->CH_Ctrl[19].val[1] = 1; + state->CH_Ctrl[19].addr[2] = 106; + state->CH_Ctrl[19].bit[2] = 1; + state->CH_Ctrl[19].val[2] = 1; + + state->CH_Ctrl[20].Ctrl_Num = TG_DIV_VAL ; + state->CH_Ctrl[20].size = 11 ; + state->CH_Ctrl[20].addr[0] = 109; + state->CH_Ctrl[20].bit[0] = 2; + state->CH_Ctrl[20].val[0] = 0; + state->CH_Ctrl[20].addr[1] = 109; + state->CH_Ctrl[20].bit[1] = 3; + state->CH_Ctrl[20].val[1] = 0; + state->CH_Ctrl[20].addr[2] = 109; + state->CH_Ctrl[20].bit[2] = 4; + state->CH_Ctrl[20].val[2] = 0; + state->CH_Ctrl[20].addr[3] = 109; + state->CH_Ctrl[20].bit[3] = 5; + state->CH_Ctrl[20].val[3] = 0; + state->CH_Ctrl[20].addr[4] = 109; + state->CH_Ctrl[20].bit[4] = 6; + state->CH_Ctrl[20].val[4] = 0; + state->CH_Ctrl[20].addr[5] = 109; + state->CH_Ctrl[20].bit[5] = 7; + state->CH_Ctrl[20].val[5] = 0; + state->CH_Ctrl[20].addr[6] = 108; + state->CH_Ctrl[20].bit[6] = 0; + state->CH_Ctrl[20].val[6] = 0; + state->CH_Ctrl[20].addr[7] = 108; + state->CH_Ctrl[20].bit[7] = 1; + state->CH_Ctrl[20].val[7] = 0; + state->CH_Ctrl[20].addr[8] = 108; + state->CH_Ctrl[20].bit[8] = 2; + state->CH_Ctrl[20].val[8] = 1; + state->CH_Ctrl[20].addr[9] = 108; + state->CH_Ctrl[20].bit[9] = 3; + state->CH_Ctrl[20].val[9] = 1; + state->CH_Ctrl[20].addr[10] = 108; + state->CH_Ctrl[20].bit[10] = 4; + state->CH_Ctrl[20].val[10] = 1; + + state->CH_Ctrl[21].Ctrl_Num = TG_VCO_BIAS ; + state->CH_Ctrl[21].size = 6 ; + state->CH_Ctrl[21].addr[0] = 106; + state->CH_Ctrl[21].bit[0] = 2; + state->CH_Ctrl[21].val[0] = 0; + state->CH_Ctrl[21].addr[1] = 106; + state->CH_Ctrl[21].bit[1] = 3; + state->CH_Ctrl[21].val[1] = 0; + state->CH_Ctrl[21].addr[2] = 106; + state->CH_Ctrl[21].bit[2] = 4; + state->CH_Ctrl[21].val[2] = 0; + state->CH_Ctrl[21].addr[3] = 106; + state->CH_Ctrl[21].bit[3] = 5; + state->CH_Ctrl[21].val[3] = 0; + state->CH_Ctrl[21].addr[4] = 106; + state->CH_Ctrl[21].bit[4] = 6; + state->CH_Ctrl[21].val[4] = 0; + state->CH_Ctrl[21].addr[5] = 106; + state->CH_Ctrl[21].bit[5] = 7; + state->CH_Ctrl[21].val[5] = 1; + + state->CH_Ctrl[22].Ctrl_Num = SEQ_EXTPOWERUP ; + state->CH_Ctrl[22].size = 1 ; + state->CH_Ctrl[22].addr[0] = 138; + state->CH_Ctrl[22].bit[0] = 4; + state->CH_Ctrl[22].val[0] = 1; + + state->CH_Ctrl[23].Ctrl_Num = OVERRIDE_2 ; + state->CH_Ctrl[23].size = 1 ; + state->CH_Ctrl[23].addr[0] = 17; + state->CH_Ctrl[23].bit[0] = 5; + state->CH_Ctrl[23].val[0] = 0; + + state->CH_Ctrl[24].Ctrl_Num = OVERRIDE_3 ; + state->CH_Ctrl[24].size = 1 ; + state->CH_Ctrl[24].addr[0] = 111; + state->CH_Ctrl[24].bit[0] = 3; + state->CH_Ctrl[24].val[0] = 0; + + state->CH_Ctrl[25].Ctrl_Num = OVERRIDE_4 ; + state->CH_Ctrl[25].size = 1 ; + state->CH_Ctrl[25].addr[0] = 112; + state->CH_Ctrl[25].bit[0] = 7; + state->CH_Ctrl[25].val[0] = 0; + + state->CH_Ctrl[26].Ctrl_Num = SEQ_FSM_PULSE ; + state->CH_Ctrl[26].size = 1 ; + state->CH_Ctrl[26].addr[0] = 136; + state->CH_Ctrl[26].bit[0] = 7; + state->CH_Ctrl[26].val[0] = 0; + + state->CH_Ctrl[27].Ctrl_Num = GPIO_4B ; + state->CH_Ctrl[27].size = 1 ; + state->CH_Ctrl[27].addr[0] = 149; + state->CH_Ctrl[27].bit[0] = 7; + state->CH_Ctrl[27].val[0] = 0; + + state->CH_Ctrl[28].Ctrl_Num = GPIO_3B ; + state->CH_Ctrl[28].size = 1 ; + state->CH_Ctrl[28].addr[0] = 149; + state->CH_Ctrl[28].bit[0] = 6; + state->CH_Ctrl[28].val[0] = 0; + + state->CH_Ctrl[29].Ctrl_Num = GPIO_4 ; + state->CH_Ctrl[29].size = 1 ; + state->CH_Ctrl[29].addr[0] = 149; + state->CH_Ctrl[29].bit[0] = 5; + state->CH_Ctrl[29].val[0] = 1; + + state->CH_Ctrl[30].Ctrl_Num = GPIO_3 ; + state->CH_Ctrl[30].size = 1 ; + state->CH_Ctrl[30].addr[0] = 149; + state->CH_Ctrl[30].bit[0] = 4; + state->CH_Ctrl[30].val[0] = 1; + + state->CH_Ctrl[31].Ctrl_Num = GPIO_1B ; + state->CH_Ctrl[31].size = 1 ; + state->CH_Ctrl[31].addr[0] = 149; + state->CH_Ctrl[31].bit[0] = 3; + state->CH_Ctrl[31].val[0] = 0; + + state->CH_Ctrl[32].Ctrl_Num = DAC_A_ENABLE ; + state->CH_Ctrl[32].size = 1 ; + state->CH_Ctrl[32].addr[0] = 93; + state->CH_Ctrl[32].bit[0] = 1; + state->CH_Ctrl[32].val[0] = 0; + + state->CH_Ctrl[33].Ctrl_Num = DAC_B_ENABLE ; + state->CH_Ctrl[33].size = 1 ; + state->CH_Ctrl[33].addr[0] = 93; + state->CH_Ctrl[33].bit[0] = 0; + state->CH_Ctrl[33].val[0] = 0; + + state->CH_Ctrl[34].Ctrl_Num = DAC_DIN_A ; + state->CH_Ctrl[34].size = 6 ; + state->CH_Ctrl[34].addr[0] = 92; + state->CH_Ctrl[34].bit[0] = 2; + state->CH_Ctrl[34].val[0] = 0; + state->CH_Ctrl[34].addr[1] = 92; + state->CH_Ctrl[34].bit[1] = 3; + state->CH_Ctrl[34].val[1] = 0; + state->CH_Ctrl[34].addr[2] = 92; + state->CH_Ctrl[34].bit[2] = 4; + state->CH_Ctrl[34].val[2] = 0; + state->CH_Ctrl[34].addr[3] = 92; + state->CH_Ctrl[34].bit[3] = 5; + state->CH_Ctrl[34].val[3] = 0; + state->CH_Ctrl[34].addr[4] = 92; + state->CH_Ctrl[34].bit[4] = 6; + state->CH_Ctrl[34].val[4] = 0; + state->CH_Ctrl[34].addr[5] = 92; + state->CH_Ctrl[34].bit[5] = 7; + state->CH_Ctrl[34].val[5] = 0; + + state->CH_Ctrl[35].Ctrl_Num = DAC_DIN_B ; + state->CH_Ctrl[35].size = 6 ; + state->CH_Ctrl[35].addr[0] = 93; + state->CH_Ctrl[35].bit[0] = 2; + state->CH_Ctrl[35].val[0] = 0; + state->CH_Ctrl[35].addr[1] = 93; + state->CH_Ctrl[35].bit[1] = 3; + state->CH_Ctrl[35].val[1] = 0; + state->CH_Ctrl[35].addr[2] = 93; + state->CH_Ctrl[35].bit[2] = 4; + state->CH_Ctrl[35].val[2] = 0; + state->CH_Ctrl[35].addr[3] = 93; + state->CH_Ctrl[35].bit[3] = 5; + state->CH_Ctrl[35].val[3] = 0; + state->CH_Ctrl[35].addr[4] = 93; + state->CH_Ctrl[35].bit[4] = 6; + state->CH_Ctrl[35].val[4] = 0; + state->CH_Ctrl[35].addr[5] = 93; + state->CH_Ctrl[35].bit[5] = 7; + state->CH_Ctrl[35].val[5] = 0; + +#ifdef _MXL_PRODUCTION + state->CH_Ctrl[36].Ctrl_Num = RFSYN_EN_DIV ; + state->CH_Ctrl[36].size = 1 ; + state->CH_Ctrl[36].addr[0] = 109; + state->CH_Ctrl[36].bit[0] = 1; + state->CH_Ctrl[36].val[0] = 1; + + state->CH_Ctrl[37].Ctrl_Num = RFSYN_DIVM ; + state->CH_Ctrl[37].size = 2 ; + state->CH_Ctrl[37].addr[0] = 112; + state->CH_Ctrl[37].bit[0] = 5; + state->CH_Ctrl[37].val[0] = 0; + state->CH_Ctrl[37].addr[1] = 112; + state->CH_Ctrl[37].bit[1] = 6; + state->CH_Ctrl[37].val[1] = 0; + + state->CH_Ctrl[38].Ctrl_Num = DN_BYPASS_AGC_I2C ; + state->CH_Ctrl[38].size = 1 ; + state->CH_Ctrl[38].addr[0] = 65; + state->CH_Ctrl[38].bit[0] = 1; + state->CH_Ctrl[38].val[0] = 0; +#endif + + return 0 ; +} + +static void InitTunerControls(struct dvb_frontend *fe) +{ + MXL5005_RegisterInit(fe); + MXL5005_ControlInit(fe); +#ifdef _MXL_INTERNAL + MXL5005_MXLControlInit(fe); +#endif +} + +static u16 MXL5005_TunerConfig(struct dvb_frontend *fe, + u8 Mode, /* 0: Analog Mode ; 1: Digital Mode */ + u8 IF_mode, /* for Analog Mode, 0: zero IF; 1: low IF */ + u32 Bandwidth, /* filter channel bandwidth (6, 7, 8) */ + u32 IF_out, /* Desired IF Out Frequency */ + u32 Fxtal, /* XTAL Frequency */ + u8 AGC_Mode, /* AGC Mode - Dual AGC: 0, Single AGC: 1 */ + u16 TOP, /* 0: Dual AGC; Value: take over point */ + u16 IF_OUT_LOAD, /* IF Out Load Resistor (200 / 300 Ohms) */ + u8 CLOCK_OUT, /* 0: turn off clk out; 1: turn on clock out */ + u8 DIV_OUT, /* 0: Div-1; 1: Div-4 */ + u8 CAPSELECT, /* 0: disable On-Chip pulling cap; 1: enable */ + u8 EN_RSSI, /* 0: disable RSSI; 1: enable RSSI */ + + /* Modulation Type; */ + /* 0 - Default; 1 - DVB-T; 2 - ATSC; 3 - QAM; 4 - Analog Cable */ + u8 Mod_Type, + + /* Tracking Filter */ + /* 0 - Default; 1 - Off; 2 - Type C; 3 - Type C-H */ + u8 TF_Type + ) +{ + struct mxl5005s_state *state = fe->tuner_priv; + u16 status = 0; + + state->Mode = Mode; + state->IF_Mode = IF_mode; + state->Chan_Bandwidth = Bandwidth; + state->IF_OUT = IF_out; + state->Fxtal = Fxtal; + state->AGC_Mode = AGC_Mode; + state->TOP = TOP; + state->IF_OUT_LOAD = IF_OUT_LOAD; + state->CLOCK_OUT = CLOCK_OUT; + state->DIV_OUT = DIV_OUT; + state->CAPSELECT = CAPSELECT; + state->EN_RSSI = EN_RSSI; + state->Mod_Type = Mod_Type; + state->TF_Type = TF_Type; + + /* Initialize all the controls and registers */ + InitTunerControls(fe); + + /* Synthesizer LO frequency calculation */ + MXL_SynthIFLO_Calc(fe); + + return status; +} + +static void MXL_SynthIFLO_Calc(struct dvb_frontend *fe) +{ + struct mxl5005s_state *state = fe->tuner_priv; + if (state->Mode == 1) /* Digital Mode */ + state->IF_LO = state->IF_OUT; + else /* Analog Mode */ { + if (state->IF_Mode == 0) /* Analog Zero IF mode */ + state->IF_LO = state->IF_OUT + 400000; + else /* Analog Low IF mode */ + state->IF_LO = state->IF_OUT + state->Chan_Bandwidth/2; + } +} + +static void MXL_SynthRFTGLO_Calc(struct dvb_frontend *fe) +{ + struct mxl5005s_state *state = fe->tuner_priv; + + if (state->Mode == 1) /* Digital Mode */ { + /* remove 20.48MHz setting for 2.6.10 */ + state->RF_LO = state->RF_IN; + /* change for 2.6.6 */ + state->TG_LO = state->RF_IN - 750000; + } else /* Analog Mode */ { + if (state->IF_Mode == 0) /* Analog Zero IF mode */ { + state->RF_LO = state->RF_IN - 400000; + state->TG_LO = state->RF_IN - 1750000; + } else /* Analog Low IF mode */ { + state->RF_LO = state->RF_IN - state->Chan_Bandwidth/2; + state->TG_LO = state->RF_IN - + state->Chan_Bandwidth + 500000; + } + } +} + +static u16 MXL_OverwriteICDefault(struct dvb_frontend *fe) +{ + u16 status = 0; + + status += MXL_ControlWrite(fe, OVERRIDE_1, 1); + status += MXL_ControlWrite(fe, OVERRIDE_2, 1); + status += MXL_ControlWrite(fe, OVERRIDE_3, 1); + status += MXL_ControlWrite(fe, OVERRIDE_4, 1); + + return status; +} + +static u16 MXL_BlockInit(struct dvb_frontend *fe) +{ + struct mxl5005s_state *state = fe->tuner_priv; + u16 status = 0; + + status += MXL_OverwriteICDefault(fe); + + /* Downconverter Control Dig Ana */ + status += MXL_ControlWrite(fe, DN_IQTN_AMP_CUT, state->Mode ? 1 : 0); + + /* Filter Control Dig Ana */ + status += MXL_ControlWrite(fe, BB_MODE, state->Mode ? 0 : 1); + status += MXL_ControlWrite(fe, BB_BUF, state->Mode ? 3 : 2); + status += MXL_ControlWrite(fe, BB_BUF_OA, state->Mode ? 1 : 0); + status += MXL_ControlWrite(fe, BB_IQSWAP, state->Mode ? 0 : 1); + status += MXL_ControlWrite(fe, BB_INITSTATE_DLPF_TUNE, 0); + + /* Initialize Low-Pass Filter */ + if (state->Mode) { /* Digital Mode */ + switch (state->Chan_Bandwidth) { + case 8000000: + status += MXL_ControlWrite(fe, BB_DLPF_BANDSEL, 0); + break; + case 7000000: + status += MXL_ControlWrite(fe, BB_DLPF_BANDSEL, 2); + break; + case 6000000: + status += MXL_ControlWrite(fe, + BB_DLPF_BANDSEL, 3); + break; + } + } else { /* Analog Mode */ + switch (state->Chan_Bandwidth) { + case 8000000: /* Low Zero */ + status += MXL_ControlWrite(fe, BB_ALPF_BANDSELECT, + (state->IF_Mode ? 0 : 3)); + break; + case 7000000: + status += MXL_ControlWrite(fe, BB_ALPF_BANDSELECT, + (state->IF_Mode ? 1 : 4)); + break; + case 6000000: + status += MXL_ControlWrite(fe, BB_ALPF_BANDSELECT, + (state->IF_Mode ? 2 : 5)); + break; + } + } + + /* Charge Pump Control Dig Ana */ + status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, state->Mode ? 5 : 8); + status += MXL_ControlWrite(fe, + RFSYN_EN_CHP_HIGAIN, state->Mode ? 1 : 1); + status += MXL_ControlWrite(fe, EN_CHP_LIN_B, state->Mode ? 0 : 0); + + /* AGC TOP Control */ + if (state->AGC_Mode == 0) /* Dual AGC */ { + status += MXL_ControlWrite(fe, AGC_IF, 15); + status += MXL_ControlWrite(fe, AGC_RF, 15); + } else /* Single AGC Mode Dig Ana */ + status += MXL_ControlWrite(fe, AGC_RF, state->Mode ? 15 : 12); + + if (state->TOP == 55) /* TOP == 5.5 */ + status += MXL_ControlWrite(fe, AGC_IF, 0x0); + + if (state->TOP == 72) /* TOP == 7.2 */ + status += MXL_ControlWrite(fe, AGC_IF, 0x1); + + if (state->TOP == 92) /* TOP == 9.2 */ + status += MXL_ControlWrite(fe, AGC_IF, 0x2); + + if (state->TOP == 110) /* TOP == 11.0 */ + status += MXL_ControlWrite(fe, AGC_IF, 0x3); + + if (state->TOP == 129) /* TOP == 12.9 */ + status += MXL_ControlWrite(fe, AGC_IF, 0x4); + + if (state->TOP == 147) /* TOP == 14.7 */ + status += MXL_ControlWrite(fe, AGC_IF, 0x5); + + if (state->TOP == 168) /* TOP == 16.8 */ + status += MXL_ControlWrite(fe, AGC_IF, 0x6); + + if (state->TOP == 194) /* TOP == 19.4 */ + status += MXL_ControlWrite(fe, AGC_IF, 0x7); + + if (state->TOP == 212) /* TOP == 21.2 */ + status += MXL_ControlWrite(fe, AGC_IF, 0x9); + + if (state->TOP == 232) /* TOP == 23.2 */ + status += MXL_ControlWrite(fe, AGC_IF, 0xA); + + if (state->TOP == 252) /* TOP == 25.2 */ + status += MXL_ControlWrite(fe, AGC_IF, 0xB); + + if (state->TOP == 271) /* TOP == 27.1 */ + status += MXL_ControlWrite(fe, AGC_IF, 0xC); + + if (state->TOP == 292) /* TOP == 29.2 */ + status += MXL_ControlWrite(fe, AGC_IF, 0xD); + + if (state->TOP == 317) /* TOP == 31.7 */ + status += MXL_ControlWrite(fe, AGC_IF, 0xE); + + if (state->TOP == 349) /* TOP == 34.9 */ + status += MXL_ControlWrite(fe, AGC_IF, 0xF); + + /* IF Synthesizer Control */ + status += MXL_IFSynthInit(fe); + + /* IF UpConverter Control */ + if (state->IF_OUT_LOAD == 200) { + status += MXL_ControlWrite(fe, DRV_RES_SEL, 6); + status += MXL_ControlWrite(fe, I_DRIVER, 2); + } + if (state->IF_OUT_LOAD == 300) { + status += MXL_ControlWrite(fe, DRV_RES_SEL, 4); + status += MXL_ControlWrite(fe, I_DRIVER, 1); + } + + /* Anti-Alias Filtering Control + * initialise Anti-Aliasing Filter + */ + if (state->Mode) { /* Digital Mode */ + if (state->IF_OUT >= 4000000UL && state->IF_OUT <= 6280000UL) { + status += MXL_ControlWrite(fe, EN_AAF, 1); + status += MXL_ControlWrite(fe, EN_3P, 1); + status += MXL_ControlWrite(fe, EN_AUX_3P, 1); + status += MXL_ControlWrite(fe, SEL_AAF_BAND, 0); + } + if ((state->IF_OUT == 36125000UL) || + (state->IF_OUT == 36150000UL)) { + status += MXL_ControlWrite(fe, EN_AAF, 1); + status += MXL_ControlWrite(fe, EN_3P, 1); + status += MXL_ControlWrite(fe, EN_AUX_3P, 1); + status += MXL_ControlWrite(fe, SEL_AAF_BAND, 1); + } + if (state->IF_OUT > 36150000UL) { + status += MXL_ControlWrite(fe, EN_AAF, 0); + status += MXL_ControlWrite(fe, EN_3P, 1); + status += MXL_ControlWrite(fe, EN_AUX_3P, 1); + status += MXL_ControlWrite(fe, SEL_AAF_BAND, 1); + } + } else { /* Analog Mode */ + if (state->IF_OUT >= 4000000UL && state->IF_OUT <= 5000000UL) { + status += MXL_ControlWrite(fe, EN_AAF, 1); + status += MXL_ControlWrite(fe, EN_3P, 1); + status += MXL_ControlWrite(fe, EN_AUX_3P, 1); + status += MXL_ControlWrite(fe, SEL_AAF_BAND, 0); + } + if (state->IF_OUT > 5000000UL) { + status += MXL_ControlWrite(fe, EN_AAF, 0); + status += MXL_ControlWrite(fe, EN_3P, 0); + status += MXL_ControlWrite(fe, EN_AUX_3P, 0); + status += MXL_ControlWrite(fe, SEL_AAF_BAND, 0); + } + } + + /* Demod Clock Out */ + if (state->CLOCK_OUT) + status += MXL_ControlWrite(fe, SEQ_ENCLK16_CLK_OUT, 1); + else + status += MXL_ControlWrite(fe, SEQ_ENCLK16_CLK_OUT, 0); + + if (state->DIV_OUT == 1) + status += MXL_ControlWrite(fe, SEQ_SEL4_16B, 1); + if (state->DIV_OUT == 0) + status += MXL_ControlWrite(fe, SEQ_SEL4_16B, 0); + + /* Crystal Control */ + if (state->CAPSELECT) + status += MXL_ControlWrite(fe, XTAL_CAPSELECT, 1); + else + status += MXL_ControlWrite(fe, XTAL_CAPSELECT, 0); + + if (state->Fxtal >= 12000000UL && state->Fxtal <= 16000000UL) + status += MXL_ControlWrite(fe, IF_SEL_DBL, 1); + if (state->Fxtal > 16000000UL && state->Fxtal <= 32000000UL) + status += MXL_ControlWrite(fe, IF_SEL_DBL, 0); + + if (state->Fxtal >= 12000000UL && state->Fxtal <= 22000000UL) + status += MXL_ControlWrite(fe, RFSYN_R_DIV, 3); + if (state->Fxtal > 22000000UL && state->Fxtal <= 32000000UL) + status += MXL_ControlWrite(fe, RFSYN_R_DIV, 0); + + /* Misc Controls */ + if (state->Mode == 0 && state->IF_Mode == 1) /* Analog LowIF mode */ + status += MXL_ControlWrite(fe, SEQ_EXTIQFSMPULSE, 0); + else + status += MXL_ControlWrite(fe, SEQ_EXTIQFSMPULSE, 1); + + /* status += MXL_ControlRead(fe, IF_DIVVAL, &IF_DIVVAL_Val); */ + + /* Set TG_R_DIV */ + status += MXL_ControlWrite(fe, TG_R_DIV, + MXL_Ceiling(state->Fxtal, 1000000)); + + /* Apply Default value to BB_INITSTATE_DLPF_TUNE */ + + /* RSSI Control */ + if (state->EN_RSSI) { + status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1); + status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1); + status += MXL_ControlWrite(fe, AGC_EN_RSSI, 1); + status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1); + + /* RSSI reference point */ + status += MXL_ControlWrite(fe, RFA_RSSI_REF, 2); + status += MXL_ControlWrite(fe, RFA_RSSI_REFH, 3); + status += MXL_ControlWrite(fe, RFA_RSSI_REFL, 1); + + /* TOP point */ + status += MXL_ControlWrite(fe, RFA_FLR, 0); + status += MXL_ControlWrite(fe, RFA_CEIL, 12); + } + + /* Modulation type bit settings + * Override the control values preset + */ + if (state->Mod_Type == MXL_DVBT) /* DVB-T Mode */ { + state->AGC_Mode = 1; /* Single AGC Mode */ + + /* Enable RSSI */ + status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1); + status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1); + status += MXL_ControlWrite(fe, AGC_EN_RSSI, 1); + status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1); + + /* RSSI reference point */ + status += MXL_ControlWrite(fe, RFA_RSSI_REF, 3); + status += MXL_ControlWrite(fe, RFA_RSSI_REFH, 5); + status += MXL_ControlWrite(fe, RFA_RSSI_REFL, 1); + + /* TOP point */ + status += MXL_ControlWrite(fe, RFA_FLR, 2); + status += MXL_ControlWrite(fe, RFA_CEIL, 13); + if (state->IF_OUT <= 6280000UL) /* Low IF */ + status += MXL_ControlWrite(fe, BB_IQSWAP, 0); + else /* High IF */ + status += MXL_ControlWrite(fe, BB_IQSWAP, 1); + + } + if (state->Mod_Type == MXL_ATSC) /* ATSC Mode */ { + state->AGC_Mode = 1; /* Single AGC Mode */ + + /* Enable RSSI */ + status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1); + status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1); + status += MXL_ControlWrite(fe, AGC_EN_RSSI, 1); + status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1); + + /* RSSI reference point */ + status += MXL_ControlWrite(fe, RFA_RSSI_REF, 2); + status += MXL_ControlWrite(fe, RFA_RSSI_REFH, 4); + status += MXL_ControlWrite(fe, RFA_RSSI_REFL, 1); + + /* TOP point */ + status += MXL_ControlWrite(fe, RFA_FLR, 2); + status += MXL_ControlWrite(fe, RFA_CEIL, 13); + status += MXL_ControlWrite(fe, BB_INITSTATE_DLPF_TUNE, 1); + /* Low Zero */ + status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 5); + + if (state->IF_OUT <= 6280000UL) /* Low IF */ + status += MXL_ControlWrite(fe, BB_IQSWAP, 0); + else /* High IF */ + status += MXL_ControlWrite(fe, BB_IQSWAP, 1); + } + if (state->Mod_Type == MXL_QAM) /* QAM Mode */ { + state->Mode = MXL_DIGITAL_MODE; + + /* state->AGC_Mode = 1; */ /* Single AGC Mode */ + + /* Disable RSSI */ /* change here for v2.6.5 */ + status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1); + status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1); + status += MXL_ControlWrite(fe, AGC_EN_RSSI, 0); + status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1); + + /* RSSI reference point */ + status += MXL_ControlWrite(fe, RFA_RSSI_REFH, 5); + status += MXL_ControlWrite(fe, RFA_RSSI_REF, 3); + status += MXL_ControlWrite(fe, RFA_RSSI_REFL, 2); + /* change here for v2.6.5 */ + status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 3); + + if (state->IF_OUT <= 6280000UL) /* Low IF */ + status += MXL_ControlWrite(fe, BB_IQSWAP, 0); + else /* High IF */ + status += MXL_ControlWrite(fe, BB_IQSWAP, 1); + status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 2); + + } + if (state->Mod_Type == MXL_ANALOG_CABLE) { + /* Analog Cable Mode */ + /* state->Mode = MXL_DIGITAL_MODE; */ + + state->AGC_Mode = 1; /* Single AGC Mode */ + + /* Disable RSSI */ + status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1); + status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1); + status += MXL_ControlWrite(fe, AGC_EN_RSSI, 0); + status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1); + /* change for 2.6.3 */ + status += MXL_ControlWrite(fe, AGC_IF, 1); + status += MXL_ControlWrite(fe, AGC_RF, 15); + status += MXL_ControlWrite(fe, BB_IQSWAP, 1); + } + + if (state->Mod_Type == MXL_ANALOG_OTA) { + /* Analog OTA Terrestrial mode add for 2.6.7 */ + /* state->Mode = MXL_ANALOG_MODE; */ + + /* Enable RSSI */ + status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1); + status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1); + status += MXL_ControlWrite(fe, AGC_EN_RSSI, 1); + status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1); + + /* RSSI reference point */ + status += MXL_ControlWrite(fe, RFA_RSSI_REFH, 5); + status += MXL_ControlWrite(fe, RFA_RSSI_REF, 3); + status += MXL_ControlWrite(fe, RFA_RSSI_REFL, 2); + status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 3); + status += MXL_ControlWrite(fe, BB_IQSWAP, 1); + } + + /* RSSI disable */ + if (state->EN_RSSI == 0) { + status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1); + status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1); + status += MXL_ControlWrite(fe, AGC_EN_RSSI, 0); + status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1); + } + + return status; +} + +static u16 MXL_IFSynthInit(struct dvb_frontend *fe) +{ + struct mxl5005s_state *state = fe->tuner_priv; + u16 status = 0 ; + u32 Fref = 0 ; + u32 Kdbl, intModVal ; + u32 fracModVal ; + Kdbl = 2 ; + + if (state->Fxtal >= 12000000UL && state->Fxtal <= 16000000UL) + Kdbl = 2 ; + if (state->Fxtal > 16000000UL && state->Fxtal <= 32000000UL) + Kdbl = 1 ; + + /* IF Synthesizer Control */ + if (state->Mode == 0 && state->IF_Mode == 1) /* Analog Low IF mode */ { + if (state->IF_LO == 41000000UL) { + status += MXL_ControlWrite(fe, IF_DIVVAL, 0x08); + status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C); + Fref = 328000000UL ; + } + if (state->IF_LO == 47000000UL) { + status += MXL_ControlWrite(fe, IF_DIVVAL, 0x08); + status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08); + Fref = 376000000UL ; + } + if (state->IF_LO == 54000000UL) { + status += MXL_ControlWrite(fe, IF_DIVVAL, 0x10); + status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C); + Fref = 324000000UL ; + } + if (state->IF_LO == 60000000UL) { + status += MXL_ControlWrite(fe, IF_DIVVAL, 0x10); + status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08); + Fref = 360000000UL ; + } + if (state->IF_LO == 39250000UL) { + status += MXL_ControlWrite(fe, IF_DIVVAL, 0x08); + status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C); + Fref = 314000000UL ; + } + if (state->IF_LO == 39650000UL) { + status += MXL_ControlWrite(fe, IF_DIVVAL, 0x08); + status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C); + Fref = 317200000UL ; + } + if (state->IF_LO == 40150000UL) { + status += MXL_ControlWrite(fe, IF_DIVVAL, 0x08); + status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C); + Fref = 321200000UL ; + } + if (state->IF_LO == 40650000UL) { + status += MXL_ControlWrite(fe, IF_DIVVAL, 0x08); + status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C); + Fref = 325200000UL ; + } + } + + if (state->Mode || (state->Mode == 0 && state->IF_Mode == 0)) { + if (state->IF_LO == 57000000UL) { + status += MXL_ControlWrite(fe, IF_DIVVAL, 0x10); + status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08); + Fref = 342000000UL ; + } + if (state->IF_LO == 44000000UL) { + status += MXL_ControlWrite(fe, IF_DIVVAL, 0x08); + status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08); + Fref = 352000000UL ; + } + if (state->IF_LO == 43750000UL) { + status += MXL_ControlWrite(fe, IF_DIVVAL, 0x08); + status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08); + Fref = 350000000UL ; + } + if (state->IF_LO == 36650000UL) { + status += MXL_ControlWrite(fe, IF_DIVVAL, 0x04); + status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08); + Fref = 366500000UL ; + } + if (state->IF_LO == 36150000UL) { + status += MXL_ControlWrite(fe, IF_DIVVAL, 0x04); + status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08); + Fref = 361500000UL ; + } + if (state->IF_LO == 36000000UL) { + status += MXL_ControlWrite(fe, IF_DIVVAL, 0x04); + status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08); + Fref = 360000000UL ; + } + if (state->IF_LO == 35250000UL) { + status += MXL_ControlWrite(fe, IF_DIVVAL, 0x04); + status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08); + Fref = 352500000UL ; + } + if (state->IF_LO == 34750000UL) { + status += MXL_ControlWrite(fe, IF_DIVVAL, 0x04); + status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08); + Fref = 347500000UL ; + } + if (state->IF_LO == 6280000UL) { + status += MXL_ControlWrite(fe, IF_DIVVAL, 0x07); + status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08); + Fref = 376800000UL ; + } + if (state->IF_LO == 5000000UL) { + status += MXL_ControlWrite(fe, IF_DIVVAL, 0x09); + status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08); + Fref = 360000000UL ; + } + if (state->IF_LO == 4500000UL) { + status += MXL_ControlWrite(fe, IF_DIVVAL, 0x06); + status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08); + Fref = 360000000UL ; + } + if (state->IF_LO == 4570000UL) { + status += MXL_ControlWrite(fe, IF_DIVVAL, 0x06); + status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08); + Fref = 365600000UL ; + } + if (state->IF_LO == 4000000UL) { + status += MXL_ControlWrite(fe, IF_DIVVAL, 0x05); + status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08); + Fref = 360000000UL ; + } + if (state->IF_LO == 57400000UL) { + status += MXL_ControlWrite(fe, IF_DIVVAL, 0x10); + status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08); + Fref = 344400000UL ; + } + if (state->IF_LO == 44400000UL) { + status += MXL_ControlWrite(fe, IF_DIVVAL, 0x08); + status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08); + Fref = 355200000UL ; + } + if (state->IF_LO == 44150000UL) { + status += MXL_ControlWrite(fe, IF_DIVVAL, 0x08); + status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08); + Fref = 353200000UL ; + } + if (state->IF_LO == 37050000UL) { + status += MXL_ControlWrite(fe, IF_DIVVAL, 0x04); + status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08); + Fref = 370500000UL ; + } + if (state->IF_LO == 36550000UL) { + status += MXL_ControlWrite(fe, IF_DIVVAL, 0x04); + status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08); + Fref = 365500000UL ; + } + if (state->IF_LO == 36125000UL) { + status += MXL_ControlWrite(fe, IF_DIVVAL, 0x04); + status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08); + Fref = 361250000UL ; + } + if (state->IF_LO == 6000000UL) { + status += MXL_ControlWrite(fe, IF_DIVVAL, 0x07); + status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08); + Fref = 360000000UL ; + } + if (state->IF_LO == 5400000UL) { + status += MXL_ControlWrite(fe, IF_DIVVAL, 0x07); + status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C); + Fref = 324000000UL ; + } + if (state->IF_LO == 5380000UL) { + status += MXL_ControlWrite(fe, IF_DIVVAL, 0x07); + status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C); + Fref = 322800000UL ; + } + if (state->IF_LO == 5200000UL) { + status += MXL_ControlWrite(fe, IF_DIVVAL, 0x09); + status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08); + Fref = 374400000UL ; + } + if (state->IF_LO == 4900000UL) { + status += MXL_ControlWrite(fe, IF_DIVVAL, 0x09); + status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08); + Fref = 352800000UL ; + } + if (state->IF_LO == 4400000UL) { + status += MXL_ControlWrite(fe, IF_DIVVAL, 0x06); + status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08); + Fref = 352000000UL ; + } + if (state->IF_LO == 4063000UL) /* add for 2.6.8 */ { + status += MXL_ControlWrite(fe, IF_DIVVAL, 0x05); + status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08); + Fref = 365670000UL ; + } + } + /* CHCAL_INT_MOD_IF */ + /* CHCAL_FRAC_MOD_IF */ + intModVal = Fref / (state->Fxtal * Kdbl/2); + status += MXL_ControlWrite(fe, CHCAL_INT_MOD_IF, intModVal); + + fracModVal = (2<<15)*(Fref/1000 - (state->Fxtal/1000 * Kdbl/2) * + intModVal); + + fracModVal = fracModVal / ((state->Fxtal * Kdbl/2)/1000); + status += MXL_ControlWrite(fe, CHCAL_FRAC_MOD_IF, fracModVal); + + return status ; +} + +static u32 MXL_GetXtalInt(u32 Xtal_Freq) +{ + if ((Xtal_Freq % 1000000) == 0) + return (Xtal_Freq / 10000); + else + return (((Xtal_Freq / 1000000) + 1)*100); +} + +static u16 MXL_TuneRF(struct dvb_frontend *fe, u32 RF_Freq) +{ + struct mxl5005s_state *state = fe->tuner_priv; + u16 status = 0; + u32 divider_val, E3, E4, E5, E5A; + u32 Fmax, Fmin, FmaxBin, FminBin; + u32 Kdbl_RF = 2; + u32 tg_divval; + u32 tg_lo; + u32 Xtal_Int; + + u32 Fref_TG; + u32 Fvco; + + Xtal_Int = MXL_GetXtalInt(state->Fxtal); + + state->RF_IN = RF_Freq; + + MXL_SynthRFTGLO_Calc(fe); + + if (state->Fxtal >= 12000000UL && state->Fxtal <= 22000000UL) + Kdbl_RF = 2; + if (state->Fxtal > 22000000 && state->Fxtal <= 32000000) + Kdbl_RF = 1; + + /* Downconverter Controls + * Look-Up Table Implementation for: + * DN_POLY + * DN_RFGAIN + * DN_CAP_RFLPF + * DN_EN_VHFUHFBAR + * DN_GAIN_ADJUST + * Change the boundary reference from RF_IN to RF_LO + */ + if (state->RF_LO < 40000000UL) + return -1; + + if (state->RF_LO >= 40000000UL && state->RF_LO <= 75000000UL) { + status += MXL_ControlWrite(fe, DN_POLY, 2); + status += MXL_ControlWrite(fe, DN_RFGAIN, 3); + status += MXL_ControlWrite(fe, DN_CAP_RFLPF, 423); + status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR, 1); + status += MXL_ControlWrite(fe, DN_GAIN_ADJUST, 1); + } + if (state->RF_LO > 75000000UL && state->RF_LO <= 100000000UL) { + status += MXL_ControlWrite(fe, DN_POLY, 3); + status += MXL_ControlWrite(fe, DN_RFGAIN, 3); + status += MXL_ControlWrite(fe, DN_CAP_RFLPF, 222); + status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR, 1); + status += MXL_ControlWrite(fe, DN_GAIN_ADJUST, 1); + } + if (state->RF_LO > 100000000UL && state->RF_LO <= 150000000UL) { + status += MXL_ControlWrite(fe, DN_POLY, 3); + status += MXL_ControlWrite(fe, DN_RFGAIN, 3); + status += MXL_ControlWrite(fe, DN_CAP_RFLPF, 147); + status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR, 1); + status += MXL_ControlWrite(fe, DN_GAIN_ADJUST, 2); + } + if (state->RF_LO > 150000000UL && state->RF_LO <= 200000000UL) { + status += MXL_ControlWrite(fe, DN_POLY, 3); + status += MXL_ControlWrite(fe, DN_RFGAIN, 3); + status += MXL_ControlWrite(fe, DN_CAP_RFLPF, 9); + status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR, 1); + status += MXL_ControlWrite(fe, DN_GAIN_ADJUST, 2); + } + if (state->RF_LO > 200000000UL && state->RF_LO <= 300000000UL) { + status += MXL_ControlWrite(fe, DN_POLY, 3); + status += MXL_ControlWrite(fe, DN_RFGAIN, 3); + status += MXL_ControlWrite(fe, DN_CAP_RFLPF, 0); + status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR, 1); + status += MXL_ControlWrite(fe, DN_GAIN_ADJUST, 3); + } + if (state->RF_LO > 300000000UL && state->RF_LO <= 650000000UL) { + status += MXL_ControlWrite(fe, DN_POLY, 3); + status += MXL_ControlWrite(fe, DN_RFGAIN, 1); + status += MXL_ControlWrite(fe, DN_CAP_RFLPF, 0); + status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR, 0); + status += MXL_ControlWrite(fe, DN_GAIN_ADJUST, 3); + } + if (state->RF_LO > 650000000UL && state->RF_LO <= 900000000UL) { + status += MXL_ControlWrite(fe, DN_POLY, 3); + status += MXL_ControlWrite(fe, DN_RFGAIN, 2); + status += MXL_ControlWrite(fe, DN_CAP_RFLPF, 0); + status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR, 0); + status += MXL_ControlWrite(fe, DN_GAIN_ADJUST, 3); + } + if (state->RF_LO > 900000000UL) + return -1; + + /* DN_IQTNBUF_AMP */ + /* DN_IQTNGNBFBIAS_BST */ + if (state->RF_LO >= 40000000UL && state->RF_LO <= 75000000UL) { + status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1); + status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0); + } + if (state->RF_LO > 75000000UL && state->RF_LO <= 100000000UL) { + status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1); + status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0); + } + if (state->RF_LO > 100000000UL && state->RF_LO <= 150000000UL) { + status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1); + status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0); + } + if (state->RF_LO > 150000000UL && state->RF_LO <= 200000000UL) { + status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1); + status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0); + } + if (state->RF_LO > 200000000UL && state->RF_LO <= 300000000UL) { + status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1); + status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0); + } + if (state->RF_LO > 300000000UL && state->RF_LO <= 400000000UL) { + status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1); + status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0); + } + if (state->RF_LO > 400000000UL && state->RF_LO <= 450000000UL) { + status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1); + status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0); + } + if (state->RF_LO > 450000000UL && state->RF_LO <= 500000000UL) { + status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1); + status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0); + } + if (state->RF_LO > 500000000UL && state->RF_LO <= 550000000UL) { + status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1); + status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0); + } + if (state->RF_LO > 550000000UL && state->RF_LO <= 600000000UL) { + status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1); + status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0); + } + if (state->RF_LO > 600000000UL && state->RF_LO <= 650000000UL) { + status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1); + status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0); + } + if (state->RF_LO > 650000000UL && state->RF_LO <= 700000000UL) { + status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1); + status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0); + } + if (state->RF_LO > 700000000UL && state->RF_LO <= 750000000UL) { + status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1); + status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0); + } + if (state->RF_LO > 750000000UL && state->RF_LO <= 800000000UL) { + status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1); + status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0); + } + if (state->RF_LO > 800000000UL && state->RF_LO <= 850000000UL) { + status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 10); + status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 1); + } + if (state->RF_LO > 850000000UL && state->RF_LO <= 900000000UL) { + status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 10); + status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 1); + } + + /* + * Set RF Synth and LO Path Control + * + * Look-Up table implementation for: + * RFSYN_EN_OUTMUX + * RFSYN_SEL_VCO_OUT + * RFSYN_SEL_VCO_HI + * RFSYN_SEL_DIVM + * RFSYN_RF_DIV_BIAS + * DN_SEL_FREQ + * + * Set divider_val, Fmax, Fmix to use in Equations + */ + FminBin = 28000000UL ; + FmaxBin = 42500000UL ; + if (state->RF_LO >= 40000000UL && state->RF_LO <= FmaxBin) { + status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 1); + status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 0); + status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0); + status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0); + status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1); + status += MXL_ControlWrite(fe, DN_SEL_FREQ, 1); + divider_val = 64 ; + Fmax = FmaxBin ; + Fmin = FminBin ; + } + FminBin = 42500000UL ; + FmaxBin = 56000000UL ; + if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) { + status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 1); + status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 0); + status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1); + status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0); + status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1); + status += MXL_ControlWrite(fe, DN_SEL_FREQ, 1); + divider_val = 64 ; + Fmax = FmaxBin ; + Fmin = FminBin ; + } + FminBin = 56000000UL ; + FmaxBin = 85000000UL ; + if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) { + status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0); + status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1); + status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0); + status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0); + status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1); + status += MXL_ControlWrite(fe, DN_SEL_FREQ, 1); + divider_val = 32 ; + Fmax = FmaxBin ; + Fmin = FminBin ; + } + FminBin = 85000000UL ; + FmaxBin = 112000000UL ; + if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) { + status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0); + status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1); + status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1); + status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0); + status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1); + status += MXL_ControlWrite(fe, DN_SEL_FREQ, 1); + divider_val = 32 ; + Fmax = FmaxBin ; + Fmin = FminBin ; + } + FminBin = 112000000UL ; + FmaxBin = 170000000UL ; + if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) { + status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0); + status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1); + status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0); + status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0); + status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1); + status += MXL_ControlWrite(fe, DN_SEL_FREQ, 2); + divider_val = 16 ; + Fmax = FmaxBin ; + Fmin = FminBin ; + } + FminBin = 170000000UL ; + FmaxBin = 225000000UL ; + if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) { + status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0); + status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1); + status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1); + status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0); + status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1); + status += MXL_ControlWrite(fe, DN_SEL_FREQ, 2); + divider_val = 16 ; + Fmax = FmaxBin ; + Fmin = FminBin ; + } + FminBin = 225000000UL ; + FmaxBin = 300000000UL ; + if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) { + status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0); + status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1); + status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0); + status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0); + status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1); + status += MXL_ControlWrite(fe, DN_SEL_FREQ, 4); + divider_val = 8 ; + Fmax = 340000000UL ; + Fmin = FminBin ; + } + FminBin = 300000000UL ; + FmaxBin = 340000000UL ; + if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) { + status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 1); + status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 0); + status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0); + status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0); + status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1); + status += MXL_ControlWrite(fe, DN_SEL_FREQ, 0); + divider_val = 8 ; + Fmax = FmaxBin ; + Fmin = 225000000UL ; + } + FminBin = 340000000UL ; + FmaxBin = 450000000UL ; + if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) { + status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 1); + status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 0); + status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1); + status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0); + status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 2); + status += MXL_ControlWrite(fe, DN_SEL_FREQ, 0); + divider_val = 8 ; + Fmax = FmaxBin ; + Fmin = FminBin ; + } + FminBin = 450000000UL ; + FmaxBin = 680000000UL ; + if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) { + status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0); + status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1); + status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0); + status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 1); + status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1); + status += MXL_ControlWrite(fe, DN_SEL_FREQ, 0); + divider_val = 4 ; + Fmax = FmaxBin ; + Fmin = FminBin ; + } + FminBin = 680000000UL ; + FmaxBin = 900000000UL ; + if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) { + status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0); + status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1); + status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1); + status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 1); + status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1); + status += MXL_ControlWrite(fe, DN_SEL_FREQ, 0); + divider_val = 4 ; + Fmax = FmaxBin ; + Fmin = FminBin ; + } + + /* CHCAL_INT_MOD_RF + * CHCAL_FRAC_MOD_RF + * RFSYN_LPF_R + * CHCAL_EN_INT_RF + */ + /* Equation E3 RFSYN_VCO_BIAS */ + E3 = (((Fmax-state->RF_LO)/1000)*32)/((Fmax-Fmin)/1000) + 8 ; + status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, E3); + + /* Equation E4 CHCAL_INT_MOD_RF */ + E4 = (state->RF_LO*divider_val/1000)/(2*state->Fxtal*Kdbl_RF/1000); + MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, E4); + + /* Equation E5 CHCAL_FRAC_MOD_RF CHCAL_EN_INT_RF */ + E5 = ((2<<17)*(state->RF_LO/10000*divider_val - + (E4*(2*state->Fxtal*Kdbl_RF)/10000))) / + (2*state->Fxtal*Kdbl_RF/10000); + + status += MXL_ControlWrite(fe, CHCAL_FRAC_MOD_RF, E5); + + /* Equation E5A RFSYN_LPF_R */ + E5A = (((Fmax - state->RF_LO)/1000)*4/((Fmax-Fmin)/1000)) + 1 ; + status += MXL_ControlWrite(fe, RFSYN_LPF_R, E5A); + + /* Euqation E5B CHCAL_EN_INIT_RF */ + status += MXL_ControlWrite(fe, CHCAL_EN_INT_RF, ((E5 == 0) ? 1 : 0)); + /*if (E5 == 0) + * status += MXL_ControlWrite(fe, CHCAL_EN_INT_RF, 1); + *else + * status += MXL_ControlWrite(fe, CHCAL_FRAC_MOD_RF, E5); + */ + + /* + * Set TG Synth + * + * Look-Up table implementation for: + * TG_LO_DIVVAL + * TG_LO_SELVAL + * + * Set divider_val, Fmax, Fmix to use in Equations + */ + if (state->TG_LO < 33000000UL) + return -1; + + FminBin = 33000000UL ; + FmaxBin = 50000000UL ; + if (state->TG_LO >= FminBin && state->TG_LO <= FmaxBin) { + status += MXL_ControlWrite(fe, TG_LO_DIVVAL, 0x6); + status += MXL_ControlWrite(fe, TG_LO_SELVAL, 0x0); + divider_val = 36 ; + Fmax = FmaxBin ; + Fmin = FminBin ; + } + FminBin = 50000000UL ; + FmaxBin = 67000000UL ; + if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) { + status += MXL_ControlWrite(fe, TG_LO_DIVVAL, 0x1); + status += MXL_ControlWrite(fe, TG_LO_SELVAL, 0x0); + divider_val = 24 ; + Fmax = FmaxBin ; + Fmin = FminBin ; + } + FminBin = 67000000UL ; + FmaxBin = 100000000UL ; + if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) { + status += MXL_ControlWrite(fe, TG_LO_DIVVAL, 0xC); + status += MXL_ControlWrite(fe, TG_LO_SELVAL, 0x2); + divider_val = 18 ; + Fmax = FmaxBin ; + Fmin = FminBin ; + } + FminBin = 100000000UL ; + FmaxBin = 150000000UL ; + if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) { + status += MXL_ControlWrite(fe, TG_LO_DIVVAL, 0x8); + status += MXL_ControlWrite(fe, TG_LO_SELVAL, 0x2); + divider_val = 12 ; + Fmax = FmaxBin ; + Fmin = FminBin ; + } + FminBin = 150000000UL ; + FmaxBin = 200000000UL ; + if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) { + status += MXL_ControlWrite(fe, TG_LO_DIVVAL, 0x0); + status += MXL_ControlWrite(fe, TG_LO_SELVAL, 0x2); + divider_val = 8 ; + Fmax = FmaxBin ; + Fmin = FminBin ; + } + FminBin = 200000000UL ; + FmaxBin = 300000000UL ; + if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) { + status += MXL_ControlWrite(fe, TG_LO_DIVVAL, 0x8); + status += MXL_ControlWrite(fe, TG_LO_SELVAL, 0x3); + divider_val = 6 ; + Fmax = FmaxBin ; + Fmin = FminBin ; + } + FminBin = 300000000UL ; + FmaxBin = 400000000UL ; + if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) { + status += MXL_ControlWrite(fe, TG_LO_DIVVAL, 0x0); + status += MXL_ControlWrite(fe, TG_LO_SELVAL, 0x3); + divider_val = 4 ; + Fmax = FmaxBin ; + Fmin = FminBin ; + } + FminBin = 400000000UL ; + FmaxBin = 600000000UL ; + if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) { + status += MXL_ControlWrite(fe, TG_LO_DIVVAL, 0x8); + status += MXL_ControlWrite(fe, TG_LO_SELVAL, 0x7); + divider_val = 3 ; + Fmax = FmaxBin ; + Fmin = FminBin ; + } + FminBin = 600000000UL ; + FmaxBin = 900000000UL ; + if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) { + status += MXL_ControlWrite(fe, TG_LO_DIVVAL, 0x0); + status += MXL_ControlWrite(fe, TG_LO_SELVAL, 0x7); + divider_val = 2 ; + Fmax = FmaxBin ; + Fmin = FminBin ; + } + + /* TG_DIV_VAL */ + tg_divval = (state->TG_LO*divider_val/100000) * + (MXL_Ceiling(state->Fxtal, 1000000) * 100) / + (state->Fxtal/1000); + + status += MXL_ControlWrite(fe, TG_DIV_VAL, tg_divval); + + if (state->TG_LO > 600000000UL) + status += MXL_ControlWrite(fe, TG_DIV_VAL, tg_divval + 1); + + Fmax = 1800000000UL ; + Fmin = 1200000000UL ; + + /* prevent overflow of 32 bit unsigned integer, use + * following equation. Edit for v2.6.4 + */ + /* Fref_TF = Fref_TG * 1000 */ + Fref_TG = (state->Fxtal/1000) / MXL_Ceiling(state->Fxtal, 1000000); + + /* Fvco = Fvco/10 */ + Fvco = (state->TG_LO/10000) * divider_val * Fref_TG; + + tg_lo = (((Fmax/10 - Fvco)/100)*32) / ((Fmax-Fmin)/1000)+8; + + /* below equation is same as above but much harder to debug. + * tg_lo = ( ((Fmax/10000 * Xtal_Int)/100) - + * ((state->TG_LO/10000)*divider_val * + * (state->Fxtal/10000)/100) )*32/((Fmax-Fmin)/10000 * + * Xtal_Int/100) + 8; + */ + + status += MXL_ControlWrite(fe, TG_VCO_BIAS , tg_lo); + + /* add for 2.6.5 Special setting for QAM */ + if (state->Mod_Type == MXL_QAM) { + if (state->RF_IN < 680000000) + status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 3); + else + status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 2); + } + + /* Off Chip Tracking Filter Control */ + if (state->TF_Type == MXL_TF_OFF) { + /* Tracking Filter Off State; turn off all the banks */ + status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0); + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0); + status += MXL_SetGPIO(fe, 3, 1); /* Bank1 Off */ + status += MXL_SetGPIO(fe, 1, 1); /* Bank2 Off */ + status += MXL_SetGPIO(fe, 4, 1); /* Bank3 Off */ + } + + if (state->TF_Type == MXL_TF_C) /* Tracking Filter type C */ { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1); + status += MXL_ControlWrite(fe, DAC_DIN_A, 0); + + if (state->RF_IN >= 43000000 && state->RF_IN < 150000000) { + status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0); + status += MXL_ControlWrite(fe, DAC_DIN_B, 0); + status += MXL_SetGPIO(fe, 3, 0); + status += MXL_SetGPIO(fe, 1, 1); + status += MXL_SetGPIO(fe, 4, 1); + } + if (state->RF_IN >= 150000000 && state->RF_IN < 280000000) { + status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0); + status += MXL_ControlWrite(fe, DAC_DIN_B, 0); + status += MXL_SetGPIO(fe, 3, 1); + status += MXL_SetGPIO(fe, 1, 0); + status += MXL_SetGPIO(fe, 4, 1); + } + if (state->RF_IN >= 280000000 && state->RF_IN < 360000000) { + status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0); + status += MXL_ControlWrite(fe, DAC_DIN_B, 0); + status += MXL_SetGPIO(fe, 3, 1); + status += MXL_SetGPIO(fe, 1, 0); + status += MXL_SetGPIO(fe, 4, 0); + } + if (state->RF_IN >= 360000000 && state->RF_IN < 560000000) { + status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0); + status += MXL_ControlWrite(fe, DAC_DIN_B, 0); + status += MXL_SetGPIO(fe, 3, 1); + status += MXL_SetGPIO(fe, 1, 1); + status += MXL_SetGPIO(fe, 4, 0); + } + if (state->RF_IN >= 560000000 && state->RF_IN < 580000000) { + status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1); + status += MXL_ControlWrite(fe, DAC_DIN_B, 29); + status += MXL_SetGPIO(fe, 3, 1); + status += MXL_SetGPIO(fe, 1, 1); + status += MXL_SetGPIO(fe, 4, 0); + } + if (state->RF_IN >= 580000000 && state->RF_IN < 630000000) { + status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1); + status += MXL_ControlWrite(fe, DAC_DIN_B, 0); + status += MXL_SetGPIO(fe, 3, 1); + status += MXL_SetGPIO(fe, 1, 1); + status += MXL_SetGPIO(fe, 4, 0); + } + if (state->RF_IN >= 630000000 && state->RF_IN < 700000000) { + status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1); + status += MXL_ControlWrite(fe, DAC_DIN_B, 16); + status += MXL_SetGPIO(fe, 3, 1); + status += MXL_SetGPIO(fe, 1, 1); + status += MXL_SetGPIO(fe, 4, 1); + } + if (state->RF_IN >= 700000000 && state->RF_IN < 760000000) { + status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1); + status += MXL_ControlWrite(fe, DAC_DIN_B, 7); + status += MXL_SetGPIO(fe, 3, 1); + status += MXL_SetGPIO(fe, 1, 1); + status += MXL_SetGPIO(fe, 4, 1); + } + if (state->RF_IN >= 760000000 && state->RF_IN <= 900000000) { + status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1); + status += MXL_ControlWrite(fe, DAC_DIN_B, 0); + status += MXL_SetGPIO(fe, 3, 1); + status += MXL_SetGPIO(fe, 1, 1); + status += MXL_SetGPIO(fe, 4, 1); + } + } + + if (state->TF_Type == MXL_TF_C_H) { + + /* Tracking Filter type C-H for Hauppauge only */ + status += MXL_ControlWrite(fe, DAC_DIN_A, 0); + + if (state->RF_IN >= 43000000 && state->RF_IN < 150000000) { + status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0); + status += MXL_SetGPIO(fe, 4, 0); + status += MXL_SetGPIO(fe, 3, 1); + status += MXL_SetGPIO(fe, 1, 1); + } + if (state->RF_IN >= 150000000 && state->RF_IN < 280000000) { + status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 3, 0); + status += MXL_SetGPIO(fe, 1, 1); + } + if (state->RF_IN >= 280000000 && state->RF_IN < 360000000) { + status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 3, 0); + status += MXL_SetGPIO(fe, 1, 0); + } + if (state->RF_IN >= 360000000 && state->RF_IN < 560000000) { + status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 3, 1); + status += MXL_SetGPIO(fe, 1, 0); + } + if (state->RF_IN >= 560000000 && state->RF_IN < 580000000) { + status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 3, 1); + status += MXL_SetGPIO(fe, 1, 0); + } + if (state->RF_IN >= 580000000 && state->RF_IN < 630000000) { + status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 3, 1); + status += MXL_SetGPIO(fe, 1, 0); + } + if (state->RF_IN >= 630000000 && state->RF_IN < 700000000) { + status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 3, 1); + status += MXL_SetGPIO(fe, 1, 1); + } + if (state->RF_IN >= 700000000 && state->RF_IN < 760000000) { + status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 3, 1); + status += MXL_SetGPIO(fe, 1, 1); + } + if (state->RF_IN >= 760000000 && state->RF_IN <= 900000000) { + status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 3, 1); + status += MXL_SetGPIO(fe, 1, 1); + } + } + + if (state->TF_Type == MXL_TF_D) { /* Tracking Filter type D */ + + status += MXL_ControlWrite(fe, DAC_DIN_B, 0); + + if (state->RF_IN >= 43000000 && state->RF_IN < 174000000) { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0); + status += MXL_SetGPIO(fe, 4, 0); + status += MXL_SetGPIO(fe, 1, 1); + status += MXL_SetGPIO(fe, 3, 1); + } + if (state->RF_IN >= 174000000 && state->RF_IN < 250000000) { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0); + status += MXL_SetGPIO(fe, 4, 0); + status += MXL_SetGPIO(fe, 1, 0); + status += MXL_SetGPIO(fe, 3, 1); + } + if (state->RF_IN >= 250000000 && state->RF_IN < 310000000) { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 1, 0); + status += MXL_SetGPIO(fe, 3, 1); + } + if (state->RF_IN >= 310000000 && state->RF_IN < 360000000) { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 1, 0); + status += MXL_SetGPIO(fe, 3, 0); + } + if (state->RF_IN >= 360000000 && state->RF_IN < 470000000) { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 1, 1); + status += MXL_SetGPIO(fe, 3, 0); + } + if (state->RF_IN >= 470000000 && state->RF_IN < 640000000) { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 1, 1); + status += MXL_SetGPIO(fe, 3, 0); + } + if (state->RF_IN >= 640000000 && state->RF_IN <= 900000000) { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 1, 1); + status += MXL_SetGPIO(fe, 3, 1); + } + } + + if (state->TF_Type == MXL_TF_D_L) { + + /* Tracking Filter type D-L for Lumanate ONLY change 2.6.3 */ + status += MXL_ControlWrite(fe, DAC_DIN_A, 0); + + /* if UHF and terrestrial => Turn off Tracking Filter */ + if (state->RF_IN >= 471000000 && + (state->RF_IN - 471000000)%6000000 != 0) { + /* Turn off all the banks */ + status += MXL_SetGPIO(fe, 3, 1); + status += MXL_SetGPIO(fe, 1, 1); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0); + status += MXL_ControlWrite(fe, AGC_IF, 10); + } else { + /* if VHF or cable => Turn on Tracking Filter */ + if (state->RF_IN >= 43000000 && + state->RF_IN < 140000000) { + + status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 1, 1); + status += MXL_SetGPIO(fe, 3, 0); + } + if (state->RF_IN >= 140000000 && + state->RF_IN < 240000000) { + status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 1, 0); + status += MXL_SetGPIO(fe, 3, 0); + } + if (state->RF_IN >= 240000000 && + state->RF_IN < 340000000) { + status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0); + status += MXL_SetGPIO(fe, 4, 0); + status += MXL_SetGPIO(fe, 1, 1); + status += MXL_SetGPIO(fe, 3, 0); + } + if (state->RF_IN >= 340000000 && + state->RF_IN < 430000000) { + status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0); + status += MXL_SetGPIO(fe, 4, 0); + status += MXL_SetGPIO(fe, 1, 0); + status += MXL_SetGPIO(fe, 3, 1); + } + if (state->RF_IN >= 430000000 && + state->RF_IN < 470000000) { + status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 1, 0); + status += MXL_SetGPIO(fe, 3, 1); + } + if (state->RF_IN >= 470000000 && + state->RF_IN < 570000000) { + status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1); + status += MXL_SetGPIO(fe, 4, 0); + status += MXL_SetGPIO(fe, 1, 0); + status += MXL_SetGPIO(fe, 3, 1); + } + if (state->RF_IN >= 570000000 && + state->RF_IN < 620000000) { + status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0); + status += MXL_SetGPIO(fe, 4, 0); + status += MXL_SetGPIO(fe, 1, 1); + status += MXL_SetGPIO(fe, 3, 1); + } + if (state->RF_IN >= 620000000 && + state->RF_IN < 760000000) { + status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1); + status += MXL_SetGPIO(fe, 4, 0); + status += MXL_SetGPIO(fe, 1, 1); + status += MXL_SetGPIO(fe, 3, 1); + } + if (state->RF_IN >= 760000000 && + state->RF_IN <= 900000000) { + status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 1, 1); + status += MXL_SetGPIO(fe, 3, 1); + } + } + } + + if (state->TF_Type == MXL_TF_E) /* Tracking Filter type E */ { + + status += MXL_ControlWrite(fe, DAC_DIN_B, 0); + + if (state->RF_IN >= 43000000 && state->RF_IN < 174000000) { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0); + status += MXL_SetGPIO(fe, 4, 0); + status += MXL_SetGPIO(fe, 1, 1); + status += MXL_SetGPIO(fe, 3, 1); + } + if (state->RF_IN >= 174000000 && state->RF_IN < 250000000) { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0); + status += MXL_SetGPIO(fe, 4, 0); + status += MXL_SetGPIO(fe, 1, 0); + status += MXL_SetGPIO(fe, 3, 1); + } + if (state->RF_IN >= 250000000 && state->RF_IN < 310000000) { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 1, 0); + status += MXL_SetGPIO(fe, 3, 1); + } + if (state->RF_IN >= 310000000 && state->RF_IN < 360000000) { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 1, 0); + status += MXL_SetGPIO(fe, 3, 0); + } + if (state->RF_IN >= 360000000 && state->RF_IN < 470000000) { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 1, 1); + status += MXL_SetGPIO(fe, 3, 0); + } + if (state->RF_IN >= 470000000 && state->RF_IN < 640000000) { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 1, 1); + status += MXL_SetGPIO(fe, 3, 0); + } + if (state->RF_IN >= 640000000 && state->RF_IN <= 900000000) { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 1, 1); + status += MXL_SetGPIO(fe, 3, 1); + } + } + + if (state->TF_Type == MXL_TF_F) { + + /* Tracking Filter type F */ + status += MXL_ControlWrite(fe, DAC_DIN_B, 0); + + if (state->RF_IN >= 43000000 && state->RF_IN < 160000000) { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0); + status += MXL_SetGPIO(fe, 4, 0); + status += MXL_SetGPIO(fe, 1, 1); + status += MXL_SetGPIO(fe, 3, 1); + } + if (state->RF_IN >= 160000000 && state->RF_IN < 210000000) { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0); + status += MXL_SetGPIO(fe, 4, 0); + status += MXL_SetGPIO(fe, 1, 0); + status += MXL_SetGPIO(fe, 3, 1); + } + if (state->RF_IN >= 210000000 && state->RF_IN < 300000000) { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 1, 0); + status += MXL_SetGPIO(fe, 3, 1); + } + if (state->RF_IN >= 300000000 && state->RF_IN < 390000000) { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 1, 0); + status += MXL_SetGPIO(fe, 3, 0); + } + if (state->RF_IN >= 390000000 && state->RF_IN < 515000000) { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 1, 1); + status += MXL_SetGPIO(fe, 3, 0); + } + if (state->RF_IN >= 515000000 && state->RF_IN < 650000000) { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 1, 1); + status += MXL_SetGPIO(fe, 3, 0); + } + if (state->RF_IN >= 650000000 && state->RF_IN <= 900000000) { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 1, 1); + status += MXL_SetGPIO(fe, 3, 1); + } + } + + if (state->TF_Type == MXL_TF_E_2) { + + /* Tracking Filter type E_2 */ + status += MXL_ControlWrite(fe, DAC_DIN_B, 0); + + if (state->RF_IN >= 43000000 && state->RF_IN < 174000000) { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0); + status += MXL_SetGPIO(fe, 4, 0); + status += MXL_SetGPIO(fe, 1, 1); + status += MXL_SetGPIO(fe, 3, 1); + } + if (state->RF_IN >= 174000000 && state->RF_IN < 250000000) { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0); + status += MXL_SetGPIO(fe, 4, 0); + status += MXL_SetGPIO(fe, 1, 0); + status += MXL_SetGPIO(fe, 3, 1); + } + if (state->RF_IN >= 250000000 && state->RF_IN < 350000000) { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 1, 0); + status += MXL_SetGPIO(fe, 3, 1); + } + if (state->RF_IN >= 350000000 && state->RF_IN < 400000000) { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 1, 0); + status += MXL_SetGPIO(fe, 3, 0); + } + if (state->RF_IN >= 400000000 && state->RF_IN < 570000000) { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 1, 1); + status += MXL_SetGPIO(fe, 3, 0); + } + if (state->RF_IN >= 570000000 && state->RF_IN < 770000000) { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 1, 1); + status += MXL_SetGPIO(fe, 3, 0); + } + if (state->RF_IN >= 770000000 && state->RF_IN <= 900000000) { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 1, 1); + status += MXL_SetGPIO(fe, 3, 1); + } + } + + if (state->TF_Type == MXL_TF_G) { + + /* Tracking Filter type G add for v2.6.8 */ + status += MXL_ControlWrite(fe, DAC_DIN_B, 0); + + if (state->RF_IN >= 50000000 && state->RF_IN < 190000000) { + + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0); + status += MXL_SetGPIO(fe, 4, 0); + status += MXL_SetGPIO(fe, 1, 1); + status += MXL_SetGPIO(fe, 3, 1); + } + if (state->RF_IN >= 190000000 && state->RF_IN < 280000000) { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0); + status += MXL_SetGPIO(fe, 4, 0); + status += MXL_SetGPIO(fe, 1, 0); + status += MXL_SetGPIO(fe, 3, 1); + } + if (state->RF_IN >= 280000000 && state->RF_IN < 350000000) { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 1, 0); + status += MXL_SetGPIO(fe, 3, 1); + } + if (state->RF_IN >= 350000000 && state->RF_IN < 400000000) { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 1, 0); + status += MXL_SetGPIO(fe, 3, 0); + } + if (state->RF_IN >= 400000000 && state->RF_IN < 470000000) { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 1, 0); + status += MXL_SetGPIO(fe, 3, 1); + } + if (state->RF_IN >= 470000000 && state->RF_IN < 640000000) { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 1, 1); + status += MXL_SetGPIO(fe, 3, 0); + } + if (state->RF_IN >= 640000000 && state->RF_IN < 820000000) { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 1, 1); + status += MXL_SetGPIO(fe, 3, 0); + } + if (state->RF_IN >= 820000000 && state->RF_IN <= 900000000) { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 1, 1); + status += MXL_SetGPIO(fe, 3, 1); + } + } + + if (state->TF_Type == MXL_TF_E_NA) { + + /* Tracking Filter type E-NA for Empia ONLY change for 2.6.8 */ + status += MXL_ControlWrite(fe, DAC_DIN_B, 0); + + /* if UHF and terrestrial=> Turn off Tracking Filter */ + if (state->RF_IN >= 471000000 && + (state->RF_IN - 471000000)%6000000 != 0) { + + /* Turn off all the banks */ + status += MXL_SetGPIO(fe, 3, 1); + status += MXL_SetGPIO(fe, 1, 1); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0); + + /* 2.6.12 Turn on RSSI */ + status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1); + status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1); + status += MXL_ControlWrite(fe, AGC_EN_RSSI, 1); + status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1); + + /* RSSI reference point */ + status += MXL_ControlWrite(fe, RFA_RSSI_REFH, 5); + status += MXL_ControlWrite(fe, RFA_RSSI_REF, 3); + status += MXL_ControlWrite(fe, RFA_RSSI_REFL, 2); + + /* following parameter is from analog OTA mode, + * can be change to seek better performance */ + status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 3); + } else { + /* if VHF or Cable => Turn on Tracking Filter */ + + /* 2.6.12 Turn off RSSI */ + status += MXL_ControlWrite(fe, AGC_EN_RSSI, 0); + + /* change back from above condition */ + status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 5); + + + if (state->RF_IN >= 43000000 && state->RF_IN < 174000000) { + + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0); + status += MXL_SetGPIO(fe, 4, 0); + status += MXL_SetGPIO(fe, 1, 1); + status += MXL_SetGPIO(fe, 3, 1); + } + if (state->RF_IN >= 174000000 && state->RF_IN < 250000000) { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0); + status += MXL_SetGPIO(fe, 4, 0); + status += MXL_SetGPIO(fe, 1, 0); + status += MXL_SetGPIO(fe, 3, 1); + } + if (state->RF_IN >= 250000000 && state->RF_IN < 350000000) { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 1, 0); + status += MXL_SetGPIO(fe, 3, 1); + } + if (state->RF_IN >= 350000000 && state->RF_IN < 400000000) { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 1, 0); + status += MXL_SetGPIO(fe, 3, 0); + } + if (state->RF_IN >= 400000000 && state->RF_IN < 570000000) { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 1, 1); + status += MXL_SetGPIO(fe, 3, 0); + } + if (state->RF_IN >= 570000000 && state->RF_IN < 770000000) { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 1, 1); + status += MXL_SetGPIO(fe, 3, 0); + } + if (state->RF_IN >= 770000000 && state->RF_IN <= 900000000) { + status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1); + status += MXL_SetGPIO(fe, 4, 1); + status += MXL_SetGPIO(fe, 1, 1); + status += MXL_SetGPIO(fe, 3, 1); + } + } + } + return status ; +} + +static u16 MXL_SetGPIO(struct dvb_frontend *fe, u8 GPIO_Num, u8 GPIO_Val) +{ + u16 status = 0; + + if (GPIO_Num == 1) + status += MXL_ControlWrite(fe, GPIO_1B, GPIO_Val ? 0 : 1); + + /* GPIO2 is not available */ + + if (GPIO_Num == 3) { + if (GPIO_Val == 1) { + status += MXL_ControlWrite(fe, GPIO_3, 0); + status += MXL_ControlWrite(fe, GPIO_3B, 0); + } + if (GPIO_Val == 0) { + status += MXL_ControlWrite(fe, GPIO_3, 1); + status += MXL_ControlWrite(fe, GPIO_3B, 1); + } + if (GPIO_Val == 3) { /* tri-state */ + status += MXL_ControlWrite(fe, GPIO_3, 0); + status += MXL_ControlWrite(fe, GPIO_3B, 1); + } + } + if (GPIO_Num == 4) { + if (GPIO_Val == 1) { + status += MXL_ControlWrite(fe, GPIO_4, 0); + status += MXL_ControlWrite(fe, GPIO_4B, 0); + } + if (GPIO_Val == 0) { + status += MXL_ControlWrite(fe, GPIO_4, 1); + status += MXL_ControlWrite(fe, GPIO_4B, 1); + } + if (GPIO_Val == 3) { /* tri-state */ + status += MXL_ControlWrite(fe, GPIO_4, 0); + status += MXL_ControlWrite(fe, GPIO_4B, 1); + } + } + + return status; +} + +static u16 MXL_ControlWrite(struct dvb_frontend *fe, u16 ControlNum, u32 value) +{ + u16 status = 0; + + /* Will write ALL Matching Control Name */ + /* Write Matching INIT Control */ + status += MXL_ControlWrite_Group(fe, ControlNum, value, 1); + /* Write Matching CH Control */ + status += MXL_ControlWrite_Group(fe, ControlNum, value, 2); +#ifdef _MXL_INTERNAL + /* Write Matching MXL Control */ + status += MXL_ControlWrite_Group(fe, ControlNum, value, 3); +#endif + return status; +} + +static u16 MXL_ControlWrite_Group(struct dvb_frontend *fe, u16 controlNum, + u32 value, u16 controlGroup) +{ + struct mxl5005s_state *state = fe->tuner_priv; + u16 i, j, k; + u32 highLimit; + u32 ctrlVal; + + if (controlGroup == 1) /* Initial Control */ { + + for (i = 0; i < state->Init_Ctrl_Num; i++) { + + if (controlNum == state->Init_Ctrl[i].Ctrl_Num) { + + highLimit = 1 << state->Init_Ctrl[i].size; + if (value < highLimit) { + for (j = 0; j < state->Init_Ctrl[i].size; j++) { + state->Init_Ctrl[i].val[j] = (u8)((value >> j) & 0x01); + MXL_RegWriteBit(fe, (u8)(state->Init_Ctrl[i].addr[j]), + (u8)(state->Init_Ctrl[i].bit[j]), + (u8)((value>>j) & 0x01)); + } + ctrlVal = 0; + for (k = 0; k < state->Init_Ctrl[i].size; k++) + ctrlVal += state->Init_Ctrl[i].val[k] * (1 << k); + } else + return -1; + } + } + } + if (controlGroup == 2) /* Chan change Control */ { + + for (i = 0; i < state->CH_Ctrl_Num; i++) { + + if (controlNum == state->CH_Ctrl[i].Ctrl_Num) { + + highLimit = 1 << state->CH_Ctrl[i].size; + if (value < highLimit) { + for (j = 0; j < state->CH_Ctrl[i].size; j++) { + state->CH_Ctrl[i].val[j] = (u8)((value >> j) & 0x01); + MXL_RegWriteBit(fe, (u8)(state->CH_Ctrl[i].addr[j]), + (u8)(state->CH_Ctrl[i].bit[j]), + (u8)((value>>j) & 0x01)); + } + ctrlVal = 0; + for (k = 0; k < state->CH_Ctrl[i].size; k++) + ctrlVal += state->CH_Ctrl[i].val[k] * (1 << k); + } else + return -1; + } + } + } +#ifdef _MXL_INTERNAL + if (controlGroup == 3) /* Maxlinear Control */ { + + for (i = 0; i < state->MXL_Ctrl_Num; i++) { + + if (controlNum == state->MXL_Ctrl[i].Ctrl_Num) { + + highLimit = (1 << state->MXL_Ctrl[i].size); + if (value < highLimit) { + for (j = 0; j < state->MXL_Ctrl[i].size; j++) { + state->MXL_Ctrl[i].val[j] = (u8)((value >> j) & 0x01); + MXL_RegWriteBit(fe, (u8)(state->MXL_Ctrl[i].addr[j]), + (u8)(state->MXL_Ctrl[i].bit[j]), + (u8)((value>>j) & 0x01)); + } + ctrlVal = 0; + for (k = 0; k < state->MXL_Ctrl[i].size; k++) + ctrlVal += state->MXL_Ctrl[i].val[k] * (1 << k); + } else + return -1; + } + } + } +#endif + return 0 ; /* successful return */ +} + +static u16 MXL_RegRead(struct dvb_frontend *fe, u8 RegNum, u8 *RegVal) +{ + struct mxl5005s_state *state = fe->tuner_priv; + int i ; + + for (i = 0; i < 104; i++) { + if (RegNum == state->TunerRegs[i].Reg_Num) { + *RegVal = (u8)(state->TunerRegs[i].Reg_Val); + return 0; + } + } + + return 1; +} + +static u16 MXL_ControlRead(struct dvb_frontend *fe, u16 controlNum, u32 *value) +{ + struct mxl5005s_state *state = fe->tuner_priv; + u32 ctrlVal ; + u16 i, k ; + + for (i = 0; i < state->Init_Ctrl_Num ; i++) { + + if (controlNum == state->Init_Ctrl[i].Ctrl_Num) { + + ctrlVal = 0; + for (k = 0; k < state->Init_Ctrl[i].size; k++) + ctrlVal += state->Init_Ctrl[i].val[k] * (1<CH_Ctrl_Num ; i++) { + + if (controlNum == state->CH_Ctrl[i].Ctrl_Num) { + + ctrlVal = 0; + for (k = 0; k < state->CH_Ctrl[i].size; k++) + ctrlVal += state->CH_Ctrl[i].val[k] * (1 << k); + *value = ctrlVal; + return 0; + + } + } + +#ifdef _MXL_INTERNAL + for (i = 0; i < state->MXL_Ctrl_Num ; i++) { + + if (controlNum == state->MXL_Ctrl[i].Ctrl_Num) { + + ctrlVal = 0; + for (k = 0; k < state->MXL_Ctrl[i].size; k++) + ctrlVal += state->MXL_Ctrl[i].val[k] * (1<tuner_priv; + int i ; + + const u8 AND_MAP[8] = { + 0xFE, 0xFD, 0xFB, 0xF7, + 0xEF, 0xDF, 0xBF, 0x7F } ; + + const u8 OR_MAP[8] = { + 0x01, 0x02, 0x04, 0x08, + 0x10, 0x20, 0x40, 0x80 } ; + + for (i = 0; i < state->TunerRegs_Num; i++) { + if (state->TunerRegs[i].Reg_Num == address) { + if (bitVal) + state->TunerRegs[i].Reg_Val |= OR_MAP[bit]; + else + state->TunerRegs[i].Reg_Val &= AND_MAP[bit]; + break ; + } + } +} + +static u32 MXL_Ceiling(u32 value, u32 resolution) +{ + return (value/resolution + (value % resolution > 0 ? 1 : 0)); +} + +/* Retrieve the Initialzation Registers */ +static u16 MXL_GetInitRegister(struct dvb_frontend *fe, u8 *RegNum, + u8 *RegVal, int *count) +{ + u16 status = 0; + int i ; + + u8 RegAddr[] = { + 11, 12, 13, 22, 32, 43, 44, 53, 56, 59, 73, + 76, 77, 91, 134, 135, 137, 147, + 156, 166, 167, 168, 25 }; + + *count = sizeof(RegAddr) / sizeof(u8); + + status += MXL_BlockInit(fe); + + for (i = 0 ; i < *count; i++) { + RegNum[i] = RegAddr[i]; + status += MXL_RegRead(fe, RegNum[i], &RegVal[i]); + } + + return status; +} + +static u16 MXL_GetCHRegister(struct dvb_frontend *fe, u8 *RegNum, u8 *RegVal, + int *count) +{ + u16 status = 0; + int i ; + +/* add 77, 166, 167, 168 register for 2.6.12 */ +#ifdef _MXL_PRODUCTION + u8 RegAddr[] = {14, 15, 16, 17, 22, 43, 65, 68, 69, 70, 73, 92, 93, 106, + 107, 108, 109, 110, 111, 112, 136, 138, 149, 77, 166, 167, 168 } ; +#else + u8 RegAddr[] = {14, 15, 16, 17, 22, 43, 68, 69, 70, 73, 92, 93, 106, + 107, 108, 109, 110, 111, 112, 136, 138, 149, 77, 166, 167, 168 } ; + /* + u8 RegAddr[171]; + for (i = 0; i <= 170; i++) + RegAddr[i] = i; + */ +#endif + + *count = sizeof(RegAddr) / sizeof(u8); + + for (i = 0 ; i < *count; i++) { + RegNum[i] = RegAddr[i]; + status += MXL_RegRead(fe, RegNum[i], &RegVal[i]); + } + + return status; +} + +static u16 MXL_GetCHRegister_ZeroIF(struct dvb_frontend *fe, u8 *RegNum, + u8 *RegVal, int *count) +{ + u16 status = 0; + int i; + + u8 RegAddr[] = {43, 136}; + + *count = sizeof(RegAddr) / sizeof(u8); + + for (i = 0; i < *count; i++) { + RegNum[i] = RegAddr[i]; + status += MXL_RegRead(fe, RegNum[i], &RegVal[i]); + } + + return status; +} + +static u16 MXL_GetMasterControl(u8 *MasterReg, int state) +{ + if (state == 1) /* Load_Start */ + *MasterReg = 0xF3; + if (state == 2) /* Power_Down */ + *MasterReg = 0x41; + if (state == 3) /* Synth_Reset */ + *MasterReg = 0xB1; + if (state == 4) /* Seq_Off */ + *MasterReg = 0xF1; + + return 0; +} + +#ifdef _MXL_PRODUCTION +static u16 MXL_VCORange_Test(struct dvb_frontend *fe, int VCO_Range) +{ + struct mxl5005s_state *state = fe->tuner_priv; + u16 status = 0 ; + + if (VCO_Range == 1) { + status += MXL_ControlWrite(fe, RFSYN_EN_DIV, 1); + status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0); + status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0); + status += MXL_ControlWrite(fe, RFSYN_DIVM, 1); + status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1); + status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1); + status += MXL_ControlWrite(fe, DN_SEL_FREQ, 0); + if (state->Mode == 0 && state->IF_Mode == 1) { + /* Analog Low IF Mode */ + status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1); + status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8); + status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 56); + status += MXL_ControlWrite(fe, + CHCAL_FRAC_MOD_RF, 180224); + } + if (state->Mode == 0 && state->IF_Mode == 0) { + /* Analog Zero IF Mode */ + status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1); + status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8); + status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 56); + status += MXL_ControlWrite(fe, + CHCAL_FRAC_MOD_RF, 222822); + } + if (state->Mode == 1) /* Digital Mode */ { + status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1); + status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8); + status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 56); + status += MXL_ControlWrite(fe, + CHCAL_FRAC_MOD_RF, 229376); + } + } + + if (VCO_Range == 2) { + status += MXL_ControlWrite(fe, RFSYN_EN_DIV, 1); + status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0); + status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0); + status += MXL_ControlWrite(fe, RFSYN_DIVM, 1); + status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1); + status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1); + status += MXL_ControlWrite(fe, DN_SEL_FREQ, 0); + status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1); + status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40); + status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 41); + if (state->Mode == 0 && state->IF_Mode == 1) { + /* Analog Low IF Mode */ + status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1); + status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40); + status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 42); + status += MXL_ControlWrite(fe, + CHCAL_FRAC_MOD_RF, 206438); + } + if (state->Mode == 0 && state->IF_Mode == 0) { + /* Analog Zero IF Mode */ + status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1); + status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40); + status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 42); + status += MXL_ControlWrite(fe, + CHCAL_FRAC_MOD_RF, 206438); + } + if (state->Mode == 1) /* Digital Mode */ { + status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1); + status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40); + status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 41); + status += MXL_ControlWrite(fe, + CHCAL_FRAC_MOD_RF, 16384); + } + } + + if (VCO_Range == 3) { + status += MXL_ControlWrite(fe, RFSYN_EN_DIV, 1); + status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0); + status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0); + status += MXL_ControlWrite(fe, RFSYN_DIVM, 1); + status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1); + status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1); + status += MXL_ControlWrite(fe, DN_SEL_FREQ, 0); + status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0); + status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8); + status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 42); + if (state->Mode == 0 && state->IF_Mode == 1) { + /* Analog Low IF Mode */ + status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0); + status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8); + status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 44); + status += MXL_ControlWrite(fe, + CHCAL_FRAC_MOD_RF, 173670); + } + if (state->Mode == 0 && state->IF_Mode == 0) { + /* Analog Zero IF Mode */ + status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0); + status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8); + status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 44); + status += MXL_ControlWrite(fe, + CHCAL_FRAC_MOD_RF, 173670); + } + if (state->Mode == 1) /* Digital Mode */ { + status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0); + status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8); + status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 42); + status += MXL_ControlWrite(fe, + CHCAL_FRAC_MOD_RF, 245760); + } + } + + if (VCO_Range == 4) { + status += MXL_ControlWrite(fe, RFSYN_EN_DIV, 1); + status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0); + status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0); + status += MXL_ControlWrite(fe, RFSYN_DIVM, 1); + status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1); + status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1); + status += MXL_ControlWrite(fe, DN_SEL_FREQ, 0); + status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0); + status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40); + status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 27); + if (state->Mode == 0 && state->IF_Mode == 1) { + /* Analog Low IF Mode */ + status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0); + status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40); + status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 27); + status += MXL_ControlWrite(fe, + CHCAL_FRAC_MOD_RF, 206438); + } + if (state->Mode == 0 && state->IF_Mode == 0) { + /* Analog Zero IF Mode */ + status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0); + status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40); + status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 27); + status += MXL_ControlWrite(fe, + CHCAL_FRAC_MOD_RF, 206438); + } + if (state->Mode == 1) /* Digital Mode */ { + status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0); + status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40); + status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 27); + status += MXL_ControlWrite(fe, + CHCAL_FRAC_MOD_RF, 212992); + } + } + + return status; +} + +static u16 MXL_Hystersis_Test(struct dvb_frontend *fe, int Hystersis) +{ + struct mxl5005s_state *state = fe->tuner_priv; + u16 status = 0; + + if (Hystersis == 1) + status += MXL_ControlWrite(fe, DN_BYPASS_AGC_I2C, 1); + + return status; +} +#endif +/* End: Reference driver code found in the Realtek driver that + * is copyright MaxLinear */ + +/* ---------------------------------------------------------------- + * Begin: Everything after here is new code to adapt the + * proprietary Realtek driver into a Linux API tuner. + * Copyright (C) 2008 Steven Toth + */ +static int mxl5005s_reset(struct dvb_frontend *fe) +{ + struct mxl5005s_state *state = fe->tuner_priv; + int ret = 0; + + u8 buf[2] = { 0xff, 0x00 }; + struct i2c_msg msg = { .addr = state->config->i2c_address, .flags = 0, + .buf = buf, .len = 2 }; + + dprintk(2, "%s()\n", __func__); + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + + if (i2c_transfer(state->i2c, &msg, 1) != 1) { + printk(KERN_WARNING "mxl5005s I2C reset failed\n"); + ret = -EREMOTEIO; + } + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + + return ret; +} + +/* Write a single byte to a single reg, latch the value if required by + * following the transaction with the latch byte. + */ +static int mxl5005s_writereg(struct dvb_frontend *fe, u8 reg, u8 val, int latch) +{ + struct mxl5005s_state *state = fe->tuner_priv; + u8 buf[3] = { reg, val, MXL5005S_LATCH_BYTE }; + struct i2c_msg msg = { .addr = state->config->i2c_address, .flags = 0, + .buf = buf, .len = 3 }; + + if (latch == 0) + msg.len = 2; + + dprintk(2, "%s(0x%x, 0x%x, 0x%x)\n", __func__, reg, val, msg.addr); + + if (i2c_transfer(state->i2c, &msg, 1) != 1) { + printk(KERN_WARNING "mxl5005s I2C write failed\n"); + return -EREMOTEIO; + } + return 0; +} + +static int mxl5005s_writeregs(struct dvb_frontend *fe, u8 *addrtable, + u8 *datatable, u8 len) +{ + int ret = 0, i; + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + + for (i = 0 ; i < len-1; i++) { + ret = mxl5005s_writereg(fe, addrtable[i], datatable[i], 0); + if (ret < 0) + break; + } + + ret = mxl5005s_writereg(fe, addrtable[i], datatable[i], 1); + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + + return ret; +} + +static int mxl5005s_init(struct dvb_frontend *fe) +{ + dprintk(1, "%s()\n", __func__); + return mxl5005s_reconfigure(fe, MXL_QAM, MXL5005S_BANDWIDTH_6MHZ); +} + +static int mxl5005s_reconfigure(struct dvb_frontend *fe, u32 mod_type, + u32 bandwidth) +{ + struct mxl5005s_state *state = fe->tuner_priv; + + u8 AddrTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX]; + u8 ByteTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX]; + int TableLen; + + dprintk(1, "%s(type=%d, bw=%d)\n", __func__, mod_type, bandwidth); + + mxl5005s_reset(fe); + + /* Tuner initialization stage 0 */ + MXL_GetMasterControl(ByteTable, MC_SYNTH_RESET); + AddrTable[0] = MASTER_CONTROL_ADDR; + ByteTable[0] |= state->config->AgcMasterByte; + + mxl5005s_writeregs(fe, AddrTable, ByteTable, 1); + + mxl5005s_AssignTunerMode(fe, mod_type, bandwidth); + + /* Tuner initialization stage 1 */ + MXL_GetInitRegister(fe, AddrTable, ByteTable, &TableLen); + + mxl5005s_writeregs(fe, AddrTable, ByteTable, TableLen); + + return 0; +} + +static int mxl5005s_AssignTunerMode(struct dvb_frontend *fe, u32 mod_type, + u32 bandwidth) +{ + struct mxl5005s_state *state = fe->tuner_priv; + struct mxl5005s_config *c = state->config; + + InitTunerControls(fe); + + /* Set MxL5005S parameters. */ + MXL5005_TunerConfig( + fe, + c->mod_mode, + c->if_mode, + bandwidth, + c->if_freq, + c->xtal_freq, + c->agc_mode, + c->top, + c->output_load, + c->clock_out, + c->div_out, + c->cap_select, + c->rssi_enable, + mod_type, + c->tracking_filter); + + return 0; +} + +static int mxl5005s_set_params(struct dvb_frontend *fe, + struct dvb_frontend_parameters *params) +{ + struct mxl5005s_state *state = fe->tuner_priv; + u32 req_mode, req_bw = 0; + int ret; + + dprintk(1, "%s()\n", __func__); + + if (fe->ops.info.type == FE_ATSC) { + switch (params->u.vsb.modulation) { + case VSB_8: + req_mode = MXL_ATSC; break; + default: + case QAM_64: + case QAM_256: + case QAM_AUTO: + req_mode = MXL_QAM; break; + } + } else + req_mode = MXL_DVBT; + + /* Change tuner for new modulation type if reqd */ + if (req_mode != state->current_mode) { + switch (req_mode) { + case VSB_8: + case QAM_64: + case QAM_256: + case QAM_AUTO: + req_bw = MXL5005S_BANDWIDTH_6MHZ; + break; + default: + /* Assume DVB-T */ + switch (params->u.ofdm.bandwidth) { + case BANDWIDTH_6_MHZ: + req_bw = MXL5005S_BANDWIDTH_6MHZ; + break; + case BANDWIDTH_7_MHZ: + req_bw = MXL5005S_BANDWIDTH_7MHZ; + break; + case BANDWIDTH_AUTO: + case BANDWIDTH_8_MHZ: + req_bw = MXL5005S_BANDWIDTH_8MHZ; + break; + } + } + + state->current_mode = req_mode; + ret = mxl5005s_reconfigure(fe, req_mode, req_bw); + + } else + ret = 0; + + if (ret == 0) { + dprintk(1, "%s() freq=%d\n", __func__, params->frequency); + ret = mxl5005s_SetRfFreqHz(fe, params->frequency); + } + + return ret; +} + +static int mxl5005s_get_frequency(struct dvb_frontend *fe, u32 *frequency) +{ + struct mxl5005s_state *state = fe->tuner_priv; + dprintk(1, "%s()\n", __func__); + + *frequency = state->RF_IN; + + return 0; +} + +static int mxl5005s_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) +{ + struct mxl5005s_state *state = fe->tuner_priv; + dprintk(1, "%s()\n", __func__); + + *bandwidth = state->Chan_Bandwidth; + + return 0; +} + +static int mxl5005s_release(struct dvb_frontend *fe) +{ + dprintk(1, "%s()\n", __func__); + kfree(fe->tuner_priv); + fe->tuner_priv = NULL; + return 0; +} + +static const struct dvb_tuner_ops mxl5005s_tuner_ops = { + .info = { + .name = "MaxLinear MXL5005S", + .frequency_min = 48000000, + .frequency_max = 860000000, + .frequency_step = 50000, + }, + + .release = mxl5005s_release, + .init = mxl5005s_init, + + .set_params = mxl5005s_set_params, + .get_frequency = mxl5005s_get_frequency, + .get_bandwidth = mxl5005s_get_bandwidth, +}; + +struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c, + struct mxl5005s_config *config) +{ + struct mxl5005s_state *state = NULL; + dprintk(1, "%s()\n", __func__); + + state = kzalloc(sizeof(struct mxl5005s_state), GFP_KERNEL); + if (state == NULL) + return NULL; + + state->frontend = fe; + state->config = config; + state->i2c = i2c; + state->current_mode = MXL_QAM; + + printk(KERN_INFO "MXL5005S: Attached at address 0x%02x\n", + config->i2c_address); + + memcpy(&fe->ops.tuner_ops, &mxl5005s_tuner_ops, + sizeof(struct dvb_tuner_ops)); + + fe->tuner_priv = state; + return fe; +} +EXPORT_SYMBOL(mxl5005s_attach); + +MODULE_DESCRIPTION("MaxLinear MXL5005S silicon tuner driver"); +MODULE_AUTHOR("Steven Toth"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/common/tuners/mxl5005s.h b/drivers/media/common/tuners/mxl5005s.h new file mode 100644 index 0000000000000000000000000000000000000000..396db150bf0c7a3ca9d294a8eb6c1e7ee26559cb --- /dev/null +++ b/drivers/media/common/tuners/mxl5005s.h @@ -0,0 +1,131 @@ +/* + MaxLinear MXL5005S VSB/QAM/DVBT tuner driver + + Copyright (C) 2008 MaxLinear + Copyright (C) 2008 Steven Toth + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef __MXL5005S_H +#define __MXL5005S_H + +#include +#include "dvb_frontend.h" + +struct mxl5005s_config { + + /* 7 bit i2c address */ + u8 i2c_address; + +#define IF_FREQ_4570000HZ 4570000 +#define IF_FREQ_4571429HZ 4571429 +#define IF_FREQ_5380000HZ 5380000 +#define IF_FREQ_36000000HZ 36000000 +#define IF_FREQ_36125000HZ 36125000 +#define IF_FREQ_36166667HZ 36166667 +#define IF_FREQ_44000000HZ 44000000 + u32 if_freq; + +#define CRYSTAL_FREQ_4000000HZ 4000000 +#define CRYSTAL_FREQ_16000000HZ 16000000 +#define CRYSTAL_FREQ_25000000HZ 25000000 +#define CRYSTAL_FREQ_28800000HZ 28800000 + u32 xtal_freq; + +#define MXL_DUAL_AGC 0 +#define MXL_SINGLE_AGC 1 + u8 agc_mode; + +#define MXL_TF_DEFAULT 0 +#define MXL_TF_OFF 1 +#define MXL_TF_C 2 +#define MXL_TF_C_H 3 +#define MXL_TF_D 4 +#define MXL_TF_D_L 5 +#define MXL_TF_E 6 +#define MXL_TF_F 7 +#define MXL_TF_E_2 8 +#define MXL_TF_E_NA 9 +#define MXL_TF_G 10 + u8 tracking_filter; + +#define MXL_RSSI_DISABLE 0 +#define MXL_RSSI_ENABLE 1 + u8 rssi_enable; + +#define MXL_CAP_SEL_DISABLE 0 +#define MXL_CAP_SEL_ENABLE 1 + u8 cap_select; + +#define MXL_DIV_OUT_1 0 +#define MXL_DIV_OUT_4 1 + u8 div_out; + +#define MXL_CLOCK_OUT_DISABLE 0 +#define MXL_CLOCK_OUT_ENABLE 1 + u8 clock_out; + +#define MXL5005S_IF_OUTPUT_LOAD_200_OHM 200 +#define MXL5005S_IF_OUTPUT_LOAD_300_OHM 300 + u32 output_load; + +#define MXL5005S_TOP_5P5 55 +#define MXL5005S_TOP_7P2 72 +#define MXL5005S_TOP_9P2 92 +#define MXL5005S_TOP_11P0 110 +#define MXL5005S_TOP_12P9 129 +#define MXL5005S_TOP_14P7 147 +#define MXL5005S_TOP_16P8 168 +#define MXL5005S_TOP_19P4 194 +#define MXL5005S_TOP_21P2 212 +#define MXL5005S_TOP_23P2 232 +#define MXL5005S_TOP_25P2 252 +#define MXL5005S_TOP_27P1 271 +#define MXL5005S_TOP_29P2 292 +#define MXL5005S_TOP_31P7 317 +#define MXL5005S_TOP_34P9 349 + u32 top; + +#define MXL_ANALOG_MODE 0 +#define MXL_DIGITAL_MODE 1 + u8 mod_mode; + +#define MXL_ZERO_IF 0 +#define MXL_LOW_IF 1 + u8 if_mode; + + /* Stuff I don't know what to do with */ + u8 AgcMasterByte; +}; + +#if defined(CONFIG_MEDIA_TUNER_MXL5005S) || \ + (defined(CONFIG_MEDIA_TUNER_MXL5005S_MODULE) && defined(MODULE)) +extern struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c, + struct mxl5005s_config *config); +#else +static inline struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c, + struct mxl5005s_config *config) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +#endif /* CONFIG_DVB_TUNER_MXL5005S */ + +#endif /* __MXL5005S_H */ + diff --git a/drivers/media/common/tuners/tda18271-common.c b/drivers/media/common/tuners/tda18271-common.c index e27a7620a32f20b2f68990bc968714b270e168eb..42b5f5d4bfe64109df3f25760be9d88ea73ba071 100644 --- a/drivers/media/common/tuners/tda18271-common.c +++ b/drivers/media/common/tuners/tda18271-common.c @@ -227,9 +227,8 @@ int tda18271_charge_pump_source(struct dvb_frontend *fe, regs[r_cp] &= ~0x20; regs[r_cp] |= ((force & 1) << 5); - tda18271_write_regs(fe, r_cp, 1); - return 0; + return tda18271_write_regs(fe, r_cp, 1); } int tda18271_init_regs(struct dvb_frontend *fe) @@ -487,16 +486,15 @@ int tda18271_set_standby_mode(struct dvb_frontend *fe, struct tda18271_priv *priv = fe->tuner_priv; unsigned char *regs = priv->tda18271_regs; - tda_dbg("sm = %d, sm_lt = %d, sm_xt = %d\n", sm, sm_lt, sm_xt); + if (tda18271_debug & DBG_ADV) + tda_dbg("sm = %d, sm_lt = %d, sm_xt = %d\n", sm, sm_lt, sm_xt); regs[R_EP3] &= ~0xe0; /* clear sm, sm_lt, sm_xt */ regs[R_EP3] |= sm ? (1 << 7) : 0 | sm_lt ? (1 << 6) : 0 | sm_xt ? (1 << 5) : 0; - tda18271_write_regs(fe, R_EP3, 1); - - return 0; + return tda18271_write_regs(fe, R_EP3, 1); } /*---------------------------------------------------------------------*/ @@ -510,7 +508,7 @@ int tda18271_calc_main_pll(struct dvb_frontend *fe, u32 freq) u32 div; int ret = tda18271_lookup_pll_map(fe, MAIN_PLL, &freq, &pd, &d); - if (ret < 0) + if (tda_fail(ret)) goto fail; regs[R_MPD] = (0x77 & pd); @@ -542,7 +540,7 @@ int tda18271_calc_cal_pll(struct dvb_frontend *fe, u32 freq) u32 div; int ret = tda18271_lookup_pll_map(fe, CAL_PLL, &freq, &pd, &d); - if (ret < 0) + if (tda_fail(ret)) goto fail; regs[R_CPD] = pd; @@ -566,7 +564,7 @@ int tda18271_calc_bp_filter(struct dvb_frontend *fe, u32 *freq) u8 val; int ret = tda18271_lookup_map(fe, BP_FILTER, freq, &val); - if (ret < 0) + if (tda_fail(ret)) goto fail; regs[R_EP1] &= ~0x07; /* clear bp filter bits */ @@ -583,7 +581,7 @@ int tda18271_calc_km(struct dvb_frontend *fe, u32 *freq) u8 val; int ret = tda18271_lookup_map(fe, RF_CAL_KMCO, freq, &val); - if (ret < 0) + if (tda_fail(ret)) goto fail; regs[R_EB13] &= ~0x7c; /* clear k & m bits */ @@ -600,7 +598,7 @@ int tda18271_calc_rf_band(struct dvb_frontend *fe, u32 *freq) u8 val; int ret = tda18271_lookup_map(fe, RF_BAND, freq, &val); - if (ret < 0) + if (tda_fail(ret)) goto fail; regs[R_EP2] &= ~0xe0; /* clear rf band bits */ @@ -617,7 +615,7 @@ int tda18271_calc_gain_taper(struct dvb_frontend *fe, u32 *freq) u8 val; int ret = tda18271_lookup_map(fe, GAIN_TAPER, freq, &val); - if (ret < 0) + if (tda_fail(ret)) goto fail; regs[R_EP2] &= ~0x1f; /* clear gain taper bits */ @@ -634,7 +632,7 @@ int tda18271_calc_ir_measure(struct dvb_frontend *fe, u32 *freq) u8 val; int ret = tda18271_lookup_map(fe, IR_MEASURE, freq, &val); - if (ret < 0) + if (tda_fail(ret)) goto fail; regs[R_EP5] &= ~0x07; diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c index b262100ae897db7b8806f89658c2bf9cad658e45..89c01fb1f85981c5cbfa909e1579c2f75212cf07 100644 --- a/drivers/media/common/tuners/tda18271-fe.c +++ b/drivers/media/common/tuners/tda18271-fe.c @@ -51,6 +51,7 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe, { struct tda18271_priv *priv = fe->tuner_priv; unsigned char *regs = priv->tda18271_regs; + int ret; u32 N; /* update TV broadcast parameters */ @@ -85,7 +86,9 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe, /* update rf top / if top */ regs[R_EB22] = 0x00; regs[R_EB22] |= map->rfagc_top; - tda18271_write_regs(fe, R_EB22, 1); + ret = tda18271_write_regs(fe, R_EB22, 1); + if (tda_fail(ret)) + goto fail; /* --------------------------------------------------------------- */ @@ -121,7 +124,9 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe, /* agc1 has priority on agc2 */ regs[R_EB1] &= ~0x01; - tda18271_write_regs(fe, R_EB1, 1); + ret = tda18271_write_regs(fe, R_EB1, 1); + if (tda_fail(ret)) + goto fail; /* --------------------------------------------------------------- */ @@ -141,7 +146,9 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe, break; } - tda18271_write_regs(fe, R_TM, 7); + ret = tda18271_write_regs(fe, R_TM, 7); + if (tda_fail(ret)) + goto fail; /* force charge pump source */ charge_pump_source(fe, 1); @@ -158,9 +165,9 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe, regs[R_EP3] &= ~0x04; else regs[R_EP3] |= 0x04; - tda18271_write_regs(fe, R_EP3, 1); - - return 0; + ret = tda18271_write_regs(fe, R_EP3, 1); +fail: + return ret; } static int tda18271_read_thermometer(struct dvb_frontend *fe) @@ -213,11 +220,13 @@ static int tda18271c2_rf_tracking_filters_correction(struct dvb_frontend *fe, struct tda18271_priv *priv = fe->tuner_priv; struct tda18271_rf_tracking_filter_cal *map = priv->rf_cal_state; unsigned char *regs = priv->tda18271_regs; - int tm_current, rfcal_comp, approx, i; + int tm_current, rfcal_comp, approx, i, ret; u8 dc_over_dt, rf_tab; /* power up */ - tda18271_set_standby_mode(fe, 0, 0, 0); + ret = tda18271_set_standby_mode(fe, 0, 0, 0); + if (tda_fail(ret)) + goto fail; /* read die current temperature */ tm_current = tda18271_read_thermometer(fe); @@ -228,8 +237,8 @@ static int tda18271c2_rf_tracking_filters_correction(struct dvb_frontend *fe, rf_tab = regs[R_EB14]; i = tda18271_lookup_rf_band(fe, &freq, NULL); - if (i < 0) - return -EINVAL; + if (tda_fail(i)) + return i; if ((0 == map[i].rf3) || (freq / 1000 < map[i].rf2)) { approx = map[i].rf_a1 * @@ -250,35 +259,42 @@ static int tda18271c2_rf_tracking_filters_correction(struct dvb_frontend *fe, rfcal_comp = dc_over_dt * (tm_current - priv->tm_rfcal); regs[R_EB14] = approx + rfcal_comp; - tda18271_write_regs(fe, R_EB14, 1); - - return 0; + ret = tda18271_write_regs(fe, R_EB14, 1); +fail: + return ret; } static int tda18271_por(struct dvb_frontend *fe) { struct tda18271_priv *priv = fe->tuner_priv; unsigned char *regs = priv->tda18271_regs; + int ret; /* power up detector 1 */ regs[R_EB12] &= ~0x20; - tda18271_write_regs(fe, R_EB12, 1); + ret = tda18271_write_regs(fe, R_EB12, 1); + if (tda_fail(ret)) + goto fail; regs[R_EB18] &= ~0x80; /* turn agc1 loop on */ regs[R_EB18] &= ~0x03; /* set agc1_gain to 6 dB */ - tda18271_write_regs(fe, R_EB18, 1); + ret = tda18271_write_regs(fe, R_EB18, 1); + if (tda_fail(ret)) + goto fail; regs[R_EB21] |= 0x03; /* set agc2_gain to -6 dB */ /* POR mode */ - tda18271_set_standby_mode(fe, 1, 0, 0); + ret = tda18271_set_standby_mode(fe, 1, 0, 0); + if (tda_fail(ret)) + goto fail; /* disable 1.5 MHz low pass filter */ regs[R_EB23] &= ~0x04; /* forcelp_fc2_en = 0 */ regs[R_EB23] &= ~0x02; /* XXX: lp_fc[2] = 0 */ - tda18271_write_regs(fe, R_EB21, 3); - - return 0; + ret = tda18271_write_regs(fe, R_EB21, 3); +fail: + return ret; } static int tda18271_calibrate_rf(struct dvb_frontend *fe, u32 freq) @@ -389,7 +405,7 @@ static int tda18271_powerscan(struct dvb_frontend *fe, { struct tda18271_priv *priv = fe->tuner_priv; unsigned char *regs = priv->tda18271_regs; - int sgn, bcal, count, wait; + int sgn, bcal, count, wait, ret; u8 cid_target; u16 count_limit; u32 freq; @@ -421,7 +437,9 @@ static int tda18271_powerscan(struct dvb_frontend *fe, tda18271_write_regs(fe, R_EP2, 1); /* read power detection info, stored in EB10 */ - tda18271_read_extended(fe); + ret = tda18271_read_extended(fe); + if (tda_fail(ret)) + return ret; /* algorithm initialization */ sgn = 1; @@ -447,7 +465,9 @@ static int tda18271_powerscan(struct dvb_frontend *fe, tda18271_write_regs(fe, R_EP2, 1); /* read power detection info, stored in EB10 */ - tda18271_read_extended(fe); + ret = tda18271_read_extended(fe); + if (tda_fail(ret)) + return ret; count += 200; @@ -478,6 +498,7 @@ static int tda18271_powerscan_init(struct dvb_frontend *fe) { struct tda18271_priv *priv = fe->tuner_priv; unsigned char *regs = priv->tda18271_regs; + int ret; /* set standard to digital */ regs[R_EP3] &= ~0x1f; /* clear std bits */ @@ -489,10 +510,14 @@ static int tda18271_powerscan_init(struct dvb_frontend *fe) /* update IF output level & IF notch frequency */ regs[R_EP4] &= ~0x1c; /* clear if level bits */ - tda18271_write_regs(fe, R_EP3, 2); + ret = tda18271_write_regs(fe, R_EP3, 2); + if (tda_fail(ret)) + goto fail; regs[R_EB18] &= ~0x03; /* set agc1_gain to 6 dB */ - tda18271_write_regs(fe, R_EB18, 1); + ret = tda18271_write_regs(fe, R_EB18, 1); + if (tda_fail(ret)) + goto fail; regs[R_EB21] &= ~0x03; /* set agc2_gain to -15 dB */ @@ -500,9 +525,9 @@ static int tda18271_powerscan_init(struct dvb_frontend *fe) regs[R_EB23] |= 0x04; /* forcelp_fc2_en = 1 */ regs[R_EB23] |= 0x02; /* lp_fc[2] = 1 */ - tda18271_write_regs(fe, R_EB21, 3); - - return 0; + ret = tda18271_write_regs(fe, R_EB21, 3); +fail: + return ret; } static int tda18271_rf_tracking_filters_init(struct dvb_frontend *fe, u32 freq) @@ -521,7 +546,7 @@ static int tda18271_rf_tracking_filters_init(struct dvb_frontend *fe, u32 freq) i = tda18271_lookup_rf_band(fe, &freq, NULL); - if (i < 0) + if (tda_fail(i)) return i; rf_default[RF1] = 1000 * map[i].rf1_def; @@ -535,6 +560,8 @@ static int tda18271_rf_tracking_filters_init(struct dvb_frontend *fe, u32 freq) /* look for optimized calibration frequency */ bcal = tda18271_powerscan(fe, &rf_default[rf], &rf_freq[rf]); + if (tda_fail(bcal)) + return bcal; tda18271_calc_rf_cal(fe, &rf_freq[rf]); prog_tab[rf] = regs[R_EB14]; @@ -575,22 +602,29 @@ static int tda18271_calc_rf_filter_curve(struct dvb_frontend *fe) { struct tda18271_priv *priv = fe->tuner_priv; unsigned int i; + int ret; tda_info("tda18271: performing RF tracking filter calibration\n"); /* wait for die temperature stabilization */ msleep(200); - tda18271_powerscan_init(fe); + ret = tda18271_powerscan_init(fe); + if (tda_fail(ret)) + goto fail; /* rf band calibration */ - for (i = 0; priv->rf_cal_state[i].rfmax != 0; i++) + for (i = 0; priv->rf_cal_state[i].rfmax != 0; i++) { + ret = tda18271_rf_tracking_filters_init(fe, 1000 * priv->rf_cal_state[i].rfmax); + if (tda_fail(ret)) + goto fail; + } priv->tm_rfcal = tda18271_read_thermometer(fe); - - return 0; +fail: + return ret; } /* ------------------------------------------------------------------ */ @@ -599,6 +633,7 @@ static int tda18271c2_rf_cal_init(struct dvb_frontend *fe) { struct tda18271_priv *priv = fe->tuner_priv; unsigned char *regs = priv->tda18271_regs; + int ret; /* test RF_CAL_OK to see if we need init */ if ((regs[R_EP1] & 0x10) == 0) @@ -607,15 +642,22 @@ static int tda18271c2_rf_cal_init(struct dvb_frontend *fe) if (priv->cal_initialized) return 0; - tda18271_calc_rf_filter_curve(fe); + ret = tda18271_calc_rf_filter_curve(fe); + if (tda_fail(ret)) + goto fail; - tda18271_por(fe); + ret = tda18271_por(fe); + if (tda_fail(ret)) + goto fail; tda_info("tda18271: RF tracking filter calibration complete\n"); priv->cal_initialized = true; - - return 0; + goto end; +fail: + tda_info("tda18271: RF tracking filter calibration failed!\n"); +end: + return ret; } static int tda18271c1_rf_tracking_filter_calibration(struct dvb_frontend *fe, @@ -623,6 +665,7 @@ static int tda18271c1_rf_tracking_filter_calibration(struct dvb_frontend *fe, { struct tda18271_priv *priv = fe->tuner_priv; unsigned char *regs = priv->tda18271_regs; + int ret; u32 N = 0; /* calculate bp filter */ @@ -671,7 +714,10 @@ static int tda18271c1_rf_tracking_filter_calibration(struct dvb_frontend *fe, tda18271_calc_main_pll(fe, N); - tda18271_write_regs(fe, R_EP3, 11); + ret = tda18271_write_regs(fe, R_EP3, 11); + if (tda_fail(ret)) + return ret; + msleep(5); /* RF tracking filter calibration initialization */ /* search for K,M,CO for RF calibration */ @@ -719,45 +765,56 @@ static int tda18271_ir_cal_init(struct dvb_frontend *fe) { struct tda18271_priv *priv = fe->tuner_priv; unsigned char *regs = priv->tda18271_regs; + int ret; - tda18271_read_regs(fe); + ret = tda18271_read_regs(fe); + if (tda_fail(ret)) + goto fail; /* test IR_CAL_OK to see if we need init */ if ((regs[R_EP1] & 0x08) == 0) - tda18271_init_regs(fe); - - return 0; + ret = tda18271_init_regs(fe); +fail: + return ret; } static int tda18271_init(struct dvb_frontend *fe) { struct tda18271_priv *priv = fe->tuner_priv; + int ret; mutex_lock(&priv->lock); /* power up */ - tda18271_set_standby_mode(fe, 0, 0, 0); + ret = tda18271_set_standby_mode(fe, 0, 0, 0); + if (tda_fail(ret)) + goto fail; /* initialization */ - tda18271_ir_cal_init(fe); + ret = tda18271_ir_cal_init(fe); + if (tda_fail(ret)) + goto fail; if (priv->id == TDA18271HDC2) tda18271c2_rf_cal_init(fe); - +fail: mutex_unlock(&priv->lock); - return 0; + return ret; } static int tda18271_tune(struct dvb_frontend *fe, struct tda18271_std_map_item *map, u32 freq, u32 bw) { struct tda18271_priv *priv = fe->tuner_priv; + int ret; tda_dbg("freq = %d, ifc = %d, bw = %d, agc_mode = %d, std = %d\n", freq, map->if_freq, bw, map->agc_mode, map->std); - tda18271_init(fe); + ret = tda18271_init(fe); + if (tda_fail(ret)) + goto fail; mutex_lock(&priv->lock); @@ -769,11 +826,11 @@ static int tda18271_tune(struct dvb_frontend *fe, tda18271c2_rf_tracking_filters_correction(fe, freq); break; } - tda18271_channel_configuration(fe, map, freq, bw); + ret = tda18271_channel_configuration(fe, map, freq, bw); mutex_unlock(&priv->lock); - - return 0; +fail: + return ret; } /* ------------------------------------------------------------------ */ @@ -837,7 +894,7 @@ static int tda18271_set_params(struct dvb_frontend *fe, ret = tda18271_tune(fe, map, freq, bw); - if (ret < 0) + if (tda_fail(ret)) goto fail; priv->frequency = freq; @@ -893,7 +950,7 @@ static int tda18271_set_analog_params(struct dvb_frontend *fe, ret = tda18271_tune(fe, map, freq, 0); - if (ret < 0) + if (tda_fail(ret)) goto fail; priv->frequency = freq; @@ -905,16 +962,17 @@ fail: static int tda18271_sleep(struct dvb_frontend *fe) { struct tda18271_priv *priv = fe->tuner_priv; + int ret; mutex_lock(&priv->lock); /* standby mode w/ slave tuner output * & loop thru & xtal oscillator on */ - tda18271_set_standby_mode(fe, 1, 0, 0); + ret = tda18271_set_standby_mode(fe, 1, 0, 0); mutex_unlock(&priv->lock); - return 0; + return ret; } static int tda18271_release(struct dvb_frontend *fe) @@ -1095,10 +1153,10 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, if (cfg) priv->small_i2c = cfg->small_i2c; - if (tda18271_get_id(fe) < 0) + if (tda_fail(tda18271_get_id(fe))) goto fail; - if (tda18271_assign_map_layout(fe) < 0) + if (tda_fail(tda18271_assign_map_layout(fe))) goto fail; mutex_lock(&priv->lock); diff --git a/drivers/media/common/tuners/tda18271-priv.h b/drivers/media/common/tuners/tda18271-priv.h index 2bc5eb368ea2853109298eb7bf1a7ee4e4b4625b..81a739365f8c65eb399379bf872fcfd91c42afb2 100644 --- a/drivers/media/common/tuners/tda18271-priv.h +++ b/drivers/media/common/tuners/tda18271-priv.h @@ -153,6 +153,15 @@ extern int tda18271_debug; #define tda_reg(fmt, arg...) dprintk(KERN_DEBUG, DBG_REG, fmt, ##arg) #define tda_cal(fmt, arg...) dprintk(KERN_DEBUG, DBG_CAL, fmt, ##arg) +#define tda_fail(ret) \ +({ \ + int __ret; \ + __ret = (ret < 0); \ + if (__ret) \ + tda_printk(KERN_ERR, "error %d on line %d\n", ret, __LINE__);\ + __ret; \ +}) + /*---------------------------------------------------------------------*/ enum tda18271_map_type { diff --git a/drivers/media/common/tuners/tea5767.c b/drivers/media/common/tuners/tea5767.c index f6e7d7ad842416ad5ac9b82bde9532125a3ddd80..1f5646334a8ffad1cffeb6183f796abb6c65f711 100644 --- a/drivers/media/common/tuners/tea5767.c +++ b/drivers/media/common/tuners/tea5767.c @@ -373,14 +373,14 @@ int tea5767_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr) if ((rc = tuner_i2c_xfer_recv(&i2c, buffer, 7))< 5) { printk(KERN_WARNING "It is not a TEA5767. Received %i bytes.\n", rc); - return EINVAL; + return -EINVAL; } /* If all bytes are the same then it's a TV tuner and not a tea5767 */ if (buffer[0] == buffer[1] && buffer[0] == buffer[2] && buffer[0] == buffer[3] && buffer[0] == buffer[4]) { printk(KERN_WARNING "All bytes are equal. It is not a TEA5767\n"); - return EINVAL; + return -EINVAL; } /* Status bytes: @@ -390,7 +390,7 @@ int tea5767_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr) */ if (((buffer[3] & 0x0f) != 0x00) || (buffer[4] != 0x00)) { printk(KERN_WARNING "Chip ID is not zero. It is not a TEA5767\n"); - return EINVAL; + return -EINVAL; } diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c index 43d35bdb221f0ab367953d557d9c29d4fae2b077..ceae6db901ecaa9543f5e4ef4bcd727e3d10cc42 100644 --- a/drivers/media/common/tuners/xc5000.c +++ b/drivers/media/common/tuners/xc5000.c @@ -212,7 +212,7 @@ static void xc5000_TunerReset(struct dvb_frontend *fe) dprintk(1, "%s()\n", __func__); if (priv->cfg->tuner_callback) { - ret = priv->cfg->tuner_callback(priv->cfg->priv, + ret = priv->cfg->tuner_callback(priv->devptr, XC5000_TUNER_RESET, 0); if (ret) printk(KERN_ERR "xc5000: reset failed\n"); @@ -900,9 +900,9 @@ static const struct dvb_tuner_ops xc5000_tuner_ops = { .get_status = xc5000_get_status }; -struct dvb_frontend * xc5000_attach(struct dvb_frontend *fe, - struct i2c_adapter *i2c, - struct xc5000_config *cfg) +struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c, + struct xc5000_config *cfg, void *devptr) { struct xc5000_priv *priv = NULL; u16 id = 0; @@ -916,6 +916,7 @@ struct dvb_frontend * xc5000_attach(struct dvb_frontend *fe, priv->cfg = cfg; priv->bandwidth = BANDWIDTH_6_MHZ; priv->i2c = i2c; + priv->devptr = devptr; /* Check if firmware has been loaded. It is possible that another instance of the driver has loaded the firmware. diff --git a/drivers/media/common/tuners/xc5000.h b/drivers/media/common/tuners/xc5000.h index 0ee80f9d19b8fa8621acb2f919650cc266925ae2..c910715addc97bdac548c89a563e2600ffa11b0e 100644 --- a/drivers/media/common/tuners/xc5000.h +++ b/drivers/media/common/tuners/xc5000.h @@ -31,29 +31,31 @@ struct xc5000_config { u8 i2c_address; u32 if_khz; - /* For each bridge framework, when it attaches either analog or digital, - * it has to store a reference back to its _core equivalent structure, - * so that it can service the hardware by steering gpio's etc. - * Each bridge implementation is different so cast priv accordingly. - * The xc5000 driver cares not for this value, other than ensuring - * it's passed back to a bridge during tuner_callback(). - */ - void *priv; int (*tuner_callback) (void *priv, int command, int arg); }; /* xc5000 callback command */ #define XC5000_TUNER_RESET 0 +/* For each bridge framework, when it attaches either analog or digital, + * it has to store a reference back to its _core equivalent structure, + * so that it can service the hardware by steering gpio's etc. + * Each bridge implementation is different so cast devptr accordingly. + * The xc5000 driver cares not for this value, other than ensuring + * it's passed back to a bridge during tuner_callback(). + */ + #if defined(CONFIG_MEDIA_TUNER_XC5000) || \ (defined(CONFIG_MEDIA_TUNER_XC5000_MODULE) && defined(MODULE)) extern struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, - struct xc5000_config *cfg); + struct xc5000_config *cfg, + void *devptr); #else static inline struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, - struct xc5000_config *cfg) + struct xc5000_config *cfg, + void *devptr) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; diff --git a/drivers/media/common/tuners/xc5000_priv.h b/drivers/media/common/tuners/xc5000_priv.h index 13b2d19341da72cd5cbdc5c450f70f9518223f6d..ecebfe4745adcadf30e3f2a82d31b00c3b21210e 100644 --- a/drivers/media/common/tuners/xc5000_priv.h +++ b/drivers/media/common/tuners/xc5000_priv.h @@ -31,6 +31,8 @@ struct xc5000_priv { u8 video_standard; u8 rf_mode; u8 fwloaded; + + void *devptr; }; #endif diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c index 7b0ea3bdfafbf9c1b00080a0e3a97a3478bce212..f9d087669d5db3dce7de713182e50eec8bdcc6d6 100644 --- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c +++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c @@ -634,7 +634,7 @@ int flexcop_frontend_init(struct flexcop_device *fc) } /* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */ - fc->fe = dvb_attach(vp310_mt312_attach, + fc->fe = dvb_attach(mt312_attach, &skystar23_samsung_tbdu18132_config, i2c); if (fc->fe != NULL) { ops = &fc->fe->ops; diff --git a/drivers/media/dvb/bt8xx/Kconfig b/drivers/media/dvb/bt8xx/Kconfig index d1239b8342f81cdb13b5642fedcf463655fc1cb6..7588db1319d0cd3d3d654af53dc972ee6dadb717 100644 --- a/drivers/media/dvb/bt8xx/Kconfig +++ b/drivers/media/dvb/bt8xx/Kconfig @@ -1,6 +1,7 @@ config DVB_BT8XX tristate "BT8xx based PCI cards" depends on DVB_CORE && PCI && I2C && VIDEO_BT848 + depends on HOTPLUG # due to FW_LOADER select DVB_MT352 if !DVB_FE_CUSTOMISE select DVB_SP887X if !DVB_FE_CUSTOMISE select DVB_NXT6000 if !DVB_FE_CUSTOMISE diff --git a/drivers/media/dvb/cinergyT2/Kconfig b/drivers/media/dvb/cinergyT2/Kconfig index 3d778c5aba68ea8035d70c4265bd1a364039e53d..c03513b2ccaee79b34bc85fbff88e81028011bc7 100644 --- a/drivers/media/dvb/cinergyT2/Kconfig +++ b/drivers/media/dvb/cinergyT2/Kconfig @@ -1,6 +1,6 @@ config DVB_CINERGYT2 tristate "Terratec CinergyT2/qanu USB2 DVB-T receiver" - depends on DVB_CORE && USB + depends on DVB_CORE && USB && INPUT help Support for "TerraTec CinergyT2" USB2.0 Highspeed DVB Receivers diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c index 8cbdb0ec67e2e4d2cc8f8119a7bfeaddd0c8f9ab..588fbe105c27ccc298bf01d9fc75f0450cffae7f 100644 --- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c @@ -910,15 +910,21 @@ static void dvb_ca_en50221_thread_update_delay(struct dvb_ca_private *ca) int curdelay = 100000000; int slot; + /* Beware of too high polling frequency, because one polling + * call might take several hundred milliseconds until timeout! + */ for (slot = 0; slot < ca->slot_count; slot++) { switch (ca->slot_info[slot].slot_state) { default: case DVB_CA_SLOTSTATE_NONE: + delay = HZ * 60; /* 60s */ + if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) + delay = HZ * 5; /* 5s */ + break; case DVB_CA_SLOTSTATE_INVALID: - delay = HZ * 60; - if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) { - delay = HZ / 10; - } + delay = HZ * 60; /* 60s */ + if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) + delay = HZ / 10; /* 100ms */ break; case DVB_CA_SLOTSTATE_UNINITIALISED: @@ -926,19 +932,17 @@ static void dvb_ca_en50221_thread_update_delay(struct dvb_ca_private *ca) case DVB_CA_SLOTSTATE_VALIDATE: case DVB_CA_SLOTSTATE_WAITFR: case DVB_CA_SLOTSTATE_LINKINIT: - delay = HZ / 10; + delay = HZ / 10; /* 100ms */ break; case DVB_CA_SLOTSTATE_RUNNING: - delay = HZ * 60; - if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) { - delay = HZ / 10; - } + delay = HZ * 60; /* 60s */ + if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) + delay = HZ / 10; /* 100ms */ if (ca->open) { if ((!ca->slot_info[slot].da_irq_supported) || - (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_DA))) { - delay = HZ / 10; - } + (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_DA))) + delay = HZ / 10; /* 100ms */ } break; } diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index 4c1cff9feb2e69ed8e3acc57b536aecc5e5804e1..cf4584e48b6d66c70d40572650e791873ce37862 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig @@ -1,6 +1,7 @@ config DVB_USB tristate "Support for various USB DVB devices" depends on DVB_CORE && USB && I2C + depends on HOTPLUG # due to FW_LOADER select FW_LOADER help By enabling this you will be able to choose the various supported diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index 6d2384605927190abaa5394672fd191fb9a6a6e6..c20553c4da1faa4645b44cf6d77417c897bf0bdb 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig @@ -30,7 +30,7 @@ config DVB_CX24123 A DVB-S tuner module. Say Y when you want to support this frontend. config DVB_MT312 - tristate "Zarlink VP310/MT312 based" + tristate "Zarlink VP310/MT312/ZL10313 based" depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE help @@ -97,7 +97,7 @@ comment "DVB-T (terrestrial) frontends" config DVB_SP8870 tristate "Spase sp8870 based" - depends on DVB_CORE && I2C + depends on DVB_CORE && I2C && HOTPLUG default m if DVB_FE_CUSTOMISE select FW_LOADER help @@ -110,7 +110,7 @@ config DVB_SP8870 config DVB_SP887X tristate "Spase sp887x based" - depends on DVB_CORE && I2C + depends on DVB_CORE && I2C && HOTPLUG default m if DVB_FE_CUSTOMISE select FW_LOADER help @@ -144,7 +144,7 @@ config DVB_L64781 config DVB_TDA1004X tristate "Philips TDA10045H/TDA10046H based" - depends on DVB_CORE && I2C + depends on DVB_CORE && I2C && HOTPLUG default m if DVB_FE_CUSTOMISE select FW_LOADER help @@ -211,7 +211,7 @@ config DVB_DIB7000P config DVB_TDA10048 tristate "Philips TDA10048HN based" - depends on DVB_CORE && I2C + depends on DVB_CORE && I2C && HOTPLUG default m if DVB_FE_CUSTOMISE select FW_LOADER help @@ -253,7 +253,7 @@ comment "ATSC (North American/Korean Terrestrial/Cable DTV) frontends" config DVB_NXT200X tristate "NxtWave Communications NXT2002/NXT2004 based" - depends on DVB_CORE && I2C + depends on DVB_CORE && I2C && HOTPLUG default m if DVB_FE_CUSTOMISE select FW_LOADER help @@ -268,7 +268,7 @@ config DVB_NXT200X config DVB_OR51211 tristate "Oren OR51211 based" - depends on DVB_CORE && I2C + depends on DVB_CORE && I2C && HOTPLUG default m if DVB_FE_CUSTOMISE select FW_LOADER help @@ -281,7 +281,7 @@ config DVB_OR51211 config DVB_OR51132 tristate "Oren OR51132 based" - depends on DVB_CORE && I2C + depends on DVB_CORE && I2C && HOTPLUG default m if DVB_FE_CUSTOMISE select FW_LOADER help @@ -297,7 +297,7 @@ config DVB_OR51132 config DVB_BCM3510 tristate "Broadcom BCM3510" - depends on DVB_CORE && I2C + depends on DVB_CORE && I2C && HOTPLUG default m if DVB_FE_CUSTOMISE select FW_LOADER help diff --git a/drivers/media/dvb/frontends/itd1000.c b/drivers/media/dvb/frontends/itd1000.c index 04c562ccf990f54acca2bcb104e4be75276412c6..600dad6b41ea8a59641bea1bc5bc36b3aea36e71 100644 --- a/drivers/media/dvb/frontends/itd1000.c +++ b/drivers/media/dvb/frontends/itd1000.c @@ -195,7 +195,7 @@ static void itd1000_set_vco(struct itd1000_state *state, u32 freq_khz) } } -struct { +static const struct { u32 freq; u8 values[10]; /* RFTR, RFST1 - RFST9 */ } itd1000_fre_values[] = { diff --git a/drivers/media/dvb/frontends/mt312.c b/drivers/media/dvb/frontends/mt312.c index 081ca3398c76b074012f4fa99d7f41910d30e165..5ac9b15920f8df47f8c8d11b10d93a14c972401d 100644 --- a/drivers/media/dvb/frontends/mt312.c +++ b/drivers/media/dvb/frontends/mt312.c @@ -737,7 +737,7 @@ static void mt312_release(struct dvb_frontend *fe) } #define MT312_SYS_CLK 90000000UL /* 90 MHz */ -static struct dvb_frontend_ops vp310_mt312_ops = { +static struct dvb_frontend_ops mt312_ops = { .info = { .name = "Zarlink ???? DVB-S", @@ -776,7 +776,7 @@ static struct dvb_frontend_ops vp310_mt312_ops = { .set_voltage = mt312_set_voltage, }; -struct dvb_frontend *vp310_mt312_attach(const struct mt312_config *config, +struct dvb_frontend *mt312_attach(const struct mt312_config *config, struct i2c_adapter *i2c) { struct mt312_state *state = NULL; @@ -795,7 +795,7 @@ struct dvb_frontend *vp310_mt312_attach(const struct mt312_config *config, goto error; /* create dvb_frontend */ - memcpy(&state->frontend.ops, &vp310_mt312_ops, + memcpy(&state->frontend.ops, &mt312_ops, sizeof(struct dvb_frontend_ops)); state->frontend.demodulator_priv = state; @@ -827,12 +827,13 @@ error: kfree(state); return NULL; } -EXPORT_SYMBOL(vp310_mt312_attach); +EXPORT_SYMBOL(mt312_attach); module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); MODULE_DESCRIPTION("Zarlink VP310/MT312/ZL10313 DVB-S Demodulator driver"); MODULE_AUTHOR("Andreas Oberritter "); +MODULE_AUTHOR("Matthias Schwarzott "); MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/mt312.h b/drivers/media/dvb/frontends/mt312.h index de796eab39119506770ea9403e14fa9557dacfdf..29e3bb5496b8944d2ac19aeca5b9278168c2403c 100644 --- a/drivers/media/dvb/frontends/mt312.h +++ b/drivers/media/dvb/frontends/mt312.h @@ -37,10 +37,10 @@ struct mt312_config { }; #if defined(CONFIG_DVB_MT312) || (defined(CONFIG_DVB_MT312_MODULE) && defined(MODULE)) -struct dvb_frontend *vp310_mt312_attach(const struct mt312_config *config, +struct dvb_frontend *mt312_attach(const struct mt312_config *config, struct i2c_adapter *i2c); #else -static inline struct dvb_frontend *vp310_mt312_attach( +static inline struct dvb_frontend *mt312_attach( const struct mt312_config *config, struct i2c_adapter *i2c) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig index ae882432dd3d2b39179cc628260b723ac84a9798..d4339b1b3b6872e905532852ef31c4403158950b 100644 --- a/drivers/media/dvb/ttpci/Kconfig +++ b/drivers/media/dvb/ttpci/Kconfig @@ -5,6 +5,7 @@ config TTPCI_EEPROM config DVB_AV7110 tristate "AV7110 cards" depends on DVB_CORE && PCI && I2C + depends on HOTPLUG select FW_LOADER if !DVB_AV7110_FIRMWARE select TTPCI_EEPROM select VIDEO_SAA7146_VV @@ -123,6 +124,7 @@ config DVB_BUDGET_AV depends on DVB_BUDGET_CORE && I2C select VIDEO_SAA7146_VV depends on VIDEO_DEV # dependencies of VIDEO_SAA7146_VV + depends on HOTPLUG # dependency of FW_LOADER select DVB_PLL if !DVB_FE_CUSTOMISE select DVB_STV0299 if !DVB_FE_CUSTOMISE select DVB_TDA1004X if !DVB_FE_CUSTOMISE diff --git a/drivers/media/dvb/ttusb-dec/Kconfig b/drivers/media/dvb/ttusb-dec/Kconfig index 83611012ef345242460527b2452940bfa356e34f..0712899e39a44dea8d7f1ce516313dd9cd408311 100644 --- a/drivers/media/dvb/ttusb-dec/Kconfig +++ b/drivers/media/dvb/ttusb-dec/Kconfig @@ -1,6 +1,7 @@ config DVB_TTUSB_DEC tristate "Technotrend/Hauppauge USB DEC devices" depends on DVB_CORE && USB + depends on HOTPLUG # due to FW_LOADER select FW_LOADER select CRC32 help diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index fe743aa7f645fb611af3058775ad2b22bbd38081..89d8d37838a38a1b68e886c860c35d138955962d 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -44,6 +44,10 @@ config VIDEO_TVEEPROM tristate depends on I2C +config VIDEO_TUNER + tristate + depends on MEDIA_TUNER + # # Multimedia Video device configuration # @@ -690,7 +694,7 @@ config VIDEO_MXB tristate "Siemens-Nixdorf 'Multimedia eXtension Board'" depends on PCI && VIDEO_V4L1 && I2C select VIDEO_SAA7146_VV - select MEDIA_TUNER + select VIDEO_TUNER select VIDEO_SAA7111 if VIDEO_HELPER_CHIPS_AUTO select VIDEO_TDA9840 if VIDEO_HELPER_CHIPS_AUTO select VIDEO_TEA6415C if VIDEO_HELPER_CHIPS_AUTO @@ -906,7 +910,7 @@ config SOC_CAMERA config SOC_CAMERA_MT9M001 tristate "mt9m001 support" - depends on SOC_CAMERA + depends on SOC_CAMERA && I2C select GPIO_PCA953X if MT9M001_PCA9536_SWITCH help This driver supports MT9M001 cameras from Micron, monochrome @@ -921,7 +925,7 @@ config MT9M001_PCA9536_SWITCH config SOC_CAMERA_MT9V022 tristate "mt9v022 support" - depends on SOC_CAMERA + depends on SOC_CAMERA && I2C select GPIO_PCA953X if MT9V022_PCA9536_SWITCH help This driver supports MT9V022 cameras from Micron diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index a352c6e31f0cbf96496e68d8f6c86e12b7089c0a..dff0d6abe917f35ecb79eb7b381802361237ecde 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile @@ -84,7 +84,7 @@ obj-$(CONFIG_VIDEO_HEXIUM_GEMINI) += hexium_gemini.o obj-$(CONFIG_VIDEO_DPC) += dpc7146.o obj-$(CONFIG_TUNER_3036) += tuner-3036.o -obj-$(CONFIG_MEDIA_TUNER) += tuner.o +obj-$(CONFIG_VIDEO_TUNER) += tuner.o obj-$(CONFIG_VIDEOBUF_GEN) += videobuf-core.o obj-$(CONFIG_VIDEOBUF_DMA_SG) += videobuf-dma-sg.o diff --git a/drivers/media/video/au0828/Kconfig b/drivers/media/video/au0828/Kconfig index cab277fafa63a97831567d5c61db98b3d149f574..def10d08637303f1c71559ef264496a04ed33437 100644 --- a/drivers/media/video/au0828/Kconfig +++ b/drivers/media/video/au0828/Kconfig @@ -1,8 +1,9 @@ config VIDEO_AU0828 tristate "Auvitek AU0828 support" - depends on VIDEO_DEV && I2C && INPUT && DVB_CORE + depends on VIDEO_DEV && I2C && INPUT && DVB_CORE && USB select I2C_ALGOBIT + select VIDEO_TVEEPROM select DVB_AU8522 if !DVB_FE_CUSTOMIZE select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMIZE ---help--- diff --git a/drivers/media/video/au0828/au0828-dvb.c b/drivers/media/video/au0828/au0828-dvb.c index 1371b4e4b5f15230fd8025fb01db690c53e0dccd..c86a5f17eca81d6b7ff46b583c3121737f6c56d4 100644 --- a/drivers/media/video/au0828/au0828-dvb.c +++ b/drivers/media/video/au0828/au0828-dvb.c @@ -337,12 +337,10 @@ int au0828_dvb_register(struct au0828_dev *dev) dvb->frontend = dvb_attach(au8522_attach, &hauppauge_hvr950q_config, &dev->i2c_adap); - if (dvb->frontend != NULL) { - hauppauge_hvr950q_tunerconfig.priv = dev; + if (dvb->frontend != NULL) dvb_attach(xc5000_attach, dvb->frontend, &dev->i2c_adap, - &hauppauge_hvr950q_tunerconfig); - } + &hauppauge_hvr950q_tunerconfig, dev); break; default: printk(KERN_WARNING "The frontend of your DVB/ATSC card " diff --git a/drivers/media/video/bt8xx/Kconfig b/drivers/media/video/bt8xx/Kconfig index 7431ef6de9f1284f9d475678956fa8fe5ea6c7e1..24a34fc1f2b3bf9821359ce6e52878b3f5abeaba 100644 --- a/drivers/media/video/bt8xx/Kconfig +++ b/drivers/media/video/bt8xx/Kconfig @@ -1,12 +1,13 @@ config VIDEO_BT848 tristate "BT848 Video For Linux" depends on VIDEO_DEV && PCI && I2C && VIDEO_V4L2 && INPUT + depends on HOTPLUG # due to FW_LOADER select I2C_ALGOBIT select FW_LOADER select VIDEO_BTCX select VIDEOBUF_DMA_SG select VIDEO_IR - select MEDIA_TUNER + select VIDEO_TUNER select VIDEO_TVEEPROM select VIDEO_MSP3400 if VIDEO_HELPER_CHIPS_AUTO select VIDEO_TVAUDIO if VIDEO_HELPER_CHIPS_AUTO diff --git a/drivers/media/video/cs5345.c b/drivers/media/video/cs5345.c index 2a429f9e32cde03068e7ea72a0ddeb93316496e1..03411503457ed5ca01fc12148aa31049a40a533c 100644 --- a/drivers/media/video/cs5345.c +++ b/drivers/media/video/cs5345.c @@ -160,10 +160,17 @@ static int cs5345_probe(struct i2c_client *client, /* ----------------------------------------------------------------------- */ +static const struct i2c_device_id cs5345_id[] = { + { "cs5345", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, cs5345_id); + static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "cs5345", .driverid = I2C_DRIVERID_CS5345, .command = cs5345_command, .probe = cs5345_probe, + .id_table = cs5345_id, }; diff --git a/drivers/media/video/cs53l32a.c b/drivers/media/video/cs53l32a.c index 2dfd0afc62db2a72f29c180e11a291646049a3be..d965af860ab2636dfdc5f6b63da7f8a580237d42 100644 --- a/drivers/media/video/cs53l32a.c +++ b/drivers/media/video/cs53l32a.c @@ -144,7 +144,8 @@ static int cs53l32a_probe(struct i2c_client *client, if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -EIO; - snprintf(client->name, sizeof(client->name) - 1, "cs53l32a"); + if (!id) + strlcpy(client->name, "cs53l32a", sizeof(client->name)); v4l_info(client, "chip found @ 0x%x (%s)\n", client->addr << 1, client->adapter->name); @@ -175,10 +176,17 @@ static int cs53l32a_probe(struct i2c_client *client, return 0; } +static const struct i2c_device_id cs53l32a_id[] = { + { "cs53l32a", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, cs53l32a_id); + static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "cs53l32a", .driverid = I2C_DRIVERID_CS53L32A, .command = cs53l32a_command, .probe = cs53l32a_probe, + .id_table = cs53l32a_id, }; diff --git a/drivers/media/video/cx18/Kconfig b/drivers/media/video/cx18/Kconfig index acc4b47f1d1dc8437ba648c7509d78f3a71ebfed..5f942690570c2079626c15c113cdaa02538d3e05 100644 --- a/drivers/media/video/cx18/Kconfig +++ b/drivers/media/video/cx18/Kconfig @@ -1,14 +1,17 @@ config VIDEO_CX18 tristate "Conexant cx23418 MPEG encoder support" depends on VIDEO_V4L2 && DVB_CORE && PCI && I2C && EXPERIMENTAL + depends on INPUT # due to VIDEO_IR + depends on HOTPLUG # due to FW_LOADER select I2C_ALGOBIT select FW_LOADER select VIDEO_IR - select MEDIA_TUNER + select VIDEO_TUNER select VIDEO_TVEEPROM select VIDEO_CX2341X select VIDEO_CS5345 select DVB_S5H1409 + select MEDIA_TUNER_MXL5005S ---help--- This is a video4linux driver for Conexant cx23418 based PCI combo video recorder devices. diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c index f5e3ba1f5354153d7780d53bd530dda4456aea9a..553adbf2cd44eab938109121e1c388aa93a97f69 100644 --- a/drivers/media/video/cx18/cx18-cards.c +++ b/drivers/media/video/cx18/cx18-cards.c @@ -47,11 +47,12 @@ static struct cx18_card_tuner_i2c cx18_i2c_std = { static const struct cx18_card cx18_card_hvr1600_esmt = { .type = CX18_CARD_HVR_1600_ESMT, .name = "Hauppauge HVR-1600", - .comment = "DVB & VBI are not yet supported\n", + .comment = "VBI is not yet supported\n", .v4l2_capabilities = CX18_CAP_ENCODER, .hw_audio_ctrl = CX18_HW_CX23418, .hw_muxer = CX18_HW_CS5345, - .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER | CX18_HW_CS5345, + .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER | + CX18_HW_CS5345 | CX18_HW_DVB, .video_inputs = { { CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE7 }, { CX18_CARD_INPUT_SVIDEO1, 1, CX23418_SVIDEO1 }, @@ -86,11 +87,12 @@ static const struct cx18_card cx18_card_hvr1600_esmt = { static const struct cx18_card cx18_card_hvr1600_samsung = { .type = CX18_CARD_HVR_1600_SAMSUNG, .name = "Hauppauge HVR-1600 (Preproduction)", - .comment = "DVB & VBI are not yet supported\n", + .comment = "VBI is not yet supported\n", .v4l2_capabilities = CX18_CAP_ENCODER, .hw_audio_ctrl = CX18_HW_CX23418, .hw_muxer = CX18_HW_CS5345, - .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER | CX18_HW_CS5345, + .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER | + CX18_HW_CS5345 | CX18_HW_DVB, .video_inputs = { { CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE7 }, { CX18_CARD_INPUT_SVIDEO1, 1, CX23418_SVIDEO1 }, @@ -134,14 +136,15 @@ static const struct cx18_card_pci_info cx18_pci_h900[] = { static const struct cx18_card cx18_card_h900 = { .type = CX18_CARD_COMPRO_H900, .name = "Compro VideoMate H900", - .comment = "Not yet supported!\n", - .v4l2_capabilities = 0, + .comment = "DVB & VBI are not yet supported\n", + .v4l2_capabilities = CX18_CAP_ENCODER, .hw_audio_ctrl = CX18_HW_CX23418, .hw_all = CX18_HW_TUNER, .video_inputs = { - { CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE7 }, - { CX18_CARD_INPUT_SVIDEO1, 1, CX23418_SVIDEO1 }, - { CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE3 }, + { CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE2 }, + { CX18_CARD_INPUT_SVIDEO1, 1, + CX23418_SVIDEO_LUMA3 | CX23418_SVIDEO_CHROMA4 }, + { CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE1 }, }, .audio_inputs = { { CX18_CARD_INPUT_AUD_TUNER, @@ -163,6 +166,7 @@ static const struct cx18_card cx18_card_h900 = { .tune_lane = 0, .initial_emrs = 0, }, + .xceive_pin = 15, .pci_list = cx18_pci_h900, .i2c = &cx18_i2c_std, }; @@ -200,8 +204,6 @@ static const struct cx18_card cx18_card_mpc718 = { /* XC3028 tuner */ { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, }, - /* tuner reset */ - .gpio_init = { .direction = 0x1000, .initial_value = 0x1000 }, .ddr = { /* Probably Samsung K4D263238G-VC33 memory */ .chip_config = 0x003, @@ -211,6 +213,7 @@ static const struct cx18_card cx18_card_mpc718 = { .tune_lane = 0, .initial_emrs = 2, }, + .xceive_pin = 15, .pci_list = cx18_pci_mpc718, .i2c = &cx18_i2c_std, }; diff --git a/drivers/media/video/cx18/cx18-cards.h b/drivers/media/video/cx18/cx18-cards.h index bca249bdd337020888c40541c72d92079c3728a9..bccb67f0db16415a1efd6ffef20909b9d42cd46d 100644 --- a/drivers/media/video/cx18/cx18-cards.h +++ b/drivers/media/video/cx18/cx18-cards.h @@ -114,8 +114,8 @@ struct cx18_card_pci_info { /* The mask is the set of bits used by the operation */ struct cx18_gpio_init { /* set initial GPIO DIR and OUT values */ - u16 direction; /* DIR setting. Leave to 0 if no init is needed */ - u16 initial_value; + u32 direction; /* DIR setting. Leave to 0 if no init is needed */ + u32 initial_value; }; struct cx18_card_tuner { @@ -153,6 +153,7 @@ struct cx18_card { struct cx18_card_audio_input radio_input; /* GPIO card-specific settings */ + u8 xceive_pin; /* XCeive tuner GPIO reset pin */ struct cx18_gpio_init gpio_init; struct cx18_card_tuner tuners[CX18_CARD_MAX_TUNERS]; diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c index 8f5ed9b4bf8327df434285194730f888d2a83a8b..0dd4e05299706f83171de37a47ea801fbf8939b9 100644 --- a/drivers/media/video/cx18/cx18-driver.c +++ b/drivers/media/video/cx18/cx18-driver.c @@ -164,16 +164,6 @@ MODULE_LICENSE("GPL"); MODULE_VERSION(CX18_VERSION); -int cx18_waitq(wait_queue_head_t *waitq) -{ - DEFINE_WAIT(wait); - - prepare_to_wait(waitq, &wait, TASK_INTERRUPTIBLE); - schedule(); - finish_wait(waitq, &wait); - return signal_pending(current) ? -EINTR : 0; -} - /* Generic utility functions */ int cx18_msleep_timeout(unsigned int msecs, int intr) { @@ -220,13 +210,13 @@ static void cx18_process_eeprom(struct cx18 *cx) /* Many thanks to Steven Toth from Hauppauge for providing the model numbers */ + /* Note: the Samsung memory models cannot be reliably determined + from the model number. Use the cardtype module option if you + have one of these preproduction models. */ switch (tv.model) { - case 74000 ... 74099: + case 74000 ... 74999: cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT); break; - case 74700 ... 74799: - cx->card = cx18_get_card(CX18_CARD_HVR_1600_SAMSUNG); - break; case 0: CX18_ERR("Invalid EEPROM\n"); return; @@ -548,6 +538,7 @@ static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *dev, return 0; } +#ifdef MODULE static u32 cx18_request_module(struct cx18 *cx, u32 hw, const char *name, u32 id) { @@ -560,18 +551,21 @@ static u32 cx18_request_module(struct cx18 *cx, u32 hw, CX18_DEBUG_INFO("Loaded module %s\n", name); return hw; } +#endif static void cx18_load_and_init_modules(struct cx18 *cx) { u32 hw = cx->card->hw_all; int i; +#ifdef MODULE /* load modules */ #ifndef CONFIG_MEDIA_TUNER hw = cx18_request_module(cx, hw, "tuner", CX18_HW_TUNER); #endif #ifndef CONFIG_VIDEO_CS5345 hw = cx18_request_module(cx, hw, "cs5345", CX18_HW_CS5345); +#endif #endif /* check which i2c devices are actually found */ @@ -613,7 +607,7 @@ static int __devinit cx18_probe(struct pci_dev *dev, } cx = kzalloc(sizeof(struct cx18), GFP_ATOMIC); - if (cx == 0) { + if (!cx) { spin_unlock(&cx18_cards_lock); return -ENOMEM; } @@ -801,7 +795,7 @@ static int __devinit cx18_probe(struct pci_dev *dev, return 0; free_streams: - cx18_streams_cleanup(cx); + cx18_streams_cleanup(cx, 1); free_irq: free_irq(cx->dev->irq, (void *)cx); free_i2c: @@ -904,14 +898,13 @@ static void cx18_remove(struct pci_dev *pci_dev) cx18_halt_firmware(cx); - cx18_streams_cleanup(cx); + cx18_streams_cleanup(cx, 1); exit_cx18_i2c(cx); free_irq(cx->dev->irq, (void *)cx); - if (cx->dev) - cx18_iounmap(cx); + cx18_iounmap(cx); release_mem_region(cx->base_addr, CX18_MEM_SIZE); diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h index 2ee939193bb7361783c23e3c7bb4e3cfa2f9ccec..a2a6c58d12fe55ffcb3b1d7be1aebb85603d62b1 100644 --- a/drivers/media/video/cx18/cx18-driver.h +++ b/drivers/media/video/cx18/cx18-driver.h @@ -444,9 +444,6 @@ extern spinlock_t cx18_cards_lock; /* Return non-zero if a signal is pending */ int cx18_msleep_timeout(unsigned int msecs, int intr); -/* Wait on queue, returns -EINTR if interrupted */ -int cx18_waitq(wait_queue_head_t *waitq); - /* Read Hauppauge eeprom */ struct tveeprom; /* forward reference */ void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv); diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c index 65efe69d939a83513d4c5fc79fa2edbb3e63bf08..c9744173f9692d635455d844beb7a2f9aef2020a 100644 --- a/drivers/media/video/cx18/cx18-dvb.c +++ b/drivers/media/video/cx18/cx18-dvb.c @@ -24,25 +24,27 @@ #include "cx18-streams.h" #include "cx18-cards.h" #include "s5h1409.h" - -/* Wait until the MXL500X driver is merged */ -#ifdef HAVE_MXL500X -#include "mxl500x.h" -#endif +#include "mxl5005s.h" DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); #define CX18_REG_DMUX_NUM_PORT_0_CONTROL 0xd5a000 -#ifdef HAVE_MXL500X -static struct mxl500x_config hauppauge_hvr1600_tuner = { - .delsys = MXL500x_MODE_ATSC, - .octf = MXL500x_OCTF_CH, - .xtal_freq = 16000000, - .iflo_freq = 5380000, - .ref_freq = 322800000, - .rssi_ena = MXL_RSSI_ENABLE, - .addr = 0xC6 >> 1, +static struct mxl5005s_config hauppauge_hvr1600_tuner = { + .i2c_address = 0xC6 >> 1, + .if_freq = IF_FREQ_5380000HZ, + .xtal_freq = CRYSTAL_FREQ_16000000HZ, + .agc_mode = MXL_SINGLE_AGC, + .tracking_filter = MXL_TF_C_H, + .rssi_enable = MXL_RSSI_ENABLE, + .cap_select = MXL_CAP_SEL_ENABLE, + .div_out = MXL_DIV_OUT_4, + .clock_out = MXL_CLOCK_OUT_DISABLE, + .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM, + .top = MXL5005S_TOP_25P2, + .mod_mode = MXL_DIGITAL_MODE, + .if_mode = MXL_ZERO_IF, + .AgcMasterByte = 0x00, }; static struct s5h1409_config hauppauge_hvr1600_config = { @@ -55,7 +57,6 @@ static struct s5h1409_config hauppauge_hvr1600_config = { .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK }; -#endif static int dvb_register(struct cx18_stream *stream); @@ -252,21 +253,18 @@ static int dvb_register(struct cx18_stream *stream) int ret = 0; switch (cx->card->type) { -/* Wait until the MXL500X driver is merged */ -#ifdef HAVE_MXL500X case CX18_CARD_HVR_1600_ESMT: case CX18_CARD_HVR_1600_SAMSUNG: dvb->fe = dvb_attach(s5h1409_attach, &hauppauge_hvr1600_config, &cx->i2c_adap[0]); if (dvb->fe != NULL) { - dvb_attach(mxl500x_attach, dvb->fe, - &hauppauge_hvr1600_tuner, - &cx->i2c_adap[0]); + dvb_attach(mxl5005s_attach, dvb->fe, + &cx->i2c_adap[0], + &hauppauge_hvr1600_tuner); ret = 0; } break; -#endif default: /* No Digital Tv Support */ break; diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c index 69303065a2948f45b8f4ff01195a098d73250a9a..0b3141db174bbf4473b158d81882af7c2e8415b0 100644 --- a/drivers/media/video/cx18/cx18-fileops.c +++ b/drivers/media/video/cx18/cx18-fileops.c @@ -39,7 +39,7 @@ associated VBI streams are also automatically claimed. Possible error returns: -EBUSY if someone else has claimed the stream or 0 on success. */ -int cx18_claim_stream(struct cx18_open_id *id, int type) +static int cx18_claim_stream(struct cx18_open_id *id, int type) { struct cx18 *cx = id->cx; struct cx18_stream *s = &cx->streams[type]; @@ -87,7 +87,7 @@ int cx18_claim_stream(struct cx18_open_id *id, int type) /* This function releases a previously claimed stream. It will take into account associated VBI streams. */ -void cx18_release_stream(struct cx18_stream *s) +static void cx18_release_stream(struct cx18_stream *s) { struct cx18 *cx = s->cx; struct cx18_stream *s_vbi; @@ -662,6 +662,8 @@ int cx18_v4l2_open(struct inode *inode, struct file *filp) for (x = 0; cx == NULL && x < cx18_cards_active; x++) { /* find out which stream this open was on */ for (y = 0; y < CX18_MAX_STREAMS; y++) { + if (cx18_cards[x] == NULL) + continue; s = &cx18_cards[x]->streams[y]; if (s->v4l2dev && s->v4l2dev->minor == minor) { cx = cx18_cards[x]; diff --git a/drivers/media/video/cx18/cx18-fileops.h b/drivers/media/video/cx18/cx18-fileops.h index 16cdafbd24c5c137016c12965fdfad3f94835dfb..46da0282fc7d71bf9b1c324226989e29229c665e 100644 --- a/drivers/media/video/cx18/cx18-fileops.h +++ b/drivers/media/video/cx18/cx18-fileops.h @@ -34,12 +34,3 @@ void cx18_stop_capture(struct cx18_open_id *id, int gop_end); void cx18_mute(struct cx18 *cx); void cx18_unmute(struct cx18 *cx); -/* Utilities */ - -/* Try to claim a stream for the filehandle. Return 0 on success, - -EBUSY if stream already claimed. Once a stream is claimed, it - remains claimed until the associated filehandle is closed. */ -int cx18_claim_stream(struct cx18_open_id *id, int type); - -/* Release a previously claimed stream. */ -void cx18_release_stream(struct cx18_stream *s); diff --git a/drivers/media/video/cx18/cx18-gpio.c b/drivers/media/video/cx18/cx18-gpio.c index 19253e6b86738f7d05c0bbac1b768dcd21cf57a4..bb8bc86086d0925c3a693bdce698524a48245265 100644 --- a/drivers/media/video/cx18/cx18-gpio.c +++ b/drivers/media/video/cx18/cx18-gpio.c @@ -35,6 +35,9 @@ #define CX18_REG_GPIO_OUT2 0xc78104 #define CX18_REG_GPIO_DIR2 0xc7810c +static u32 gpio_dir; +static u32 gpio_val; + /* * HVR-1600 GPIO pins, courtesy of Hauppauge: * @@ -44,31 +47,53 @@ * gpio13: cs5345 reset pin */ +static void gpio_write(struct cx18 *cx) +{ + write_reg((gpio_dir & 0xffff) << 16, CX18_REG_GPIO_DIR1); + write_reg(((gpio_dir & 0xffff) << 16) | (gpio_val & 0xffff), + CX18_REG_GPIO_OUT1); + write_reg(gpio_dir & 0xffff0000, CX18_REG_GPIO_DIR2); + write_reg((gpio_dir & 0xffff0000) | ((gpio_val & 0xffff0000) >> 16), + CX18_REG_GPIO_OUT2); +} + void cx18_gpio_init(struct cx18 *cx) { - if (cx->card->gpio_init.direction == 0) + gpio_dir = cx->card->gpio_init.direction; + gpio_val = cx->card->gpio_init.initial_value; + + if (gpio_dir == 0) return; - CX18_DEBUG_INFO("GPIO initial dir: %08x out: %08x\n", - read_reg(CX18_REG_GPIO_DIR1), read_reg(CX18_REG_GPIO_OUT1)); + gpio_dir |= 1 << cx->card->xceive_pin; + gpio_val |= 1 << cx->card->xceive_pin; - /* init output data then direction */ - write_reg(cx->card->gpio_init.direction << 16, CX18_REG_GPIO_DIR1); - write_reg(0, CX18_REG_GPIO_DIR2); - write_reg((cx->card->gpio_init.direction << 16) | - cx->card->gpio_init.initial_value, CX18_REG_GPIO_OUT1); - write_reg(0, CX18_REG_GPIO_OUT2); + CX18_DEBUG_INFO("GPIO initial dir: %08x/%08x out: %08x/%08x\n", + read_reg(CX18_REG_GPIO_DIR1), read_reg(CX18_REG_GPIO_DIR2), + read_reg(CX18_REG_GPIO_OUT1), read_reg(CX18_REG_GPIO_OUT2)); + + gpio_write(cx); } /* Xceive tuner reset function */ int cx18_reset_tuner_gpio(void *dev, int cmd, int value) { struct i2c_algo_bit_data *algo = dev; - struct cx18 *cx = algo->data; -/* int curdir, curout;*/ + struct cx18_i2c_algo_callback_data *cb_data = algo->data; + struct cx18 *cx = cb_data->cx; if (cmd != XC2028_TUNER_RESET) return 0; CX18_DEBUG_INFO("Resetting tuner\n"); + + gpio_dir |= 1 << cx->card->xceive_pin; + gpio_val &= ~(1 << cx->card->xceive_pin); + + gpio_write(cx); + schedule_timeout_interruptible(msecs_to_jiffies(1)); + + gpio_val |= 1 << cx->card->xceive_pin; + gpio_write(cx); + schedule_timeout_interruptible(msecs_to_jiffies(1)); return 0; } diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c index 18c88d1e4833840e3eb83763550c544cfcecaa46..1d6c51a753137652028763005bc3c318404e4011 100644 --- a/drivers/media/video/cx18/cx18-i2c.c +++ b/drivers/media/video/cx18/cx18-i2c.c @@ -25,6 +25,7 @@ #include "cx18-cards.h" #include "cx18-gpio.h" #include "cx18-av-core.h" +#include "cx18-i2c.h" #include @@ -73,7 +74,7 @@ static const u8 hw_bus[] = { }; /* This array should match the CX18_HW_ defines */ -static const char * const hw_drivernames[] = { +static const char * const hw_devicenames[] = { "tuner", "tveeprom", "cs5345", @@ -94,8 +95,7 @@ int cx18_i2c_register(struct cx18 *cx, unsigned idx) id = hw_driverids[idx]; bus = hw_bus[idx]; memset(&info, 0, sizeof(info)); - strlcpy(info.driver_name, hw_drivernames[idx], - sizeof(info.driver_name)); + strlcpy(info.type, hw_devicenames[idx], sizeof(info.type)); info.addr = hw_addrs[idx]; for (i = 0; i < I2C_CLIENTS_MAX; i++) if (cx->i2c_clients[i] == NULL) @@ -278,7 +278,7 @@ static const char *cx18_i2c_id_name(u32 id) for (i = 0; i < ARRAY_SIZE(hw_driverids); i++) if (hw_driverids[i] == id) - return hw_drivernames[i]; + return hw_devicenames[i]; return "unknown device"; } @@ -289,7 +289,7 @@ static const char *cx18_i2c_hw_name(u32 hw) for (i = 0; i < ARRAY_SIZE(hw_driverids); i++) if (1 << i == hw) - return hw_drivernames[i]; + return hw_devicenames[i]; return "unknown device"; } diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c index 65af1bb507ca16343fe4271183ab1018b709c6d2..6990b77c6200ab57ab29bb1a2962a67930ff1392 100644 --- a/drivers/media/video/cx18/cx18-queue.c +++ b/drivers/media/video/cx18/cx18-queue.c @@ -26,17 +26,6 @@ #include "cx18-queue.h" #include "cx18-scb.h" -int cx18_buf_copy_from_user(struct cx18_stream *s, struct cx18_buffer *buf, - const char __user *src, int copybytes) -{ - if (s->buf_size - buf->bytesused < copybytes) - copybytes = s->buf_size - buf->bytesused; - if (copy_from_user(buf->buf + buf->bytesused, src, copybytes)) - return -EFAULT; - buf->bytesused += copybytes; - return copybytes; -} - void cx18_buf_swap(struct cx18_buffer *buf) { int i; @@ -159,8 +148,9 @@ static void cx18_queue_move_buf(struct cx18_stream *s, struct cx18_queue *from, -ENOMEM is returned if the buffers could not be obtained, 0 if all buffers where obtained from the 'from' list and if non-zero then the number of stolen buffers is returned. */ -int cx18_queue_move(struct cx18_stream *s, struct cx18_queue *from, - struct cx18_queue *steal, struct cx18_queue *to, int needed_bytes) +static int cx18_queue_move(struct cx18_stream *s, struct cx18_queue *from, + struct cx18_queue *steal, struct cx18_queue *to, + int needed_bytes) { unsigned long flags; int rc = 0; @@ -239,12 +229,12 @@ int cx18_stream_alloc(struct cx18_stream *s) /* allocate stream buffers. Initially all buffers are in q_free. */ for (i = 0; i < s->buffers; i++) { - struct cx18_buffer *buf = - kzalloc(sizeof(struct cx18_buffer), GFP_KERNEL); + struct cx18_buffer *buf = kzalloc(sizeof(struct cx18_buffer), + GFP_KERNEL|__GFP_NOWARN); if (buf == NULL) break; - buf->buf = kmalloc(s->buf_size, GFP_KERNEL); + buf->buf = kmalloc(s->buf_size, GFP_KERNEL|__GFP_NOWARN); if (buf->buf == NULL) { kfree(buf); break; diff --git a/drivers/media/video/cx18/cx18-queue.h b/drivers/media/video/cx18/cx18-queue.h index f86c8a6fa6e7690bec9552f8fd4f560d96d75fe0..91423b9863a43a402d6fe7c6efe5b347d059d355 100644 --- a/drivers/media/video/cx18/cx18-queue.h +++ b/drivers/media/video/cx18/cx18-queue.h @@ -39,8 +39,6 @@ static inline void cx18_buf_sync_for_device(struct cx18_stream *s, s->buf_size, s->dma); } -int cx18_buf_copy_from_user(struct cx18_stream *s, struct cx18_buffer *buf, - const char __user *src, int copybytes); void cx18_buf_swap(struct cx18_buffer *buf); /* cx18_queue utility functions */ @@ -48,8 +46,6 @@ void cx18_queue_init(struct cx18_queue *q); void cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf, struct cx18_queue *q); struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q); -int cx18_queue_move(struct cx18_stream *s, struct cx18_queue *from, - struct cx18_queue *steal, struct cx18_queue *to, int needed_bytes); struct cx18_buffer *cx18_queue_find_buf(struct cx18_stream *s, u32 id, u32 bytesused); void cx18_flush_queues(struct cx18_stream *s); diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c index afb141b2027ae146024dc5bbf767bfb86e72a9b8..4ca9d847f1b1863703f8421212aae1ce8f493070 100644 --- a/drivers/media/video/cx18/cx18-streams.c +++ b/drivers/media/video/cx18/cx18-streams.c @@ -218,7 +218,7 @@ int cx18_streams_setup(struct cx18 *cx) return 0; /* One or more streams could not be initialized. Clean 'em all up. */ - cx18_streams_cleanup(cx); + cx18_streams_cleanup(cx, 0); return -ENOMEM; } @@ -296,12 +296,12 @@ int cx18_streams_register(struct cx18 *cx) return 0; /* One or more streams could not be initialized. Clean 'em all up. */ - cx18_streams_cleanup(cx); + cx18_streams_cleanup(cx, 1); return -ENOMEM; } /* Unregister v4l2 devices */ -void cx18_streams_cleanup(struct cx18 *cx) +void cx18_streams_cleanup(struct cx18 *cx, int unregister) { struct video_device *vdev; int type; @@ -319,8 +319,11 @@ void cx18_streams_cleanup(struct cx18 *cx) cx18_stream_free(&cx->streams[type]); - /* Unregister device */ - video_unregister_device(vdev); + /* Unregister or release device */ + if (unregister) + video_unregister_device(vdev); + else + video_device_release(vdev); } } diff --git a/drivers/media/video/cx18/cx18-streams.h b/drivers/media/video/cx18/cx18-streams.h index 8c7ba7d2fa79036b7d4b4506e39743ca00cace91..f327e947b24f069a9791e6b8e47e82156a1e34de 100644 --- a/drivers/media/video/cx18/cx18-streams.h +++ b/drivers/media/video/cx18/cx18-streams.h @@ -24,7 +24,7 @@ u32 cx18_find_handle(struct cx18 *cx); int cx18_streams_setup(struct cx18 *cx); int cx18_streams_register(struct cx18 *cx); -void cx18_streams_cleanup(struct cx18 *cx); +void cx18_streams_cleanup(struct cx18 *cx, int unregister); /* Capture related */ int cx18_start_v4l2_encode_stream(struct cx18_stream *s); diff --git a/drivers/media/video/cx23885/Kconfig b/drivers/media/video/cx23885/Kconfig index cadf936c367351fb249bef07ac1a8c42a547c987..7bf14c9a15c71f37456f1af1f600ca2f42cb5add 100644 --- a/drivers/media/video/cx23885/Kconfig +++ b/drivers/media/video/cx23885/Kconfig @@ -1,18 +1,20 @@ config VIDEO_CX23885 tristate "Conexant cx23885 (2388x successor) support" depends on DVB_CORE && VIDEO_DEV && PCI && I2C && INPUT + depends on HOTPLUG # due to FW_LOADER select I2C_ALGOBIT select FW_LOADER select VIDEO_BTCX - select MEDIA_TUNER + select VIDEO_TUNER select VIDEO_TVEEPROM select VIDEO_IR select VIDEOBUF_DVB select VIDEO_CX25840 + select VIDEO_CX2341X + select DVB_DIB7000P if !DVB_FE_CUSTOMISE select MEDIA_TUNER_MT2131 if !DVB_FE_CUSTOMISE select DVB_S5H1409 if !DVB_FE_CUSTOMISE select DVB_LGDT330X if !DVB_FE_CUSTOMISE - select DVB_PLL if !DVB_FE_CUSTOMISE select MEDIA_TUNER_XC2028 if !DVB_FE_CUSTOMIZE select MEDIA_TUNER_TDA8290 if !DVB_FE_CUSTOMIZE select MEDIA_TUNER_TDA18271 if !DVB_FE_CUSTOMIZE diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c index 6ebf58724a0134d27737b015a0acced695252ce0..20e05f230546b66979f65fde727f5f6d30c43203 100644 --- a/drivers/media/video/cx23885/cx23885-cards.c +++ b/drivers/media/video/cx23885/cx23885-cards.c @@ -198,6 +198,10 @@ struct cx23885_subid cx23885_subids[] = { .subvendor = 0x0070, .subdevice = 0x71d1, .card = CX23885_BOARD_HAUPPAUGE_HVR1200, + }, { + .subvendor = 0x0070, + .subdevice = 0x71d3, + .card = CX23885_BOARD_HAUPPAUGE_HVR1200, }, { .subvendor = 0x0070, .subdevice = 0x8101, @@ -245,6 +249,33 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data) /* Make sure we support the board model */ switch (tv.model) { + case 71009: + /* WinTV-HVR1200 (PCIe, Retail, full height) + * DVB-T and basic analog */ + case 71359: + /* WinTV-HVR1200 (PCIe, OEM, half height) + * DVB-T and basic analog */ + case 71439: + /* WinTV-HVR1200 (PCIe, OEM, half height) + * DVB-T and basic analog */ + case 71449: + /* WinTV-HVR1200 (PCIe, OEM, full height) + * DVB-T and basic analog */ + case 71939: + /* WinTV-HVR1200 (PCIe, OEM, half height) + * DVB-T and basic analog */ + case 71949: + /* WinTV-HVR1200 (PCIe, OEM, full height) + * DVB-T and basic analog */ + case 71959: + /* WinTV-HVR1200 (PCIe, OEM, full height) + * DVB-T and basic analog */ + case 71979: + /* WinTV-HVR1200 (PCIe, OEM, half height) + * DVB-T and basic analog */ + case 71999: + /* WinTV-HVR1200 (PCIe, OEM, full height) + * DVB-T and basic analog */ case 76601: /* WinTV-HVR1800lp (PCIe, Retail, No IR, Dual channel ATSC and MPEG2 HW Encoder */ case 77001: /* WinTV-HVR1500 (Express Card, OEM, No IR, ATSC and Basic analog */ case 77011: /* WinTV-HVR1500 (Express Card, Retail, No IR, ATSC and Basic analog */ @@ -263,8 +294,11 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data) case 80019: /* WinTV-HVR1400 (Express Card, Retail, IR, * DVB-T and Basic analog */ + case 81509: + /* WinTV-HVR1700 (PCIe, OEM, No IR, half height) + * DVB-T and MPEG2 HW Encoder */ case 81519: - /* WinTV-HVR1700 (PCIe, Retail, No IR, half height, + /* WinTV-HVR1700 (PCIe, OEM, No IR, full height) * DVB-T and MPEG2 HW Encoder */ break; default: diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c index f05649727b60d9d434c435589fb4f78baaea22e4..022aa391937a673b7780d16dae2e22cd25e14925 100644 --- a/drivers/media/video/cx23885/cx23885-dvb.c +++ b/drivers/media/video/cx23885/cx23885-dvb.c @@ -37,7 +37,6 @@ #include "lgdt330x.h" #include "xc5000.h" #include "tda10048.h" -#include "dvb-pll.h" #include "tuner-xc2028.h" #include "tuner-simple.h" #include "dib7000p.h" @@ -385,12 +384,10 @@ static int dvb_register(struct cx23885_tsport *port) port->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_hvr1500q_config, &dev->i2c_bus[0].i2c_adap); - if (port->dvb.frontend != NULL) { - hauppauge_hvr1500q_tunerconfig.priv = i2c_bus; + if (port->dvb.frontend != NULL) dvb_attach(xc5000_attach, port->dvb.frontend, &i2c_bus->i2c_adap, - &hauppauge_hvr1500q_tunerconfig); - } + &hauppauge_hvr1500q_tunerconfig, i2c_bus); break; case CX23885_BOARD_HAUPPAUGE_HVR1500: i2c_bus = &dev->i2c_bus[1]; diff --git a/drivers/media/video/cx25840/Kconfig b/drivers/media/video/cx25840/Kconfig index 7cf29a03ed63a9d3da53f9d3823627e86e23b47c..448f4cd0ce345e67f87c024683d7c6ec81dc2549 100644 --- a/drivers/media/video/cx25840/Kconfig +++ b/drivers/media/video/cx25840/Kconfig @@ -1,6 +1,7 @@ config VIDEO_CX25840 tristate "Conexant CX2584x audio/video decoders" depends on VIDEO_V4L2 && I2C && EXPERIMENTAL + depends on HOTPLUG # due to FW_LOADER select FW_LOADER ---help--- Support for the Conexant CX2584x audio/video decoders. diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index 88823810497ca3c002fa53e25801551f911c30a4..607efdcd22f8d0eeae68ba7a57b01c2c171293cd 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c @@ -1284,10 +1284,17 @@ static int cx25840_remove(struct i2c_client *client) return 0; } +static const struct i2c_device_id cx25840_id[] = { + { "cx25840", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, cx25840_id); + static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "cx25840", .driverid = I2C_DRIVERID_CX25840, .command = cx25840_command, .probe = cx25840_probe, .remove = cx25840_remove, + .id_table = cx25840_id, }; diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig index b0d7d6a7a4cc359dc725ee27b1ed3c5d87264d4e..10e20d8196dcfcf8cdb890269303dc43e600440e 100644 --- a/drivers/media/video/cx88/Kconfig +++ b/drivers/media/video/cx88/Kconfig @@ -2,10 +2,9 @@ config VIDEO_CX88 tristate "Conexant 2388x (bt878 successor) support" depends on VIDEO_DEV && PCI && I2C && INPUT select I2C_ALGOBIT - select FW_LOADER select VIDEO_BTCX select VIDEOBUF_DMA_SG - select MEDIA_TUNER + select VIDEO_TUNER select VIDEO_TVEEPROM select VIDEO_IR select VIDEO_WM8775 if VIDEO_HELPER_CHIPS_AUTO @@ -34,8 +33,9 @@ config VIDEO_CX88_ALSA config VIDEO_CX88_BLACKBIRD tristate "Blackbird MPEG encoder support (cx2388x + cx23416)" - depends on VIDEO_CX88 + depends on VIDEO_CX88 && HOTPLUG select VIDEO_CX2341X + select FW_LOADER ---help--- This adds support for MPEG encoder cards based on the Blackbird reference design, using the Conexant 2388x diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c index 1c7fe6862a60c05b3f758467bb7dba6fe001985a..d96173ff1dbac4a0096f854cdb0cc8008d4b8f7e 100644 --- a/drivers/media/video/cx88/cx88-dvb.c +++ b/drivers/media/video/cx88/cx88-dvb.c @@ -509,9 +509,6 @@ static int attach_xc3028(u8 addr, struct cx8802_dev *dev) if (!fe) { printk(KERN_ERR "%s/2: xc3028 attach failed\n", dev->core->name); - dvb_frontend_detach(dev->dvb.frontend); - dvb_unregister_frontend(dev->dvb.frontend); - dev->dvb.frontend = NULL; return -EINVAL; } @@ -523,20 +520,23 @@ static int attach_xc3028(u8 addr, struct cx8802_dev *dev) static int dvb_register(struct cx8802_dev *dev) { + struct cx88_core *core = dev->core; + /* init struct videobuf_dvb */ - dev->dvb.name = dev->core->name; + dev->dvb.name = core->name; dev->ts_gen_cntrl = 0x0c; /* init frontend */ - switch (dev->core->boardnr) { + switch (core->boardnr) { case CX88_BOARD_HAUPPAUGE_DVB_T1: dev->dvb.frontend = dvb_attach(cx22702_attach, &connexant_refboard_config, - &dev->core->i2c_adap); + &core->i2c_adap); if (dev->dvb.frontend != NULL) { - dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, - &dev->core->i2c_adap, - DVB_PLL_THOMSON_DTT759X); + if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, + 0x61, &core->i2c_adap, + DVB_PLL_THOMSON_DTT759X)) + goto frontend_detach; } break; case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: @@ -545,11 +545,12 @@ static int dvb_register(struct cx8802_dev *dev) case CX88_BOARD_WINFAST_DTV1000: dev->dvb.frontend = dvb_attach(cx22702_attach, &connexant_refboard_config, - &dev->core->i2c_adap); + &core->i2c_adap); if (dev->dvb.frontend != NULL) { - dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, - &dev->core->i2c_adap, - DVB_PLL_THOMSON_DTT7579); + if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, + 0x60, &core->i2c_adap, + DVB_PLL_THOMSON_DTT7579)) + goto frontend_detach; } break; case CX88_BOARD_WINFAST_DTV2000H: @@ -559,29 +560,32 @@ static int dvb_register(struct cx8802_dev *dev) case CX88_BOARD_HAUPPAUGE_HVR3000: dev->dvb.frontend = dvb_attach(cx22702_attach, &hauppauge_hvr_config, - &dev->core->i2c_adap); + &core->i2c_adap); if (dev->dvb.frontend != NULL) { - dvb_attach(simple_tuner_attach, dev->dvb.frontend, - &dev->core->i2c_adap, 0x61, - TUNER_PHILIPS_FMD1216ME_MK3); + if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, + &core->i2c_adap, 0x61, + TUNER_PHILIPS_FMD1216ME_MK3)) + goto frontend_detach; } break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: dev->dvb.frontend = dvb_attach(mt352_attach, &dvico_fusionhdtv, - &dev->core->i2c_adap); + &core->i2c_adap); if (dev->dvb.frontend != NULL) { - dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, - NULL, DVB_PLL_THOMSON_DTT7579); + if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, + 0x60, NULL, DVB_PLL_THOMSON_DTT7579)) + goto frontend_detach; break; } /* ZL10353 replaces MT352 on later cards */ dev->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_plus_v1_1, - &dev->core->i2c_adap); + &core->i2c_adap); if (dev->dvb.frontend != NULL) { - dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, - NULL, DVB_PLL_THOMSON_DTT7579); + if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, + 0x60, NULL, DVB_PLL_THOMSON_DTT7579)) + goto frontend_detach; } break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL: @@ -589,28 +593,31 @@ static int dvb_register(struct cx8802_dev *dev) * compatible, with a slightly different MT352 AGC gain. */ dev->dvb.frontend = dvb_attach(mt352_attach, &dvico_fusionhdtv_dual, - &dev->core->i2c_adap); + &core->i2c_adap); if (dev->dvb.frontend != NULL) { - dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, - NULL, DVB_PLL_THOMSON_DTT7579); + if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, + 0x61, NULL, DVB_PLL_THOMSON_DTT7579)) + goto frontend_detach; break; } /* ZL10353 replaces MT352 on later cards */ dev->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_plus_v1_1, - &dev->core->i2c_adap); + &core->i2c_adap); if (dev->dvb.frontend != NULL) { - dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, - NULL, DVB_PLL_THOMSON_DTT7579); + if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, + 0x61, NULL, DVB_PLL_THOMSON_DTT7579)) + goto frontend_detach; } break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: dev->dvb.frontend = dvb_attach(mt352_attach, &dvico_fusionhdtv, - &dev->core->i2c_adap); + &core->i2c_adap); if (dev->dvb.frontend != NULL) { - dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, - NULL, DVB_PLL_LG_Z201); + if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, + 0x61, NULL, DVB_PLL_LG_Z201)) + goto frontend_detach; } break; case CX88_BOARD_KWORLD_DVB_T: @@ -618,10 +625,11 @@ static int dvb_register(struct cx8802_dev *dev) case CX88_BOARD_ADSTECH_DVB_T_PCI: dev->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_config, - &dev->core->i2c_adap); + &core->i2c_adap); if (dev->dvb.frontend != NULL) { - dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, - NULL, DVB_PLL_UNKNOWN_1); + if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, + 0x61, NULL, DVB_PLL_UNKNOWN_1)) + goto frontend_detach; } break; case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: @@ -630,32 +638,35 @@ static int dvb_register(struct cx8802_dev *dev) dev->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config, &dev->vp3054->adap); if (dev->dvb.frontend != NULL) { - dvb_attach(simple_tuner_attach, dev->dvb.frontend, - &dev->core->i2c_adap, 0x61, - TUNER_PHILIPS_FMD1216ME_MK3); + if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, + &core->i2c_adap, 0x61, + TUNER_PHILIPS_FMD1216ME_MK3)) + goto frontend_detach; } #else - printk(KERN_ERR "%s/2: built without vp3054 support\n", dev->core->name); + printk(KERN_ERR "%s/2: built without vp3054 support\n", + core->name); #endif break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID: dev->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_hybrid, - &dev->core->i2c_adap); + &core->i2c_adap); if (dev->dvb.frontend != NULL) { - dvb_attach(simple_tuner_attach, dev->dvb.frontend, - &dev->core->i2c_adap, 0x61, - TUNER_THOMSON_FE6600); + if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, + &core->i2c_adap, 0x61, + TUNER_THOMSON_FE6600)) + goto frontend_detach; } break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO: dev->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_xc3028, - &dev->core->i2c_adap); + &core->i2c_adap); if (dev->dvb.frontend == NULL) dev->dvb.frontend = dvb_attach(mt352_attach, &dvico_fusionhdtv_mt352_xc3028, - &dev->core->i2c_adap); + &core->i2c_adap); /* * On this board, the demod provides the I2C bus pullup. * We must not permit gate_ctrl to be performed, or @@ -668,19 +679,18 @@ static int dvb_register(struct cx8802_dev *dev) break; case CX88_BOARD_PCHDTV_HD3000: dev->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000, - &dev->core->i2c_adap); + &core->i2c_adap); if (dev->dvb.frontend != NULL) { - dvb_attach(simple_tuner_attach, dev->dvb.frontend, - &dev->core->i2c_adap, 0x61, - TUNER_THOMSON_DTT761X); + if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, + &core->i2c_adap, 0x61, + TUNER_THOMSON_DTT761X)) + goto frontend_detach; } break; case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q: dev->ts_gen_cntrl = 0x08; - { - /* Do a hardware reset of chip before using it. */ - struct cx88_core *core = dev->core; + /* Do a hardware reset of chip before using it. */ cx_clear(MO_GP0_IO, 1); mdelay(100); cx_set(MO_GP0_IO, 1); @@ -690,139 +700,137 @@ static int dvb_register(struct cx8802_dev *dev) fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set; dev->dvb.frontend = dvb_attach(lgdt330x_attach, &fusionhdtv_3_gold, - &dev->core->i2c_adap); + &core->i2c_adap); if (dev->dvb.frontend != NULL) { - dvb_attach(simple_tuner_attach, dev->dvb.frontend, - &dev->core->i2c_adap, 0x61, - TUNER_MICROTUNE_4042FI5); - } + if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, + &core->i2c_adap, 0x61, + TUNER_MICROTUNE_4042FI5)) + goto frontend_detach; } break; case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T: dev->ts_gen_cntrl = 0x08; - { - /* Do a hardware reset of chip before using it. */ - struct cx88_core *core = dev->core; + /* Do a hardware reset of chip before using it. */ cx_clear(MO_GP0_IO, 1); mdelay(100); cx_set(MO_GP0_IO, 9); mdelay(200); dev->dvb.frontend = dvb_attach(lgdt330x_attach, &fusionhdtv_3_gold, - &dev->core->i2c_adap); + &core->i2c_adap); if (dev->dvb.frontend != NULL) { - dvb_attach(simple_tuner_attach, dev->dvb.frontend, - &dev->core->i2c_adap, 0x61, - TUNER_THOMSON_DTT761X); - } + if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, + &core->i2c_adap, 0x61, + TUNER_THOMSON_DTT761X)) + goto frontend_detach; } break; case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD: dev->ts_gen_cntrl = 0x08; - { - /* Do a hardware reset of chip before using it. */ - struct cx88_core *core = dev->core; + /* Do a hardware reset of chip before using it. */ cx_clear(MO_GP0_IO, 1); mdelay(100); cx_set(MO_GP0_IO, 1); mdelay(200); dev->dvb.frontend = dvb_attach(lgdt330x_attach, &fusionhdtv_5_gold, - &dev->core->i2c_adap); + &core->i2c_adap); if (dev->dvb.frontend != NULL) { - dvb_attach(simple_tuner_attach, dev->dvb.frontend, - &dev->core->i2c_adap, 0x61, - TUNER_LG_TDVS_H06XF); - dvb_attach(tda9887_attach, dev->dvb.frontend, - &dev->core->i2c_adap, 0x43); - } + if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, + &core->i2c_adap, 0x61, + TUNER_LG_TDVS_H06XF)) + goto frontend_detach; + if (!dvb_attach(tda9887_attach, dev->dvb.frontend, + &core->i2c_adap, 0x43)) + goto frontend_detach; } break; case CX88_BOARD_PCHDTV_HD5500: dev->ts_gen_cntrl = 0x08; - { - /* Do a hardware reset of chip before using it. */ - struct cx88_core *core = dev->core; + /* Do a hardware reset of chip before using it. */ cx_clear(MO_GP0_IO, 1); mdelay(100); cx_set(MO_GP0_IO, 1); mdelay(200); dev->dvb.frontend = dvb_attach(lgdt330x_attach, &pchdtv_hd5500, - &dev->core->i2c_adap); + &core->i2c_adap); if (dev->dvb.frontend != NULL) { - dvb_attach(simple_tuner_attach, dev->dvb.frontend, - &dev->core->i2c_adap, 0x61, - TUNER_LG_TDVS_H06XF); - dvb_attach(tda9887_attach, dev->dvb.frontend, - &dev->core->i2c_adap, 0x43); - } + if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, + &core->i2c_adap, 0x61, + TUNER_LG_TDVS_H06XF)) + goto frontend_detach; + if (!dvb_attach(tda9887_attach, dev->dvb.frontend, + &core->i2c_adap, 0x43)) + goto frontend_detach; } break; case CX88_BOARD_ATI_HDTVWONDER: dev->dvb.frontend = dvb_attach(nxt200x_attach, &ati_hdtvwonder, - &dev->core->i2c_adap); + &core->i2c_adap); if (dev->dvb.frontend != NULL) { - dvb_attach(simple_tuner_attach, dev->dvb.frontend, - &dev->core->i2c_adap, 0x61, - TUNER_PHILIPS_TUV1236D); + if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, + &core->i2c_adap, 0x61, + TUNER_PHILIPS_TUV1236D)) + goto frontend_detach; } break; case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: dev->dvb.frontend = dvb_attach(cx24123_attach, &hauppauge_novas_config, - &dev->core->i2c_adap); + &core->i2c_adap); if (dev->dvb.frontend) { - dvb_attach(isl6421_attach, dev->dvb.frontend, - &dev->core->i2c_adap, 0x08, 0x00, 0x00); + if (!dvb_attach(isl6421_attach, dev->dvb.frontend, + &core->i2c_adap, 0x08, 0x00, 0x00)) + goto frontend_detach; } break; case CX88_BOARD_KWORLD_DVBS_100: dev->dvb.frontend = dvb_attach(cx24123_attach, &kworld_dvbs_100_config, - &dev->core->i2c_adap); + &core->i2c_adap); if (dev->dvb.frontend) { - dev->core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; + core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; dev->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage; } break; case CX88_BOARD_GENIATECH_DVBS: dev->dvb.frontend = dvb_attach(cx24123_attach, &geniatech_dvbs_config, - &dev->core->i2c_adap); + &core->i2c_adap); if (dev->dvb.frontend) { - dev->core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; + core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; dev->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage; } break; case CX88_BOARD_PINNACLE_PCTV_HD_800i: dev->dvb.frontend = dvb_attach(s5h1409_attach, &pinnacle_pctv_hd_800i_config, - &dev->core->i2c_adap); + &core->i2c_adap); if (dev->dvb.frontend != NULL) { /* tuner_config.video_dev must point to * i2c_adap.algo_data */ - pinnacle_pctv_hd_800i_tuner_config.priv = - dev->core->i2c_adap.algo_data; - dvb_attach(xc5000_attach, dev->dvb.frontend, - &dev->core->i2c_adap, - &pinnacle_pctv_hd_800i_tuner_config); + if (!dvb_attach(xc5000_attach, dev->dvb.frontend, + &core->i2c_adap, + &pinnacle_pctv_hd_800i_tuner_config, + core->i2c_adap.algo_data)) + goto frontend_detach; } break; case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO: dev->dvb.frontend = dvb_attach(s5h1409_attach, &dvico_hdtv5_pci_nano_config, - &dev->core->i2c_adap); + &core->i2c_adap); if (dev->dvb.frontend != NULL) { struct dvb_frontend *fe; struct xc2028_config cfg = { - .i2c_adap = &dev->core->i2c_adap, + .i2c_adap = &core->i2c_adap, .i2c_addr = 0x61, .callback = cx88_pci_nano_callback, }; @@ -841,50 +849,50 @@ static int dvb_register(struct cx8802_dev *dev) case CX88_BOARD_PINNACLE_HYBRID_PCTV: dev->dvb.frontend = dvb_attach(zl10353_attach, &cx88_geniatech_x8000_mt, - &dev->core->i2c_adap); + &core->i2c_adap); if (attach_xc3028(0x61, dev) < 0) - return -EINVAL; + goto frontend_detach; break; case CX88_BOARD_GENIATECH_X8000_MT: dev->ts_gen_cntrl = 0x00; dev->dvb.frontend = dvb_attach(zl10353_attach, &cx88_geniatech_x8000_mt, - &dev->core->i2c_adap); + &core->i2c_adap); if (attach_xc3028(0x61, dev) < 0) - return -EINVAL; + goto frontend_detach; break; case CX88_BOARD_KWORLD_ATSC_120: dev->dvb.frontend = dvb_attach(s5h1409_attach, &kworld_atsc_120_config, - &dev->core->i2c_adap); + &core->i2c_adap); if (attach_xc3028(0x61, dev) < 0) - return -EINVAL; + goto frontend_detach; break; case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD: dev->dvb.frontend = dvb_attach(s5h1411_attach, &dvico_fusionhdtv7_config, - &dev->core->i2c_adap); + &core->i2c_adap); if (dev->dvb.frontend != NULL) { /* tuner_config.video_dev must point to * i2c_adap.algo_data */ - dvico_fusionhdtv7_tuner_config.priv = - dev->core->i2c_adap.algo_data; - dvb_attach(xc5000_attach, dev->dvb.frontend, - &dev->core->i2c_adap, - &dvico_fusionhdtv7_tuner_config); + if (!dvb_attach(xc5000_attach, dev->dvb.frontend, + &core->i2c_adap, + &dvico_fusionhdtv7_tuner_config, + core->i2c_adap.algo_data)) + goto frontend_detach; } break; default: printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n", - dev->core->name); + core->name); break; } if (NULL == dev->dvb.frontend) { printk(KERN_ERR "%s/2: frontend initialization failed\n", - dev->core->name); + core->name); return -EINVAL; } @@ -892,11 +900,18 @@ static int dvb_register(struct cx8802_dev *dev) dev->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl; /* Put the analog decoder in standby to keep it quiet */ - cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); + cx88_call_i2c_clients(core, TUNER_SET_STANDBY, NULL); /* register everything */ return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev, &dev->pci->dev, adapter_nr); + +frontend_detach: + if (dev->dvb.frontend) { + dvb_frontend_detach(dev->dvb.frontend); + dev->dvb.frontend = NULL; + } + return -EINVAL; } /* ----------------------------------------------------------- */ diff --git a/drivers/media/video/em28xx/Kconfig b/drivers/media/video/em28xx/Kconfig index c7c2896bbd8b312823d0abd9898c3ed8ee8e455f..16a5af30e9d1fd1e4184da4969d5956798f8a76a 100644 --- a/drivers/media/video/em28xx/Kconfig +++ b/drivers/media/video/em28xx/Kconfig @@ -1,7 +1,7 @@ config VIDEO_EM28XX tristate "Empia EM28xx USB video capture support" depends on VIDEO_DEV && I2C && INPUT - select MEDIA_TUNER + select VIDEO_TUNER select VIDEO_TVEEPROM select VIDEO_IR select VIDEOBUF_VMALLOC @@ -35,7 +35,6 @@ config VIDEO_EM28XX_DVB select DVB_LGDT330X if !DVB_FE_CUSTOMISE select DVB_ZL10353 if !DVB_FE_CUSTOMISE select VIDEOBUF_DVB - select FW_LOADER ---help--- This adds support for DVB cards based on the Empiatech em28xx chips. diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 50ccf377120488e0d61a40776b4e2a162b529915..3e4f3c7e92e78ee62231feaebde1628d0cae27ff 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -420,7 +420,13 @@ struct usb_device_id em28xx_id_table [] = { .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 }, { USB_DEVICE(0x2040, 0x6502), .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 }, - { USB_DEVICE(0x2040, 0x6513), + { USB_DEVICE(0x2040, 0x6513), /* HCW HVR-980 */ + .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 }, + { USB_DEVICE(0x2040, 0x6517), /* HP HVR-950 */ + .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 }, + { USB_DEVICE(0x2040, 0x651b), /* RP HVR-950 */ + .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 }, + { USB_DEVICE(0x2040, 0x651f), /* HCW HVR-850 */ .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 }, { USB_DEVICE(0x0ccd, 0x0042), .driver_info = EM2880_BOARD_TERRATEC_HYBRID_XS }, diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c index 7df81575b7f242c23937f7dbe71afb0fb5019a3c..8cf4983f0039602ce617fbe929a1edad032baa26 100644 --- a/drivers/media/video/em28xx/em28xx-dvb.c +++ b/drivers/media/video/em28xx/em28xx-dvb.c @@ -251,7 +251,6 @@ static int attach_xc3028(u8 addr, struct em28xx *dev) printk(KERN_ERR "%s/2: xc3028 attach failed\n", dev->name); dvb_frontend_detach(dev->dvb->frontend); - dvb_unregister_frontend(dev->dvb->frontend); dev->dvb->frontend = NULL; return -EINVAL; } diff --git a/drivers/media/video/et61x251/et61x251_core.c b/drivers/media/video/et61x251/et61x251_core.c index 5e749c528a624e7ea6babc290ede9dc041726e88..15d037ae25c5fed1700bdf589b9f8bb6136b5173 100644 --- a/drivers/media/video/et61x251/et61x251_core.c +++ b/drivers/media/video/et61x251/et61x251_core.c @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/media/video/ivtv/Kconfig b/drivers/media/video/ivtv/Kconfig index eec115bf9517a54342ea749323f14208020cd05f..5d7ee8fcdd50b3fd4b788ed0a48078a64e68d9ec 100644 --- a/drivers/media/video/ivtv/Kconfig +++ b/drivers/media/video/ivtv/Kconfig @@ -1,10 +1,12 @@ config VIDEO_IVTV tristate "Conexant cx23416/cx23415 MPEG encoder/decoder support" depends on VIDEO_V4L1 && VIDEO_V4L2 && PCI && I2C && EXPERIMENTAL + depends on INPUT # due to VIDEO_IR + depends on HOTPLUG # due to FW_LOADER select I2C_ALGOBIT select FW_LOADER select VIDEO_IR - select MEDIA_TUNER + select VIDEO_TUNER select VIDEO_TVEEPROM select VIDEO_CX2341X select VIDEO_CX25840 diff --git a/drivers/media/video/ivtv/ivtv-controls.c b/drivers/media/video/ivtv/ivtv-controls.c index 8c02fa661591fd063611795c1dd5236aedede43e..c7e449f6397bb9b3d6f91311ee82fbfa0289bdc9 100644 --- a/drivers/media/video/ivtv/ivtv-controls.c +++ b/drivers/media/video/ivtv/ivtv-controls.c @@ -181,12 +181,12 @@ static int ivtv_setup_vbi_fmt(struct ivtv *itv, enum v4l2_mpeg_stream_vbi_fmt fm return 0; } /* Need sliced data for mpeg insertion */ - if (get_service_set(itv->vbi.sliced_in) == 0) { + if (ivtv_get_service_set(itv->vbi.sliced_in) == 0) { if (itv->is_60hz) itv->vbi.sliced_in->service_set = V4L2_SLICED_CAPTION_525; else itv->vbi.sliced_in->service_set = V4L2_SLICED_WSS_625; - expand_service_set(itv->vbi.sliced_in, itv->is_50hz); + ivtv_expand_service_set(itv->vbi.sliced_in, itv->is_50hz); } return 0; } diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index ed020f722b05ec840bada9ecdd776406c8ef18f1..797e636771da07a38bc7025130a681371a09312f 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c @@ -853,6 +853,7 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *dev, return 0; } +#ifdef MODULE static u32 ivtv_request_module(struct ivtv *itv, u32 hw, const char *name, u32 id) { @@ -865,12 +866,14 @@ static u32 ivtv_request_module(struct ivtv *itv, u32 hw, IVTV_DEBUG_INFO("Loaded module %s\n", name); return hw; } +#endif static void ivtv_load_and_init_modules(struct ivtv *itv) { u32 hw = itv->card->hw_all; unsigned i; +#ifdef MODULE /* load modules */ #ifndef CONFIG_MEDIA_TUNER hw = ivtv_request_module(itv, hw, "tuner", IVTV_HW_TUNER); @@ -910,6 +913,7 @@ static void ivtv_load_and_init_modules(struct ivtv *itv) #endif #ifndef CONFIG_VIDEO_M52790 hw = ivtv_request_module(itv, hw, "m52790", IVTV_HW_M52790); +#endif #endif /* check which i2c devices are actually found */ @@ -1228,7 +1232,7 @@ static int __devinit ivtv_probe(struct pci_dev *dev, return 0; free_streams: - ivtv_streams_cleanup(itv); + ivtv_streams_cleanup(itv, 1); free_irq: free_irq(itv->dev->irq, (void *)itv); free_i2c: @@ -1373,7 +1377,7 @@ static void ivtv_remove(struct pci_dev *pci_dev) flush_workqueue(itv->irq_work_queues); destroy_workqueue(itv->irq_work_queues); - ivtv_streams_cleanup(itv); + ivtv_streams_cleanup(itv, 1); ivtv_udma_free(itv); exit_ivtv_i2c(itv); diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c index 2b74b0ab147788c7942d5af34dfe1beeb954f904..f2fa434b677b88673ef4e7335b10f2f92f02d095 100644 --- a/drivers/media/video/ivtv/ivtv-fileops.c +++ b/drivers/media/video/ivtv/ivtv-fileops.c @@ -987,6 +987,8 @@ int ivtv_v4l2_open(struct inode *inode, struct file *filp) /* Find which card this open was on */ spin_lock(&ivtv_cards_lock); for (x = 0; itv == NULL && x < ivtv_cards_active; x++) { + if (ivtv_cards[x] == NULL) + continue; /* find out which stream this open was on */ for (y = 0; y < IVTV_MAX_STREAMS; y++) { s = &ivtv_cards[x]->streams[y]; diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c index 771adf47e944ff1379f4264db37f4a17b4dc210b..32129f3ea836630e3388ba1ade85b92ee0257b68 100644 --- a/drivers/media/video/ivtv/ivtv-i2c.c +++ b/drivers/media/video/ivtv/ivtv-i2c.c @@ -136,7 +136,7 @@ static const u8 hw_addrs[] = { }; /* This array should match the IVTV_HW_ defines */ -static const char * const hw_drivernames[] = { +static const char * const hw_devicenames[] = { "cx25840", "saa7115", "saa7127", @@ -145,7 +145,7 @@ static const char * const hw_drivernames[] = { "wm8775", "cs53l32a", "tveeprom", - "saa7115", + "saa7114", "upd64031a", "upd64083", "saa717x", @@ -167,8 +167,7 @@ int ivtv_i2c_register(struct ivtv *itv, unsigned idx) return -1; id = hw_driverids[idx]; memset(&info, 0, sizeof(info)); - strlcpy(info.driver_name, hw_drivernames[idx], - sizeof(info.driver_name)); + strlcpy(info.type, hw_devicenames[idx], sizeof(info.type)); info.addr = hw_addrs[idx]; for (i = 0; itv->i2c_clients[i] && i < I2C_CLIENTS_MAX; i++) {} @@ -657,7 +656,7 @@ static const char *ivtv_i2c_id_name(u32 id) for (i = 0; i < ARRAY_SIZE(hw_driverids); i++) if (hw_driverids[i] == id) - return hw_drivernames[i]; + return hw_devicenames[i]; return "unknown device"; } @@ -668,7 +667,7 @@ static const char *ivtv_i2c_hw_name(u32 hw) for (i = 0; i < ARRAY_SIZE(hw_driverids); i++) if (1 << i == hw) - return hw_drivernames[i]; + return hw_devicenames[i]; return "unknown device"; } @@ -770,7 +769,7 @@ int init_ivtv_i2c(struct ivtv *itv) * same size and GPIO must be the last entry. */ if (ARRAY_SIZE(hw_driverids) != ARRAY_SIZE(hw_addrs) || - ARRAY_SIZE(hw_drivernames) != ARRAY_SIZE(hw_addrs) || + ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_addrs) || IVTV_HW_GPIO != (1 << (ARRAY_SIZE(hw_addrs) - 1)) || hw_driverids[ARRAY_SIZE(hw_addrs) - 1]) { IVTV_ERR("Mismatched I2C hardware arrays\n"); diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index d508b5d0538cfb71bfa9b7b2c137eebfcbdaafd4..26cc0f6699fdc9d44bfcdce386d2533f3cc06227 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c @@ -38,7 +38,7 @@ #include #include -u16 service2vbi(int type) +u16 ivtv_service2vbi(int type) { switch (type) { case V4L2_SLICED_TELETEXT_B: @@ -88,7 +88,7 @@ static u16 select_service_from_set(int field, int line, u16 set, int is_pal) return 0; } -void expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal) +void ivtv_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal) { u16 set = fmt->service_set; int f, l; @@ -115,7 +115,7 @@ static int check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal) return set != 0; } -u16 get_service_set(struct v4l2_sliced_vbi_format *fmt) +u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt) { int f, l; u16 set = 0; @@ -466,7 +466,7 @@ static int ivtv_get_fmt(struct ivtv *itv, int streamtype, struct v4l2_format *fm vbifmt->service_lines[0][23] = V4L2_SLICED_WSS_625; vbifmt->service_lines[0][16] = V4L2_SLICED_VPS; } - vbifmt->service_set = get_service_set(vbifmt); + vbifmt->service_set = ivtv_get_service_set(vbifmt); break; } @@ -481,12 +481,12 @@ static int ivtv_get_fmt(struct ivtv *itv, int streamtype, struct v4l2_format *fm if (streamtype == IVTV_DEC_STREAM_TYPE_VBI) { vbifmt->service_set = itv->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525; - expand_service_set(vbifmt, itv->is_50hz); + ivtv_expand_service_set(vbifmt, itv->is_50hz); break; } itv->video_dec_func(itv, VIDIOC_G_FMT, fmt); - vbifmt->service_set = get_service_set(vbifmt); + vbifmt->service_set = ivtv_get_service_set(vbifmt); break; } case V4L2_BUF_TYPE_VBI_OUTPUT: @@ -640,9 +640,9 @@ static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype, memset(vbifmt->reserved, 0, sizeof(vbifmt->reserved)); if (vbifmt->service_set) - expand_service_set(vbifmt, itv->is_50hz); + ivtv_expand_service_set(vbifmt, itv->is_50hz); set = check_service_set(vbifmt, itv->is_50hz); - vbifmt->service_set = get_service_set(vbifmt); + vbifmt->service_set = ivtv_get_service_set(vbifmt); if (!set_fmt) return 0; diff --git a/drivers/media/video/ivtv/ivtv-ioctl.h b/drivers/media/video/ivtv/ivtv-ioctl.h index a03351b6853d8fe9f8663b1995179e8ad7d26bf8..4e67f0ed1fc0458d1020fb2826835296de092167 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.h +++ b/drivers/media/video/ivtv/ivtv-ioctl.h @@ -21,9 +21,9 @@ #ifndef IVTV_IOCTL_H #define IVTV_IOCTL_H -u16 service2vbi(int type); -void expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal); -u16 get_service_set(struct v4l2_sliced_vbi_format *fmt); +u16 ivtv_service2vbi(int type); +void ivtv_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal); +u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt); int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void *arg); diff --git a/drivers/media/video/ivtv/ivtv-queue.c b/drivers/media/video/ivtv/ivtv-queue.c index 3e1deec67a5e33d8f12ba141546946eec6db4436..fc8b1eaa333b38ac0b03d0458aed478e4a71343d 100644 --- a/drivers/media/video/ivtv/ivtv-queue.c +++ b/drivers/media/video/ivtv/ivtv-queue.c @@ -203,14 +203,14 @@ int ivtv_stream_alloc(struct ivtv_stream *s) s->dma != PCI_DMA_NONE ? "DMA " : "", s->name, s->buffers, s->buf_size, s->buffers * s->buf_size / 1024); - s->sg_pending = kzalloc(SGsize, GFP_KERNEL); + s->sg_pending = kzalloc(SGsize, GFP_KERNEL|__GFP_NOWARN); if (s->sg_pending == NULL) { IVTV_ERR("Could not allocate sg_pending for %s stream\n", s->name); return -ENOMEM; } s->sg_pending_size = 0; - s->sg_processing = kzalloc(SGsize, GFP_KERNEL); + s->sg_processing = kzalloc(SGsize, GFP_KERNEL|__GFP_NOWARN); if (s->sg_processing == NULL) { IVTV_ERR("Could not allocate sg_processing for %s stream\n", s->name); kfree(s->sg_pending); @@ -219,7 +219,8 @@ int ivtv_stream_alloc(struct ivtv_stream *s) } s->sg_processing_size = 0; - s->sg_dma = kzalloc(sizeof(struct ivtv_sg_element), GFP_KERNEL); + s->sg_dma = kzalloc(sizeof(struct ivtv_sg_element), + GFP_KERNEL|__GFP_NOWARN); if (s->sg_dma == NULL) { IVTV_ERR("Could not allocate sg_dma for %s stream\n", s->name); kfree(s->sg_pending); @@ -235,11 +236,12 @@ int ivtv_stream_alloc(struct ivtv_stream *s) /* allocate stream buffers. Initially all buffers are in q_free. */ for (i = 0; i < s->buffers; i++) { - struct ivtv_buffer *buf = kzalloc(sizeof(struct ivtv_buffer), GFP_KERNEL); + struct ivtv_buffer *buf = kzalloc(sizeof(struct ivtv_buffer), + GFP_KERNEL|__GFP_NOWARN); if (buf == NULL) break; - buf->buf = kmalloc(s->buf_size + 256, GFP_KERNEL); + buf->buf = kmalloc(s->buf_size + 256, GFP_KERNEL|__GFP_NOWARN); if (buf->buf == NULL) { kfree(buf); break; diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c index 4ab8d36831ba427e477e984b457d967824493443..c47c2b9451474c1dffa24c1757fe1e9d0d69994d 100644 --- a/drivers/media/video/ivtv/ivtv-streams.c +++ b/drivers/media/video/ivtv/ivtv-streams.c @@ -244,7 +244,7 @@ int ivtv_streams_setup(struct ivtv *itv) return 0; /* One or more streams could not be initialized. Clean 'em all up. */ - ivtv_streams_cleanup(itv); + ivtv_streams_cleanup(itv, 0); return -ENOMEM; } @@ -304,12 +304,12 @@ int ivtv_streams_register(struct ivtv *itv) return 0; /* One or more streams could not be initialized. Clean 'em all up. */ - ivtv_streams_cleanup(itv); + ivtv_streams_cleanup(itv, 1); return -ENOMEM; } /* Unregister v4l2 devices */ -void ivtv_streams_cleanup(struct ivtv *itv) +void ivtv_streams_cleanup(struct ivtv *itv, int unregister) { int type; @@ -322,8 +322,11 @@ void ivtv_streams_cleanup(struct ivtv *itv) continue; ivtv_stream_free(&itv->streams[type]); - /* Unregister device */ - video_unregister_device(vdev); + /* Unregister or release device */ + if (unregister) + video_unregister_device(vdev); + else + video_device_release(vdev); } } diff --git a/drivers/media/video/ivtv/ivtv-streams.h b/drivers/media/video/ivtv/ivtv-streams.h index 3d76a415fbd8892a1b425873259177a1314d2d02..a653a5136417df1bbf7eb4abdbb3789a3cd55bc8 100644 --- a/drivers/media/video/ivtv/ivtv-streams.h +++ b/drivers/media/video/ivtv/ivtv-streams.h @@ -23,7 +23,7 @@ int ivtv_streams_setup(struct ivtv *itv); int ivtv_streams_register(struct ivtv *itv); -void ivtv_streams_cleanup(struct ivtv *itv); +void ivtv_streams_cleanup(struct ivtv *itv, int unregister); /* Capture related */ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s); diff --git a/drivers/media/video/ivtv/ivtv-vbi.c b/drivers/media/video/ivtv/ivtv-vbi.c index c151bcf5519ae92be2fd189b8f3856f593c04e74..71798f0da27f9172f4dc3d34027b37a786b7966e 100644 --- a/drivers/media/video/ivtv/ivtv-vbi.c +++ b/drivers/media/video/ivtv/ivtv-vbi.c @@ -169,7 +169,8 @@ static void copy_vbi_data(struct ivtv *itv, int lines, u32 pts_stamp) linemask[0] |= (1 << l); else linemask[1] |= (1 << (l - 32)); - dst[sd + 12 + line * 43] = service2vbi(itv->vbi.sliced_data[i].id); + dst[sd + 12 + line * 43] = + ivtv_service2vbi(itv->vbi.sliced_data[i].id); memcpy(dst + sd + 12 + line * 43 + 1, itv->vbi.sliced_data[i].data, 42); line++; } diff --git a/drivers/media/video/ivtv/ivtv-yuv.c b/drivers/media/video/ivtv/ivtv-yuv.c index 62f70bd5e3cb149f47ec1199ba3381d9574735a9..a9417f6e40870d8837411a109f9ddf240c1ffb13 100644 --- a/drivers/media/video/ivtv/ivtv-yuv.c +++ b/drivers/media/video/ivtv/ivtv-yuv.c @@ -908,7 +908,7 @@ static void ivtv_yuv_init(struct ivtv *itv) } /* We need a buffer for blanking when Y plane is offset - non-fatal if we can't get one */ - yi->blanking_ptr = kzalloc(720 * 16, GFP_KERNEL); + yi->blanking_ptr = kzalloc(720 * 16, GFP_KERNEL|__GFP_NOWARN); if (yi->blanking_ptr) { yi->blanking_dmaptr = pci_map_single(itv->dev, yi->blanking_ptr, 720*16, PCI_DMA_TODEVICE); } else { diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c index df789f683e63ce1402f34725f0fe16ccb11e824a..73be154f7f0520666c977140bf8a3047b72b7061 100644 --- a/drivers/media/video/ivtv/ivtvfb.c +++ b/drivers/media/video/ivtv/ivtvfb.c @@ -948,7 +948,8 @@ static int ivtvfb_init_vidmode(struct ivtv *itv) } /* Allocate the pseudo palette */ - oi->ivtvfb_info.pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL); + oi->ivtvfb_info.pseudo_palette = + kmalloc(sizeof(u32) * 16, GFP_KERNEL|__GFP_NOWARN); if (!oi->ivtvfb_info.pseudo_palette) { IVTVFB_ERR("abort, unable to alloc pseudo pallete\n"); @@ -1056,7 +1057,8 @@ static int ivtvfb_init_card(struct ivtv *itv) return -EBUSY; } - itv->osd_info = kzalloc(sizeof(struct osd_info), GFP_ATOMIC); + itv->osd_info = kzalloc(sizeof(struct osd_info), + GFP_ATOMIC|__GFP_NOWARN); if (itv->osd_info == NULL) { IVTVFB_ERR("Failed to allocate memory for osd_info\n"); return -ENOMEM; diff --git a/drivers/media/video/m52790.c b/drivers/media/video/m52790.c index 5b9dfa2c51b43874e8b9045379ee685260982720..8e0160d275ca53aaf3ac27874bfa62dcfd3a7799 100644 --- a/drivers/media/video/m52790.c +++ b/drivers/media/video/m52790.c @@ -135,8 +135,6 @@ static int m52790_probe(struct i2c_client *client, if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -EIO; - snprintf(client->name, sizeof(client->name) - 1, "m52790"); - v4l_info(client, "chip found @ 0x%x (%s)\n", client->addr << 1, client->adapter->name); @@ -159,11 +157,18 @@ static int m52790_remove(struct i2c_client *client) /* ----------------------------------------------------------------------- */ +static const struct i2c_device_id m52790_id[] = { + { "m52790", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, m52790_id); + static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "m52790", .driverid = I2C_DRIVERID_M52790, .command = m52790_command, .probe = m52790_probe, .remove = m52790_remove, + .id_table = m52790_id, }; diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c index e6273162e12379e4ae054dfeb410458267f3c83a..310dbaba55ff325264675a1f56d79f463e2144cd 100644 --- a/drivers/media/video/msp3400-driver.c +++ b/drivers/media/video/msp3400-driver.c @@ -815,7 +815,8 @@ static int msp_probe(struct i2c_client *client, const struct i2c_device_id *id) int msp_product, msp_prod_hi, msp_prod_lo; int msp_rom; - snprintf(client->name, sizeof(client->name) - 1, "msp3400"); + if (!id) + strlcpy(client->name, "msp3400", sizeof(client->name)); if (msp_reset(client) == -1) { v4l_dbg(1, msp_debug, client, "msp3400 not found\n"); @@ -864,9 +865,6 @@ static int msp_probe(struct i2c_client *client, const struct i2c_device_id *id) msp_revision = (state->rev1 & 0x0f) + '@'; msp_hard = ((state->rev1 >> 8) & 0xff) + '@'; msp_rom = state->rev2 & 0x1f; - snprintf(client->name, sizeof(client->name), "MSP%d4%02d%c-%c%d", - msp_family, msp_product, - msp_revision, msp_hard, msp_rom); /* Rev B=2, C=3, D=4, G=7 */ state->ident = msp_family * 10000 + 4000 + msp_product * 10 + msp_revision - '@'; @@ -931,7 +929,9 @@ static int msp_probe(struct i2c_client *client, const struct i2c_device_id *id) } /* hello world :-) */ - v4l_info(client, "%s found @ 0x%x (%s)\n", client->name, + v4l_info(client, "MSP%d4%02d%c-%c%d found @ 0x%x (%s)\n", + msp_family, msp_product, + msp_revision, msp_hard, msp_rom, client->addr << 1, client->adapter->name); v4l_info(client, "%s ", client->name); if (state->has_nicam && state->has_radio) @@ -987,6 +987,12 @@ static int msp_remove(struct i2c_client *client) /* ----------------------------------------------------------------------- */ +static const struct i2c_device_id msp_id[] = { + { "msp3400", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, msp_id); + static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "msp3400", .driverid = I2C_DRIVERID_MSP3400, @@ -995,6 +1001,7 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = { .remove = msp_remove, .suspend = msp_suspend, .resume = msp_resume, + .id_table = msp_id, }; diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c index 179e47049a452ff1619d977d4bc44779a1b00847..ee43499544c13d9f01cd12d1c973762099475db8 100644 --- a/drivers/media/video/mt9m001.c +++ b/drivers/media/video/mt9m001.c @@ -12,15 +12,12 @@ #include #include #include +#include #include #include #include -#ifdef CONFIG_MT9M001_PCA9536_SWITCH -#include -#endif - /* mt9m001 i2c address 0x5d * The platform has to define i2c_board_info * and call i2c_register_board_info() */ diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c index d1391ac550963b14ebeb2e52e9470c5215501bfd..1658fe5903928d076612e888ceb0be2d15641f0a 100644 --- a/drivers/media/video/mt9v022.c +++ b/drivers/media/video/mt9v022.c @@ -13,15 +13,12 @@ #include #include #include +#include #include #include #include -#ifdef CONFIG_MT9M001_PCA9536_SWITCH -#include -#endif - /* mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c * The platform has to define i2c_board_info * and call i2c_register_board_info() */ @@ -91,7 +88,7 @@ static const struct soc_camera_data_format mt9v022_monochrome_formats[] = { struct mt9v022 { struct i2c_client *client; struct soc_camera_device icd; - int model; /* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */ + int model; /* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */ int switch_gpio; u16 chip_control; unsigned char datawidth; diff --git a/drivers/media/video/pvrusb2/Kconfig b/drivers/media/video/pvrusb2/Kconfig index 9620c67fae77050f442dd024f186915affda8353..4482b2c72cedb3c8a1cbe3a212b7317186615ef3 100644 --- a/drivers/media/video/pvrusb2/Kconfig +++ b/drivers/media/video/pvrusb2/Kconfig @@ -1,8 +1,10 @@ config VIDEO_PVRUSB2 tristate "Hauppauge WinTV-PVR USB2 support" depends on VIDEO_V4L2 && I2C + depends on VIDEO_MEDIA # Avoids pvrusb = Y / DVB = M + depends on HOTPLUG # due to FW_LOADER select FW_LOADER - select MEDIA_TUNER + select VIDEO_TUNER select VIDEO_TVEEPROM select VIDEO_CX2341X select VIDEO_SAA711X diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c index e684108637add93351b42fb005f27cc9da5be7da..435c083cc542af91af65a2fca0cac67cae643e94 100644 --- a/drivers/media/video/saa7115.c +++ b/drivers/media/video/saa7115.c @@ -1456,14 +1456,13 @@ static int saa7115_probe(struct i2c_client *client, struct saa711x_state *state; int i; char name[17]; - u8 chip_id; + char chip_id; + int autodetect = !id || id->driver_data == 1; /* Check if the adapter supports the needed features */ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -EIO; - snprintf(client->name, sizeof(client->name) - 1, "saa7115"); - for (i = 0; i < 0x0f; i++) { saa711x_write(client, 0, i); name[i] = (saa711x_read(client, 0) & 0x0f) + '0'; @@ -1472,8 +1471,7 @@ static int saa7115_probe(struct i2c_client *client, } name[i] = '\0'; - saa711x_write(client, 0, 5); - chip_id = saa711x_read(client, 0) & 0x0f; + chip_id = name[5]; /* Check whether this chip is part of the saa711x series */ if (memcmp(name, "1f711", 5)) { @@ -1482,8 +1480,14 @@ static int saa7115_probe(struct i2c_client *client, return -ENODEV; } - snprintf(client->name, sizeof(client->name) - 1, "saa711%d",chip_id); - v4l_info(client, "saa711%d found (%s) @ 0x%x (%s)\n", chip_id, name, client->addr << 1, client->adapter->name); + /* Safety check */ + if (!autodetect && id->name[6] != chip_id) { + v4l_warn(client, "found saa711%c while %s was expected\n", + chip_id, id->name); + } + snprintf(client->name, sizeof(client->name), "saa711%c", chip_id); + v4l_info(client, "saa711%c found (%s) @ 0x%x (%s)\n", chip_id, name, + client->addr << 1, client->adapter->name); state = kzalloc(sizeof(struct saa711x_state), GFP_KERNEL); i2c_set_clientdata(client, state); @@ -1499,19 +1503,19 @@ static int saa7115_probe(struct i2c_client *client, state->hue = 0; state->sat = 64; switch (chip_id) { - case 1: + case '1': state->ident = V4L2_IDENT_SAA7111; break; - case 3: + case '3': state->ident = V4L2_IDENT_SAA7113; break; - case 4: + case '4': state->ident = V4L2_IDENT_SAA7114; break; - case 5: + case '5': state->ident = V4L2_IDENT_SAA7115; break; - case 8: + case '8': state->ident = V4L2_IDENT_SAA7118; break; default: @@ -1553,6 +1557,17 @@ static int saa7115_remove(struct i2c_client *client) return 0; } +static const struct i2c_device_id saa7115_id[] = { + { "saa711x", 1 }, /* autodetect */ + { "saa7111", 0 }, + { "saa7113", 0 }, + { "saa7114", 0 }, + { "saa7115", 0 }, + { "saa7118", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, saa7115_id); + static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "saa7115", .driverid = I2C_DRIVERID_SAA711X, @@ -1560,5 +1575,6 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = { .probe = saa7115_probe, .remove = saa7115_remove, .legacy_class = I2C_CLASS_TV_ANALOG | I2C_CLASS_TV_DIGITAL, + .id_table = saa7115_id, }; diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c index e750cd65c1c37676612c1955c9674ad5b232ebb5..79d11a658bdfff44b12e9128a0d3e0f5624d6e1d 100644 --- a/drivers/media/video/saa7127.c +++ b/drivers/media/video/saa7127.c @@ -672,8 +672,6 @@ static int saa7127_probe(struct i2c_client *client, if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -EIO; - snprintf(client->name, sizeof(client->name) - 1, "saa7127"); - v4l_dbg(1, debug, client, "detecting saa7127 client on address 0x%x\n", client->addr << 1); @@ -741,11 +739,18 @@ static int saa7127_remove(struct i2c_client *client) /* ----------------------------------------------------------------------- */ +static struct i2c_device_id saa7127_id[] = { + { "saa7127", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, saa7127_id); + static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "saa7127", .driverid = I2C_DRIVERID_SAA7127, .command = saa7127_command, .probe = saa7127_probe, .remove = saa7127_remove, + .id_table = saa7127_id, }; diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig index 40e4c3bd2cb9b39a6b764793f3286801454e508c..83f076abce35193acf230ec73bcdd9fb87807c6c 100644 --- a/drivers/media/video/saa7134/Kconfig +++ b/drivers/media/video/saa7134/Kconfig @@ -3,7 +3,7 @@ config VIDEO_SAA7134 depends on VIDEO_DEV && PCI && I2C && INPUT select VIDEOBUF_DMA_SG select VIDEO_IR - select MEDIA_TUNER + select VIDEO_TUNER select VIDEO_TVEEPROM select CRC32 ---help--- @@ -27,6 +27,7 @@ config VIDEO_SAA7134_ALSA config VIDEO_SAA7134_DVB tristate "DVB/ATSC Support for saa7134 based TV cards" depends on VIDEO_SAA7134 && DVB_CORE + depends on HOTPLUG # due to FW_LOADER select VIDEOBUF_DVB select FW_LOADER select DVB_PLL if !DVB_FE_CUSTOMISE diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index eec127864fe3e710832a34275c337b51819cf53b..2c19cd0113c8d2e1faa1b54493562b456a8ed3c4 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c @@ -864,7 +864,6 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, struct saa7134_dev *dev; struct saa7134_mpeg_ops *mops; int err; - int mask; if (saa7134_devcount == SAA7134_MAXBOARDS) return -ENOMEM; @@ -1065,11 +1064,6 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, if (TUNER_ABSENT != dev->tuner_type) saa7134_i2c_call_clients(dev, TUNER_SET_STANDBY, NULL); - if (card(dev).gpiomask != 0) { - mask = card(dev).gpiomask; - saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, mask, mask); - saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, mask, 0); - } return 0; fail4: diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index 2d16be2259dbb6182b10d84b54585bfc66e81ed5..469f93aac0083a1e049cb55bc27ed985ca31596d 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c @@ -538,19 +538,23 @@ static int philips_tda827x_tuner_sleep(struct dvb_frontend *fe) return 0; } -static void configure_tda827x_fe(struct saa7134_dev *dev, struct tda1004x_config *cdec_conf, - struct tda827x_config *tuner_conf) +static int configure_tda827x_fe(struct saa7134_dev *dev, + struct tda1004x_config *cdec_conf, + struct tda827x_config *tuner_conf) { dev->dvb.frontend = dvb_attach(tda10046_attach, cdec_conf, &dev->i2c_adap); if (dev->dvb.frontend) { if (cdec_conf->i2c_gate) dev->dvb.frontend->ops.i2c_gate_ctrl = tda8290_i2c_gate_ctrl; - if (dvb_attach(tda827x_attach, dev->dvb.frontend, cdec_conf->tuner_address, - &dev->i2c_adap, tuner_conf) == NULL) { - wprintk("no tda827x tuner found at addr: %02x\n", + if (dvb_attach(tda827x_attach, dev->dvb.frontend, + cdec_conf->tuner_address, + &dev->i2c_adap, tuner_conf)) + return 0; + + wprintk("no tda827x tuner found at addr: %02x\n", cdec_conf->tuner_address); - } } + return -EINVAL; } /* ------------------------------------------------------------------ */ @@ -997,7 +1001,9 @@ static int dvb_init(struct saa7134_dev *dev) break; case SAA7134_BOARD_FLYDVBTDUO: case SAA7134_BOARD_FLYDVBT_DUO_CARDBUS: - configure_tda827x_fe(dev, &tda827x_lifeview_config, &tda827x_cfg_0); + if (configure_tda827x_fe(dev, &tda827x_lifeview_config, + &tda827x_cfg_0) < 0) + goto dettach_frontend; break; case SAA7134_BOARD_PHILIPS_EUROPA: case SAA7134_BOARD_VIDEOMATE_DVBT_300: @@ -1022,36 +1028,52 @@ static int dvb_init(struct saa7134_dev *dev) } break; case SAA7134_BOARD_KWORLD_DVBT_210: - configure_tda827x_fe(dev, &kworld_dvb_t_210_config, &tda827x_cfg_2); + if (configure_tda827x_fe(dev, &kworld_dvb_t_210_config, + &tda827x_cfg_2) < 0) + goto dettach_frontend; break; case SAA7134_BOARD_PHILIPS_TIGER: - configure_tda827x_fe(dev, &philips_tiger_config, &tda827x_cfg_0); + if (configure_tda827x_fe(dev, &philips_tiger_config, + &tda827x_cfg_0) < 0) + goto dettach_frontend; break; case SAA7134_BOARD_PINNACLE_PCTV_310i: - configure_tda827x_fe(dev, &pinnacle_pctv_310i_config, &tda827x_cfg_1); + if (configure_tda827x_fe(dev, &pinnacle_pctv_310i_config, + &tda827x_cfg_1) < 0) + goto dettach_frontend; break; case SAA7134_BOARD_HAUPPAUGE_HVR1110: - configure_tda827x_fe(dev, &hauppauge_hvr_1110_config, &tda827x_cfg_1); + if (configure_tda827x_fe(dev, &hauppauge_hvr_1110_config, + &tda827x_cfg_1) < 0) + goto dettach_frontend; break; case SAA7134_BOARD_ASUSTeK_P7131_DUAL: - configure_tda827x_fe(dev, &asus_p7131_dual_config, &tda827x_cfg_0); + if (configure_tda827x_fe(dev, &asus_p7131_dual_config, + &tda827x_cfg_0) < 0) + goto dettach_frontend; break; case SAA7134_BOARD_FLYDVBT_LR301: - configure_tda827x_fe(dev, &tda827x_lifeview_config, &tda827x_cfg_0); + if (configure_tda827x_fe(dev, &tda827x_lifeview_config, + &tda827x_cfg_0) < 0) + goto dettach_frontend; break; case SAA7134_BOARD_FLYDVB_TRIO: - if(! use_frontend) { /* terrestrial */ - configure_tda827x_fe(dev, &lifeview_trio_config, &tda827x_cfg_0); + if (!use_frontend) { /* terrestrial */ + if (configure_tda827x_fe(dev, &lifeview_trio_config, + &tda827x_cfg_0) < 0) + goto dettach_frontend; } else { /* satellite */ dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap); if (dev->dvb.frontend) { if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x63, &dev->i2c_adap, 0) == NULL) { wprintk("%s: Lifeview Trio, No tda826x found!\n", __func__); + goto dettach_frontend; } if (dvb_attach(isl6421_attach, dev->dvb.frontend, &dev->i2c_adap, 0x08, 0, 0) == NULL) { wprintk("%s: Lifeview Trio, No ISL6421 found!\n", __func__); + goto dettach_frontend; } } } @@ -1067,15 +1089,20 @@ static int dvb_init(struct saa7134_dev *dev) &ads_duo_cfg) == NULL) { wprintk("no tda827x tuner found at addr: %02x\n", ads_tech_duo_config.tuner_address); + goto dettach_frontend; } } break; case SAA7134_BOARD_TEVION_DVBT_220RF: - configure_tda827x_fe(dev, &tevion_dvbt220rf_config, &tda827x_cfg_0); + if (configure_tda827x_fe(dev, &tevion_dvbt220rf_config, + &tda827x_cfg_0) < 0) + goto dettach_frontend; break; case SAA7134_BOARD_MEDION_MD8800_QUADRO: if (!use_frontend) { /* terrestrial */ - configure_tda827x_fe(dev, &md8800_dvbt_config, &tda827x_cfg_0); + if (configure_tda827x_fe(dev, &md8800_dvbt_config, + &tda827x_cfg_0) < 0) + goto dettach_frontend; } else { /* satellite */ dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap); @@ -1086,16 +1113,20 @@ static int dvb_init(struct saa7134_dev *dev) struct i2c_msg msg = {.addr = 0x08, .flags = 0, .len = 1}; if (dvb_attach(tda826x_attach, dev->dvb.frontend, - 0x60, &dev->i2c_adap, 0) == NULL) + 0x60, &dev->i2c_adap, 0) == NULL) { wprintk("%s: Medion Quadro, no tda826x " "found !\n", __func__); + goto dettach_frontend; + } if (dev_id != 0x08) { /* we need to open the i2c gate (we know it exists) */ fe->ops.i2c_gate_ctrl(fe, 1); if (dvb_attach(isl6405_attach, fe, - &dev->i2c_adap, 0x08, 0, 0) == NULL) + &dev->i2c_adap, 0x08, 0, 0) == NULL) { wprintk("%s: Medion Quadro, no ISL6405 " "found !\n", __func__); + goto dettach_frontend; + } if (dev_id == 0x07) { /* fire up the 2nd section of the LNB supply since we can't do this from the other section */ @@ -1117,19 +1148,17 @@ static int dvb_init(struct saa7134_dev *dev) case SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180: dev->dvb.frontend = dvb_attach(nxt200x_attach, &avertvhda180, &dev->i2c_adap); - if (dev->dvb.frontend) { + if (dev->dvb.frontend) dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, NULL, DVB_PLL_TDHU2); - } break; case SAA7134_BOARD_KWORLD_ATSC110: dev->dvb.frontend = dvb_attach(nxt200x_attach, &kworldatsc110, &dev->i2c_adap); - if (dev->dvb.frontend) { + if (dev->dvb.frontend) dvb_attach(simple_tuner_attach, dev->dvb.frontend, &dev->i2c_adap, 0x61, TUNER_PHILIPS_TUV1236D); - } break; case SAA7134_BOARD_FLYDVBS_LR300: dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, @@ -1138,10 +1167,12 @@ static int dvb_init(struct saa7134_dev *dev) if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x60, &dev->i2c_adap, 0) == NULL) { wprintk("%s: No tda826x found!\n", __func__); + goto dettach_frontend; } if (dvb_attach(isl6421_attach, dev->dvb.frontend, &dev->i2c_adap, 0x08, 0, 0) == NULL) { wprintk("%s: No ISL6421 found!\n", __func__); + goto dettach_frontend; } } break; @@ -1168,43 +1199,65 @@ static int dvb_init(struct saa7134_dev *dev) } break; case SAA7134_BOARD_CINERGY_HT_PCMCIA: - configure_tda827x_fe(dev, &cinergy_ht_config, &tda827x_cfg_0); + if (configure_tda827x_fe(dev, &cinergy_ht_config, + &tda827x_cfg_0) < 0) + goto dettach_frontend; break; case SAA7134_BOARD_CINERGY_HT_PCI: - configure_tda827x_fe(dev, &cinergy_ht_pci_config, &tda827x_cfg_0); + if (configure_tda827x_fe(dev, &cinergy_ht_pci_config, + &tda827x_cfg_0) < 0) + goto dettach_frontend; break; case SAA7134_BOARD_PHILIPS_TIGER_S: - configure_tda827x_fe(dev, &philips_tiger_s_config, &tda827x_cfg_2); + if (configure_tda827x_fe(dev, &philips_tiger_s_config, + &tda827x_cfg_2) < 0) + goto dettach_frontend; break; case SAA7134_BOARD_ASUS_P7131_4871: - configure_tda827x_fe(dev, &asus_p7131_4871_config, &tda827x_cfg_2); + if (configure_tda827x_fe(dev, &asus_p7131_4871_config, + &tda827x_cfg_2) < 0) + goto dettach_frontend; break; case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA: - configure_tda827x_fe(dev, &asus_p7131_hybrid_lna_config, &tda827x_cfg_2); + if (configure_tda827x_fe(dev, &asus_p7131_hybrid_lna_config, + &tda827x_cfg_2) < 0) + goto dettach_frontend; break; case SAA7134_BOARD_AVERMEDIA_SUPER_007: - configure_tda827x_fe(dev, &avermedia_super_007_config, &tda827x_cfg_0); + if (configure_tda827x_fe(dev, &avermedia_super_007_config, + &tda827x_cfg_0) < 0) + goto dettach_frontend; break; case SAA7134_BOARD_TWINHAN_DTV_DVB_3056: - configure_tda827x_fe(dev, &twinhan_dtv_dvb_3056_config, &tda827x_cfg_2_sw42); + if (configure_tda827x_fe(dev, &twinhan_dtv_dvb_3056_config, + &tda827x_cfg_2_sw42) < 0) + goto dettach_frontend; break; case SAA7134_BOARD_PHILIPS_SNAKE: dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap); if (dev->dvb.frontend) { if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x60, - &dev->i2c_adap, 0) == NULL) + &dev->i2c_adap, 0) == NULL) { wprintk("%s: No tda826x found!\n", __func__); + goto dettach_frontend; + } if (dvb_attach(lnbp21_attach, dev->dvb.frontend, - &dev->i2c_adap, 0, 0) == NULL) + &dev->i2c_adap, 0, 0) == NULL) { wprintk("%s: No lnbp21 found!\n", __func__); + goto dettach_frontend; + } } break; case SAA7134_BOARD_CREATIX_CTX953: - configure_tda827x_fe(dev, &md8800_dvbt_config, &tda827x_cfg_0); + if (configure_tda827x_fe(dev, &md8800_dvbt_config, + &tda827x_cfg_0) < 0) + goto dettach_frontend; break; case SAA7134_BOARD_MSI_TVANYWHERE_AD11: - configure_tda827x_fe(dev, &philips_tiger_s_config, &tda827x_cfg_2); + if (configure_tda827x_fe(dev, &philips_tiger_s_config, + &tda827x_cfg_2) < 0) + goto dettach_frontend; break; case SAA7134_BOARD_AVERMEDIA_CARDBUS_506: dev->dvb.frontend = dvb_attach(mt352_attach, @@ -1218,16 +1271,20 @@ static int dvb_init(struct saa7134_dev *dev) if (dev->dvb.frontend) { struct dvb_frontend *fe; if (dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, - &dev->i2c_adap, DVB_PLL_PHILIPS_SD1878_TDA8261) == NULL) + &dev->i2c_adap, DVB_PLL_PHILIPS_SD1878_TDA8261) == NULL) { wprintk("%s: MD7134 DVB-S, no SD1878 " "found !\n", __func__); + goto dettach_frontend; + } /* we need to open the i2c gate (we know it exists) */ fe = dev->dvb.frontend; fe->ops.i2c_gate_ctrl(fe, 1); if (dvb_attach(isl6405_attach, fe, - &dev->i2c_adap, 0x08, 0, 0) == NULL) + &dev->i2c_adap, 0x08, 0, 0) == NULL) { wprintk("%s: MD7134 DVB-S, no ISL6405 " "found !\n", __func__); + goto dettach_frontend; + } fe->ops.i2c_gate_ctrl(fe, 0); dev->original_set_voltage = fe->ops.set_voltage; fe->ops.set_voltage = md8800_set_voltage; @@ -1254,10 +1311,7 @@ static int dvb_init(struct saa7134_dev *dev) if (!fe) { printk(KERN_ERR "%s/2: xc3028 attach failed\n", dev->name); - dvb_frontend_detach(dev->dvb.frontend); - dvb_unregister_frontend(dev->dvb.frontend); - dev->dvb.frontend = NULL; - return -1; + goto dettach_frontend; } } @@ -1282,6 +1336,12 @@ static int dvb_init(struct saa7134_dev *dev) dev->dvb.frontend->ops.tuner_ops.sleep(dev->dvb.frontend); } return ret; + +dettach_frontend: + dvb_frontend_detach(dev->dvb.frontend); + dev->dvb.frontend = NULL; + + return -1; } static int dvb_fini(struct saa7134_dev *dev) diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c index a0baf2d0ba7f307bade2c320716ce08b9b143d18..48e1a01718ec37390f72fa8ed731bfaa0d16bc78 100644 --- a/drivers/media/video/saa7134/saa7134-video.c +++ b/drivers/media/video/saa7134/saa7134-video.c @@ -1634,7 +1634,7 @@ static int saa7134_s_fmt_overlay(struct file *file, void *priv, struct saa7134_fh *fh = priv; struct saa7134_dev *dev = fh->dev; int err; - unsigned int flags; + unsigned long flags; if (saa7134_no_overlay > 0) { printk(KERN_ERR "V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); diff --git a/drivers/media/video/saa717x.c b/drivers/media/video/saa717x.c index 72c4081feff5e4d8af049bacbc5d62ab07181b3b..2220f9569941e04a767d1692546500294bc0cf7e 100644 --- a/drivers/media/video/saa717x.c +++ b/drivers/media/video/saa717x.c @@ -1429,8 +1429,6 @@ static int saa717x_probe(struct i2c_client *client, if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -EIO; - snprintf(client->name, sizeof(client->name) - 1, "saa717x"); - if (saa717x_write(client, 0x5a4, 0xfe) && saa717x_write(client, 0x5a5, 0x0f) && saa717x_write(client, 0x5a6, 0x00) && @@ -1507,6 +1505,12 @@ static int saa717x_remove(struct i2c_client *client) /* ----------------------------------------------------------------------- */ +static const struct i2c_device_id saa717x_id[] = { + { "saa717x", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, saa717x_id); + static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "saa717x", .driverid = I2C_DRIVERID_SAA717X, @@ -1514,4 +1518,5 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = { .probe = saa717x_probe, .remove = saa717x_remove, .legacy_class = I2C_CLASS_TV_ANALOG | I2C_CLASS_TV_DIGITAL, + .id_table = saa717x_id, }; diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c index 5748b1e1a128aacdff1abfbdc756d1c6048963a3..7f9c7bcf3c852428b73052e89b146c33c4569e2b 100644 --- a/drivers/media/video/sn9c102/sn9c102_core.c +++ b/drivers/media/video/sn9c102/sn9c102_core.c @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c index 9276ed99738839075615554ff384e5afd285815b..b12c60cf5a0985749df66008e1b6f10a558ee28f 100644 --- a/drivers/media/video/stk-webcam.c +++ b/drivers/media/video/stk-webcam.c @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -245,6 +246,8 @@ static int stk_initialise(struct stk_camera *dev) return -1; } +#ifdef CONFIG_VIDEO_V4L1_COMPAT + /* sysfs functions */ /*FIXME cleanup this */ @@ -350,6 +353,10 @@ static void stk_remove_sysfs_files(struct video_device *vdev) video_device_remove_file(vdev, &dev_attr_vflip); } +#else +#define stk_create_sysfs_files(a) +#define stk_remove_sysfs_files(a) +#endif /* *********************************************** */ /* diff --git a/drivers/media/video/tcm825x.c b/drivers/media/video/tcm825x.c index e57a646057785eb51dd331febc4db1772284204c..8f0100f67a91ea21bec97b6f708d337c18da1428 100644 --- a/drivers/media/video/tcm825x.c +++ b/drivers/media/video/tcm825x.c @@ -885,12 +885,19 @@ static int __exit tcm825x_remove(struct i2c_client *client) return 0; } +static const struct i2c_device_id tcm825x_id[] = { + { "tcm825x", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, tcm825x_id); + static struct i2c_driver tcm825x_i2c_driver = { .driver = { .name = TCM825X_NAME, }, .probe = tcm825x_probe, .remove = __exit_p(tcm825x_remove), + .id_table = tcm825x_id, }; static struct tcm825x_sensor tcm825x = { diff --git a/drivers/media/video/tlv320aic23b.c b/drivers/media/video/tlv320aic23b.c index f1db54202deaebb36138b119279bdf18424644aa..28ab9f9d760a29aa0317a9ee4eda54a78f2da854 100644 --- a/drivers/media/video/tlv320aic23b.c +++ b/drivers/media/video/tlv320aic23b.c @@ -168,6 +168,11 @@ static int tlv320aic23b_remove(struct i2c_client *client) /* ----------------------------------------------------------------------- */ +static const struct i2c_device_id tlv320aic23b_id[] = { + { "tlv320aic23b", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, tlv320aic23b_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "tlv320aic23b", @@ -175,4 +180,5 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = { .command = tlv320aic23b_command, .probe = tlv320aic23b_probe, .remove = tlv320aic23b_remove, + .id_table = tlv320aic23b_id, }; diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index 6bf104ea051da24c06c8b7d7bfe470555bd2f964..198f0afb812e2c93612af7b9786482bbe373367e 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c @@ -40,11 +40,11 @@ typeof(&FUNCTION) __a = symbol_request(FUNCTION); \ if (__a) { \ __r = (int) __a(ARGS); \ + symbol_put(FUNCTION); \ } else { \ printk(KERN_ERR "TUNER: Unable to find " \ "symbol "#FUNCTION"()\n"); \ } \ - symbol_put(FUNCTION); \ __r; \ }) @@ -340,16 +340,6 @@ static void tuner_i2c_address_check(struct tuner *t) tuner_warn("====================== WARNING! ======================\n"); } -static void attach_tda829x(struct tuner *t) -{ - struct tda829x_config cfg = { - .lna_cfg = t->config, - .tuner_callback = t->tuner_callback, - }; - dvb_attach(tda829x_attach, - &t->fe, t->i2c->adapter, t->i2c->addr, &cfg); -} - static struct xc5000_config xc5000_cfg; static void set_type(struct i2c_client *c, unsigned int type, @@ -385,12 +375,19 @@ static void set_type(struct i2c_client *c, unsigned int type, switch (t->type) { case TUNER_MT2032: - dvb_attach(microtune_attach, - &t->fe, t->i2c->adapter, t->i2c->addr); + if (!dvb_attach(microtune_attach, + &t->fe, t->i2c->adapter, t->i2c->addr)) + goto attach_failed; break; case TUNER_PHILIPS_TDA8290: { - attach_tda829x(t); + struct tda829x_config cfg = { + .lna_cfg = t->config, + .tuner_callback = t->tuner_callback, + }; + if (!dvb_attach(tda829x_attach, &t->fe, t->i2c->adapter, + t->i2c->addr, &cfg)) + goto attach_failed; break; } case TUNER_TEA5767: @@ -441,8 +438,9 @@ static void set_type(struct i2c_client *c, unsigned int type, break; } case TUNER_TDA9887: - dvb_attach(tda9887_attach, - &t->fe, t->i2c->adapter, t->i2c->addr); + if (!dvb_attach(tda9887_attach, + &t->fe, t->i2c->adapter, t->i2c->addr)) + goto attach_failed; break; case TUNER_XC5000: { @@ -450,10 +448,10 @@ static void set_type(struct i2c_client *c, unsigned int type, xc5000_cfg.i2c_address = t->i2c->addr; xc5000_cfg.if_khz = 5380; - xc5000_cfg.priv = c->adapter->algo_data; xc5000_cfg.tuner_callback = t->tuner_callback; if (!dvb_attach(xc5000_attach, - &t->fe, t->i2c->adapter, &xc5000_cfg)) + &t->fe, t->i2c->adapter, &xc5000_cfg, + c->adapter->algo_data)) goto attach_failed; xc_tuner_ops = &t->fe.ops.tuner_ops; @@ -1117,7 +1115,6 @@ static int tuner_probe(struct i2c_client *client, if (NULL == t) return -ENOMEM; t->i2c = client; - strlcpy(client->name, "(tuner unset)", sizeof(client->name)); i2c_set_clientdata(client, t); t->type = UNSET; t->audmode = V4L2_TUNER_MODE_STEREO; @@ -1167,7 +1164,7 @@ static int tuner_probe(struct i2c_client *client, /* If chip is not tda8290, don't register. since it can be tda9887*/ if (tuner_symbol_probe(tda829x_probe, t->i2c->adapter, - t->i2c->addr) == 0) { + t->i2c->addr) >= 0) { tuner_dbg("tda829x detected\n"); } else { /* Default is being tda9887 */ @@ -1181,7 +1178,7 @@ static int tuner_probe(struct i2c_client *client, case 0x60: if (tuner_symbol_probe(tea5767_autodetection, t->i2c->adapter, t->i2c->addr) - != EINVAL) { + >= 0) { t->type = TUNER_TEA5767; t->mode_mask = T_RADIO; t->mode = T_STANDBY; @@ -1275,11 +1272,26 @@ static int tuner_remove(struct i2c_client *client) list_del(&t->list); kfree(t); + + /* The probing code has overwritten the device name, restore it so + that reloading the driver will work. Ideally the device name + should not be overwritten in the first place, but for now that + will do. */ + strlcpy(client->name, "tuner", I2C_NAME_SIZE); return 0; } /* ----------------------------------------------------------------------- */ +/* This driver supports many devices and the idea is to let the driver + detect which device is present. So rather than listing all supported + devices here, we pretend to support a single, fake device type. */ +static const struct i2c_device_id tuner_id[] = { + { "tuner", }, /* autodetect */ + { } +}; +MODULE_DEVICE_TABLE(i2c, tuner_id); + static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "tuner", .driverid = I2C_DRIVERID_TUNER, @@ -1289,6 +1301,7 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = { .suspend = tuner_suspend, .resume = tuner_resume, .legacy_probe = tuner_legacy_probe, + .id_table = tuner_id, }; diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c index 6f9945b04e1f2bcd676f0ed8dc910994b29ed300..c77914d99d15c5972c94e9763a08b5789098e90a 100644 --- a/drivers/media/video/tvaudio.c +++ b/drivers/media/video/tvaudio.c @@ -1505,7 +1505,8 @@ static int chip_probe(struct i2c_client *client, const struct i2c_device_id *id) } /* fill required data structures */ - strcpy(client->name, desc->name); + if (!id) + strlcpy(client->name, desc->name, I2C_NAME_SIZE); chip->type = desc-chiplist; chip->shadow.count = desc->registers+1; chip->prevmode = -1; @@ -1830,6 +1831,15 @@ static int chip_legacy_probe(struct i2c_adapter *adap) return 0; } +/* This driver supports many devices and the idea is to let the driver + detect which device is present. So rather than listing all supported + devices here, we pretend to support a single, fake device type. */ +static const struct i2c_device_id chip_id[] = { + { "tvaudio", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, chip_id); + static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "tvaudio", .driverid = I2C_DRIVERID_TVAUDIO, @@ -1837,6 +1847,7 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = { .probe = chip_probe, .remove = chip_remove, .legacy_probe = chip_legacy_probe, + .id_table = chip_id, }; /* diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c index 3cf8a8e801e5eb0ec2649b020e9fdc931c6f0363..9da0e1807ffb236619fe8f73f56a72fad5b91526 100644 --- a/drivers/media/video/tveeprom.c +++ b/drivers/media/video/tveeprom.c @@ -319,10 +319,12 @@ audioIC[] = {AUDIO_CHIP_INTERNAL, "CX25843"}, {AUDIO_CHIP_INTERNAL, "CX23418"}, {AUDIO_CHIP_INTERNAL, "CX23885"}, - /* 40-42 */ + /* 40-44 */ {AUDIO_CHIP_INTERNAL, "CX23888"}, {AUDIO_CHIP_INTERNAL, "SAA7131"}, {AUDIO_CHIP_INTERNAL, "CX23887"}, + {AUDIO_CHIP_INTERNAL, "SAA7164"}, + {AUDIO_CHIP_INTERNAL, "AU8522"}, }; /* This list is supplied by Hauppauge. Thanks! */ @@ -341,8 +343,10 @@ static const char *decoderIC[] = { "CX882", "TVP5150A", "CX25840", "CX25841", "CX25842", /* 30-34 */ "CX25843", "CX23418", "NEC61153", "CX23885", "CX23888", - /* 35-37 */ - "SAA7131", "CX25837", "CX23887" + /* 35-39 */ + "SAA7131", "CX25837", "CX23887", "CX23885A", "CX23887A", + /* 40-42 */ + "SAA7164", "CX23885B", "AU8522" }; static int hasRadioTuner(int tunerType) diff --git a/drivers/media/video/upd64031a.c b/drivers/media/video/upd64031a.c index 93bfd19dec7d6fdad7da5d4d6cf111e82327248e..b4628874933bc3eb23595b0c54acf5854b1e0378 100644 --- a/drivers/media/video/upd64031a.c +++ b/drivers/media/video/upd64031a.c @@ -228,6 +228,11 @@ static int upd64031a_remove(struct i2c_client *client) /* ----------------------------------------------------------------------- */ +static const struct i2c_device_id upd64031a_id[] = { + { "upd64031a", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, upd64031a_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "upd64031a", @@ -235,4 +240,5 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = { .command = upd64031a_command, .probe = upd64031a_probe, .remove = upd64031a_remove, + .id_table = upd64031a_id, }; diff --git a/drivers/media/video/upd64083.c b/drivers/media/video/upd64083.c index 9ab712a56ce0a9e1e4b11940a6770c3672c7b1a6..9521ce004dcc1b282b4febbb4bcb7a3a43f74e25 100644 --- a/drivers/media/video/upd64083.c +++ b/drivers/media/video/upd64083.c @@ -205,6 +205,11 @@ static int upd64083_remove(struct i2c_client *client) /* ----------------------------------------------------------------------- */ +static const struct i2c_device_id upd64083_id[] = { + { "upd64083", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, upd64083_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "upd64083", @@ -212,4 +217,5 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = { .command = upd64083_command, .probe = upd64083_probe, .remove = upd64083_remove, + .id_table = upd64083_id, }; diff --git a/drivers/media/video/usbvision/Kconfig b/drivers/media/video/usbvision/Kconfig index 74e1d3075a20c28d34f27f171bd09019e230373c..fc24ef05b3f31cf527b6fc850423cae317ad224b 100644 --- a/drivers/media/video/usbvision/Kconfig +++ b/drivers/media/video/usbvision/Kconfig @@ -1,7 +1,7 @@ config VIDEO_USBVISION tristate "USB video devices based on Nogatech NT1003/1004/1005" depends on I2C && VIDEO_V4L2 - select MEDIA_TUNER + select VIDEO_TUNER select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO ---help--- There are more than 50 different USB video devices based on diff --git a/drivers/media/video/vp27smpx.c b/drivers/media/video/vp27smpx.c index fac0deba24afc69b67d07963c557ecc748e24c84..a1f76ee032e71c65725d39651235bc3a7de7c5aa 100644 --- a/drivers/media/video/vp27smpx.c +++ b/drivers/media/video/vp27smpx.c @@ -130,8 +130,6 @@ static int vp27smpx_probe(struct i2c_client *client, if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -EIO; - snprintf(client->name, sizeof(client->name) - 1, "vp27smpx"); - v4l_info(client, "chip found @ 0x%x (%s)\n", client->addr << 1, client->adapter->name); @@ -154,11 +152,18 @@ static int vp27smpx_remove(struct i2c_client *client) /* ----------------------------------------------------------------------- */ +static const struct i2c_device_id vp27smpx_id[] = { + { "vp27smpx", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, vp27smpx_id); + static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "vp27smpx", .driverid = I2C_DRIVERID_VP27SMPX, .command = vp27smpx_command, .probe = vp27smpx_probe, .remove = vp27smpx_remove, + .id_table = vp27smpx_id, }; diff --git a/drivers/media/video/wm8739.c b/drivers/media/video/wm8739.c index 0f8ed8461fba25f7c70f0a3bd9573f4698569a03..fc50299caa36f8f1715160a2499392efe77a2551 100644 --- a/drivers/media/video/wm8739.c +++ b/drivers/media/video/wm8739.c @@ -313,11 +313,18 @@ static int wm8739_remove(struct i2c_client *client) return 0; } +static const struct i2c_device_id wm8739_id[] = { + { "wm8739", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, wm8739_id); + static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "wm8739", .driverid = I2C_DRIVERID_WM8739, .command = wm8739_command, .probe = wm8739_probe, .remove = wm8739_remove, + .id_table = wm8739_id, }; diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c index 67a409e60c46559b4aa76fe820ac60b2a88e07b5..506378a508b906e270f636be6748517c3bf8b875 100644 --- a/drivers/media/video/wm8775.c +++ b/drivers/media/video/wm8775.c @@ -216,11 +216,18 @@ static int wm8775_remove(struct i2c_client *client) return 0; } +static const struct i2c_device_id wm8775_id[] = { + { "wm8775", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, wm8775_id); + static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "wm8775", .driverid = I2C_DRIVERID_WM8775, .command = wm8775_command, .probe = wm8775_probe, .remove = wm8775_remove, + .id_table = wm8775_id, }; diff --git a/drivers/media/video/zc0301/zc0301_core.c b/drivers/media/video/zc0301/zc0301_core.c index 363dd2b9475cfe40ca30fd3adfecdb2689d59d8c..e5c4e9f5193fed56cbd2e504e25dc2fdeb662e5b 100644 --- a/drivers/media/video/zc0301/zc0301_core.c +++ b/drivers/media/video/zc0301/zc0301_core.c @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/media/video/zoran_device.c b/drivers/media/video/zoran_device.c index 7b60533efe456bb4b650f060acc02bf66396f1de..37629ffd34c360f245de350137f00760130a025e 100644 --- a/drivers/media/video/zoran_device.c +++ b/drivers/media/video/zoran_device.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include @@ -47,6 +46,7 @@ #include #include +#include #include #include "videocodec.h" diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c index 0134bec1e399e66fca43153dbe64c6c9066d84c0..345c77e4683769bf7ba84cdf69e056749096315c 100644 --- a/drivers/media/video/zoran_driver.c +++ b/drivers/media/video/zoran_driver.c @@ -52,7 +52,6 @@ #include #include #include -#include #include #include @@ -74,6 +73,7 @@ #include #include "videocodec.h" +#include #include #include #include diff --git a/drivers/misc/sgi-xp/xp.h b/drivers/misc/sgi-xp/xp.h index 5515234be86ab952d79d3165a9e1d96a7cbb004b..03a87a307e321f0ac2ae3dffd2a16cef7baa03f5 100644 --- a/drivers/misc/sgi-xp/xp.h +++ b/drivers/misc/sgi-xp/xp.h @@ -157,215 +157,136 @@ struct xpc_msg { /* * Define the return values and values passed to user's callout functions. * (It is important to add new value codes at the end just preceding - * xpcUnknownReason, which must have the highest numerical value.) + * xpUnknownReason, which must have the highest numerical value.) */ -enum xpc_retval { - xpcSuccess = 0, +enum xp_retval { + xpSuccess = 0, - xpcNotConnected, /* 1: channel is not connected */ - xpcConnected, /* 2: channel connected (opened) */ - xpcRETIRED1, /* 3: (formerly xpcDisconnected) */ + xpNotConnected, /* 1: channel is not connected */ + xpConnected, /* 2: channel connected (opened) */ + xpRETIRED1, /* 3: (formerly xpDisconnected) */ - xpcMsgReceived, /* 4: message received */ - xpcMsgDelivered, /* 5: message delivered and acknowledged */ + xpMsgReceived, /* 4: message received */ + xpMsgDelivered, /* 5: message delivered and acknowledged */ - xpcRETIRED2, /* 6: (formerly xpcTransferFailed) */ + xpRETIRED2, /* 6: (formerly xpTransferFailed) */ - xpcNoWait, /* 7: operation would require wait */ - xpcRetry, /* 8: retry operation */ - xpcTimeout, /* 9: timeout in xpc_allocate_msg_wait() */ - xpcInterrupted, /* 10: interrupted wait */ + xpNoWait, /* 7: operation would require wait */ + xpRetry, /* 8: retry operation */ + xpTimeout, /* 9: timeout in xpc_allocate_msg_wait() */ + xpInterrupted, /* 10: interrupted wait */ - xpcUnequalMsgSizes, /* 11: message size disparity between sides */ - xpcInvalidAddress, /* 12: invalid address */ + xpUnequalMsgSizes, /* 11: message size disparity between sides */ + xpInvalidAddress, /* 12: invalid address */ - xpcNoMemory, /* 13: no memory available for XPC structures */ - xpcLackOfResources, /* 14: insufficient resources for operation */ - xpcUnregistered, /* 15: channel is not registered */ - xpcAlreadyRegistered, /* 16: channel is already registered */ + xpNoMemory, /* 13: no memory available for XPC structures */ + xpLackOfResources, /* 14: insufficient resources for operation */ + xpUnregistered, /* 15: channel is not registered */ + xpAlreadyRegistered, /* 16: channel is already registered */ - xpcPartitionDown, /* 17: remote partition is down */ - xpcNotLoaded, /* 18: XPC module is not loaded */ - xpcUnloading, /* 19: this side is unloading XPC module */ + xpPartitionDown, /* 17: remote partition is down */ + xpNotLoaded, /* 18: XPC module is not loaded */ + xpUnloading, /* 19: this side is unloading XPC module */ - xpcBadMagic, /* 20: XPC MAGIC string not found */ + xpBadMagic, /* 20: XPC MAGIC string not found */ - xpcReactivating, /* 21: remote partition was reactivated */ + xpReactivating, /* 21: remote partition was reactivated */ - xpcUnregistering, /* 22: this side is unregistering channel */ - xpcOtherUnregistering, /* 23: other side is unregistering channel */ + xpUnregistering, /* 22: this side is unregistering channel */ + xpOtherUnregistering, /* 23: other side is unregistering channel */ - xpcCloneKThread, /* 24: cloning kernel thread */ - xpcCloneKThreadFailed, /* 25: cloning kernel thread failed */ + xpCloneKThread, /* 24: cloning kernel thread */ + xpCloneKThreadFailed, /* 25: cloning kernel thread failed */ - xpcNoHeartbeat, /* 26: remote partition has no heartbeat */ + xpNoHeartbeat, /* 26: remote partition has no heartbeat */ - xpcPioReadError, /* 27: PIO read error */ - xpcPhysAddrRegFailed, /* 28: registration of phys addr range failed */ + xpPioReadError, /* 27: PIO read error */ + xpPhysAddrRegFailed, /* 28: registration of phys addr range failed */ - xpcBteDirectoryError, /* 29: maps to BTEFAIL_DIR */ - xpcBtePoisonError, /* 30: maps to BTEFAIL_POISON */ - xpcBteWriteError, /* 31: maps to BTEFAIL_WERR */ - xpcBteAccessError, /* 32: maps to BTEFAIL_ACCESS */ - xpcBtePWriteError, /* 33: maps to BTEFAIL_PWERR */ - xpcBtePReadError, /* 34: maps to BTEFAIL_PRERR */ - xpcBteTimeOutError, /* 35: maps to BTEFAIL_TOUT */ - xpcBteXtalkError, /* 36: maps to BTEFAIL_XTERR */ - xpcBteNotAvailable, /* 37: maps to BTEFAIL_NOTAVAIL */ - xpcBteUnmappedError, /* 38: unmapped BTEFAIL_ error */ + xpRETIRED3, /* 29: (formerly xpBteDirectoryError) */ + xpRETIRED4, /* 30: (formerly xpBtePoisonError) */ + xpRETIRED5, /* 31: (formerly xpBteWriteError) */ + xpRETIRED6, /* 32: (formerly xpBteAccessError) */ + xpRETIRED7, /* 33: (formerly xpBtePWriteError) */ + xpRETIRED8, /* 34: (formerly xpBtePReadError) */ + xpRETIRED9, /* 35: (formerly xpBteTimeOutError) */ + xpRETIRED10, /* 36: (formerly xpBteXtalkError) */ + xpRETIRED11, /* 37: (formerly xpBteNotAvailable) */ + xpRETIRED12, /* 38: (formerly xpBteUnmappedError) */ - xpcBadVersion, /* 39: bad version number */ - xpcVarsNotSet, /* 40: the XPC variables are not set up */ - xpcNoRsvdPageAddr, /* 41: unable to get rsvd page's phys addr */ - xpcInvalidPartid, /* 42: invalid partition ID */ - xpcLocalPartid, /* 43: local partition ID */ + xpBadVersion, /* 39: bad version number */ + xpVarsNotSet, /* 40: the XPC variables are not set up */ + xpNoRsvdPageAddr, /* 41: unable to get rsvd page's phys addr */ + xpInvalidPartid, /* 42: invalid partition ID */ + xpLocalPartid, /* 43: local partition ID */ - xpcOtherGoingDown, /* 44: other side going down, reason unknown */ - xpcSystemGoingDown, /* 45: system is going down, reason unknown */ - xpcSystemHalt, /* 46: system is being halted */ - xpcSystemReboot, /* 47: system is being rebooted */ - xpcSystemPoweroff, /* 48: system is being powered off */ + xpOtherGoingDown, /* 44: other side going down, reason unknown */ + xpSystemGoingDown, /* 45: system is going down, reason unknown */ + xpSystemHalt, /* 46: system is being halted */ + xpSystemReboot, /* 47: system is being rebooted */ + xpSystemPoweroff, /* 48: system is being powered off */ - xpcDisconnecting, /* 49: channel disconnecting (closing) */ + xpDisconnecting, /* 49: channel disconnecting (closing) */ - xpcOpenCloseError, /* 50: channel open/close protocol error */ + xpOpenCloseError, /* 50: channel open/close protocol error */ - xpcDisconnected, /* 51: channel disconnected (closed) */ + xpDisconnected, /* 51: channel disconnected (closed) */ - xpcBteSh2Start, /* 52: BTE CRB timeout */ + xpBteCopyError, /* 52: bte_copy() returned error */ - /* 53: 0x1 BTE Error Response Short */ - xpcBteSh2RspShort = xpcBteSh2Start + BTEFAIL_SH2_RESP_SHORT, - - /* 54: 0x2 BTE Error Response Long */ - xpcBteSh2RspLong = xpcBteSh2Start + BTEFAIL_SH2_RESP_LONG, - - /* 56: 0x4 BTE Error Response DSB */ - xpcBteSh2RspDSB = xpcBteSh2Start + BTEFAIL_SH2_RESP_DSP, - - /* 60: 0x8 BTE Error Response Access */ - xpcBteSh2RspAccess = xpcBteSh2Start + BTEFAIL_SH2_RESP_ACCESS, - - /* 68: 0x10 BTE Error CRB timeout */ - xpcBteSh2CRBTO = xpcBteSh2Start + BTEFAIL_SH2_CRB_TO, - - /* 84: 0x20 BTE Error NACK limit */ - xpcBteSh2NACKLimit = xpcBteSh2Start + BTEFAIL_SH2_NACK_LIMIT, - - /* 115: BTE end */ - xpcBteSh2End = xpcBteSh2Start + BTEFAIL_SH2_ALL, - - xpcUnknownReason /* 116: unknown reason - must be last in enum */ + xpUnknownReason /* 53: unknown reason - must be last in enum */ }; /* - * Define the callout function types used by XPC to update the user on - * connection activity and state changes (via the user function registered by - * xpc_connect()) and to notify them of messages received and delivered (via - * the user function registered by xpc_send_notify()). - * - * The two function types are xpc_channel_func and xpc_notify_func and - * both share the following arguments, with the exception of "data", which - * only xpc_channel_func has. + * Define the callout function type used by XPC to update the user on + * connection activity and state changes via the user function registered + * by xpc_connect(). * * Arguments: * - * reason - reason code. (See following table.) + * reason - reason code. * partid - partition ID associated with condition. * ch_number - channel # associated with condition. - * data - pointer to optional data. (See following table.) + * data - pointer to optional data. * key - pointer to optional user-defined value provided as the "key" - * argument to xpc_connect() or xpc_send_notify(). + * argument to xpc_connect(). * - * In the following table the "Optional Data" column applies to callouts made - * to functions registered by xpc_connect(). A "NA" in that column indicates - * that this reason code can be passed to functions registered by - * xpc_send_notify() (i.e. they don't have data arguments). + * A reason code of xpConnected indicates that a connection has been + * established to the specified partition on the specified channel. The data + * argument indicates the max number of entries allowed in the message queue. * - * Also, the first three reason codes in the following table indicate - * success, whereas the others indicate failure. When a failure reason code - * is received, one can assume that the channel is not connected. + * A reason code of xpMsgReceived indicates that a XPC message arrived from + * the specified partition on the specified channel. The data argument + * specifies the address of the message's payload. The user must call + * xpc_received() when finished with the payload. * - * - * Reason Code | Cause | Optional Data - * =====================+================================+===================== - * xpcConnected | connection has been established| max #of entries - * | to the specified partition on | allowed in message - * | the specified channel | queue - * ---------------------+--------------------------------+--------------------- - * xpcMsgReceived | an XPC message arrived from | address of payload - * | the specified partition on the | - * | specified channel | [the user must call - * | | xpc_received() when - * | | finished with the - * | | payload] - * ---------------------+--------------------------------+--------------------- - * xpcMsgDelivered | notification that the message | NA - * | was delivered to the intended | - * | recipient and that they have | - * | acknowledged its receipt by | - * | calling xpc_received() | - * =====================+================================+===================== - * xpcUnequalMsgSizes | can't connect to the specified | NULL - * | partition on the specified | - * | channel because of mismatched | - * | message sizes | - * ---------------------+--------------------------------+--------------------- - * xpcNoMemory | insufficient memory avaiable | NULL - * | to allocate message queue | - * ---------------------+--------------------------------+--------------------- - * xpcLackOfResources | lack of resources to create | NULL - * | the necessary kthreads to | - * | support the channel | - * ---------------------+--------------------------------+--------------------- - * xpcUnregistering | this side's user has | NULL or NA - * | unregistered by calling | - * | xpc_disconnect() | - * ---------------------+--------------------------------+--------------------- - * xpcOtherUnregistering| the other side's user has | NULL or NA - * | unregistered by calling | - * | xpc_disconnect() | - * ---------------------+--------------------------------+--------------------- - * xpcNoHeartbeat | the other side's XPC is no | NULL or NA - * | longer heartbeating | - * | | - * ---------------------+--------------------------------+--------------------- - * xpcUnloading | this side's XPC module is | NULL or NA - * | being unloaded | - * | | - * ---------------------+--------------------------------+--------------------- - * xpcOtherUnloading | the other side's XPC module is | NULL or NA - * | is being unloaded | - * | | - * ---------------------+--------------------------------+--------------------- - * xpcPioReadError | xp_nofault_PIOR() returned an | NULL or NA - * | error while sending an IPI | - * | | - * ---------------------+--------------------------------+--------------------- - * xpcInvalidAddress | the address either received or | NULL or NA - * | sent by the specified partition| - * | is invalid | - * ---------------------+--------------------------------+--------------------- - * xpcBteNotAvailable | attempt to pull data from the | NULL or NA - * xpcBtePoisonError | specified partition over the | - * xpcBteWriteError | specified channel via a | - * xpcBteAccessError | bte_copy() failed | - * xpcBteTimeOutError | | - * xpcBteXtalkError | | - * xpcBteDirectoryError | | - * xpcBteGenericError | | - * xpcBteUnmappedError | | - * ---------------------+--------------------------------+--------------------- - * xpcUnknownReason | the specified channel to the | NULL or NA - * | specified partition was | - * | unavailable for unknown reasons| - * =====================+================================+===================== + * All other reason codes indicate failure. The data argmument is NULL. + * When a failure reason code is received, one can assume that the channel + * is not connected. */ - -typedef void (*xpc_channel_func) (enum xpc_retval reason, partid_t partid, +typedef void (*xpc_channel_func) (enum xp_retval reason, short partid, int ch_number, void *data, void *key); -typedef void (*xpc_notify_func) (enum xpc_retval reason, partid_t partid, +/* + * Define the callout function type used by XPC to notify the user of + * messages received and delivered via the user function registered by + * xpc_send_notify(). + * + * Arguments: + * + * reason - reason code. + * partid - partition ID associated with condition. + * ch_number - channel # associated with condition. + * key - pointer to optional user-defined value provided as the "key" + * argument to xpc_send_notify(). + * + * A reason code of xpMsgDelivered indicates that the message was delivered + * to the intended recipient and that they have acknowledged its receipt by + * calling xpc_received(). + * + * All other reason codes indicate failure. + */ +typedef void (*xpc_notify_func) (enum xp_retval reason, short partid, int ch_number, void *key); /* @@ -401,57 +322,57 @@ struct xpc_registration { struct xpc_interface { void (*connect) (int); void (*disconnect) (int); - enum xpc_retval (*allocate) (partid_t, int, u32, void **); - enum xpc_retval (*send) (partid_t, int, void *); - enum xpc_retval (*send_notify) (partid_t, int, void *, + enum xp_retval (*allocate) (short, int, u32, void **); + enum xp_retval (*send) (short, int, void *); + enum xp_retval (*send_notify) (short, int, void *, xpc_notify_func, void *); - void (*received) (partid_t, int, void *); - enum xpc_retval (*partid_to_nasids) (partid_t, void *); + void (*received) (short, int, void *); + enum xp_retval (*partid_to_nasids) (short, void *); }; extern struct xpc_interface xpc_interface; extern void xpc_set_interface(void (*)(int), void (*)(int), - enum xpc_retval (*)(partid_t, int, u32, void **), - enum xpc_retval (*)(partid_t, int, void *), - enum xpc_retval (*)(partid_t, int, void *, + enum xp_retval (*)(short, int, u32, void **), + enum xp_retval (*)(short, int, void *), + enum xp_retval (*)(short, int, void *, xpc_notify_func, void *), - void (*)(partid_t, int, void *), - enum xpc_retval (*)(partid_t, void *)); + void (*)(short, int, void *), + enum xp_retval (*)(short, void *)); extern void xpc_clear_interface(void); -extern enum xpc_retval xpc_connect(int, xpc_channel_func, void *, u16, +extern enum xp_retval xpc_connect(int, xpc_channel_func, void *, u16, u16, u32, u32); extern void xpc_disconnect(int); -static inline enum xpc_retval -xpc_allocate(partid_t partid, int ch_number, u32 flags, void **payload) +static inline enum xp_retval +xpc_allocate(short partid, int ch_number, u32 flags, void **payload) { return xpc_interface.allocate(partid, ch_number, flags, payload); } -static inline enum xpc_retval -xpc_send(partid_t partid, int ch_number, void *payload) +static inline enum xp_retval +xpc_send(short partid, int ch_number, void *payload) { return xpc_interface.send(partid, ch_number, payload); } -static inline enum xpc_retval -xpc_send_notify(partid_t partid, int ch_number, void *payload, +static inline enum xp_retval +xpc_send_notify(short partid, int ch_number, void *payload, xpc_notify_func func, void *key) { return xpc_interface.send_notify(partid, ch_number, payload, func, key); } static inline void -xpc_received(partid_t partid, int ch_number, void *payload) +xpc_received(short partid, int ch_number, void *payload) { return xpc_interface.received(partid, ch_number, payload); } -static inline enum xpc_retval -xpc_partid_to_nasids(partid_t partid, void *nasids) +static inline enum xp_retval +xpc_partid_to_nasids(short partid, void *nasids) { return xpc_interface.partid_to_nasids(partid, nasids); } diff --git a/drivers/misc/sgi-xp/xp_main.c b/drivers/misc/sgi-xp/xp_main.c index 1fbf99bae963a8cd49008b26bbbb81c0790ee6d1..196480b691a11c216e8601e61fdae213cd3d8bab 100644 --- a/drivers/misc/sgi-xp/xp_main.c +++ b/drivers/misc/sgi-xp/xp_main.c @@ -42,21 +42,21 @@ EXPORT_SYMBOL_GPL(xpc_registrations); /* * Initialize the XPC interface to indicate that XPC isn't loaded. */ -static enum xpc_retval +static enum xp_retval xpc_notloaded(void) { - return xpcNotLoaded; + return xpNotLoaded; } struct xpc_interface xpc_interface = { (void (*)(int))xpc_notloaded, (void (*)(int))xpc_notloaded, - (enum xpc_retval(*)(partid_t, int, u32, void **))xpc_notloaded, - (enum xpc_retval(*)(partid_t, int, void *))xpc_notloaded, - (enum xpc_retval(*)(partid_t, int, void *, xpc_notify_func, void *)) + (enum xp_retval(*)(short, int, u32, void **))xpc_notloaded, + (enum xp_retval(*)(short, int, void *))xpc_notloaded, + (enum xp_retval(*)(short, int, void *, xpc_notify_func, void *)) xpc_notloaded, - (void (*)(partid_t, int, void *))xpc_notloaded, - (enum xpc_retval(*)(partid_t, void *))xpc_notloaded + (void (*)(short, int, void *))xpc_notloaded, + (enum xp_retval(*)(short, void *))xpc_notloaded }; EXPORT_SYMBOL_GPL(xpc_interface); @@ -66,12 +66,12 @@ EXPORT_SYMBOL_GPL(xpc_interface); void xpc_set_interface(void (*connect) (int), void (*disconnect) (int), - enum xpc_retval (*allocate) (partid_t, int, u32, void **), - enum xpc_retval (*send) (partid_t, int, void *), - enum xpc_retval (*send_notify) (partid_t, int, void *, + enum xp_retval (*allocate) (short, int, u32, void **), + enum xp_retval (*send) (short, int, void *), + enum xp_retval (*send_notify) (short, int, void *, xpc_notify_func, void *), - void (*received) (partid_t, int, void *), - enum xpc_retval (*partid_to_nasids) (partid_t, void *)) + void (*received) (short, int, void *), + enum xp_retval (*partid_to_nasids) (short, void *)) { xpc_interface.connect = connect; xpc_interface.disconnect = disconnect; @@ -91,16 +91,16 @@ xpc_clear_interface(void) { xpc_interface.connect = (void (*)(int))xpc_notloaded; xpc_interface.disconnect = (void (*)(int))xpc_notloaded; - xpc_interface.allocate = (enum xpc_retval(*)(partid_t, int, u32, + xpc_interface.allocate = (enum xp_retval(*)(short, int, u32, void **))xpc_notloaded; - xpc_interface.send = (enum xpc_retval(*)(partid_t, int, void *)) + xpc_interface.send = (enum xp_retval(*)(short, int, void *)) xpc_notloaded; - xpc_interface.send_notify = (enum xpc_retval(*)(partid_t, int, void *, + xpc_interface.send_notify = (enum xp_retval(*)(short, int, void *, xpc_notify_func, void *))xpc_notloaded; - xpc_interface.received = (void (*)(partid_t, int, void *)) + xpc_interface.received = (void (*)(short, int, void *)) xpc_notloaded; - xpc_interface.partid_to_nasids = (enum xpc_retval(*)(partid_t, void *)) + xpc_interface.partid_to_nasids = (enum xp_retval(*)(short, void *)) xpc_notloaded; } EXPORT_SYMBOL_GPL(xpc_clear_interface); @@ -123,13 +123,13 @@ EXPORT_SYMBOL_GPL(xpc_clear_interface); * nentries - max #of XPC message entries a message queue can contain. * The actual number, which is determined when a connection * is established and may be less then requested, will be - * passed to the user via the xpcConnected callout. + * passed to the user via the xpConnected callout. * assigned_limit - max number of kthreads allowed to be processing * messages (per connection) at any given instant. * idle_limit - max number of kthreads allowed to be idle at any given * instant. */ -enum xpc_retval +enum xp_retval xpc_connect(int ch_number, xpc_channel_func func, void *key, u16 payload_size, u16 nentries, u32 assigned_limit, u32 idle_limit) { @@ -143,12 +143,12 @@ xpc_connect(int ch_number, xpc_channel_func func, void *key, u16 payload_size, registration = &xpc_registrations[ch_number]; if (mutex_lock_interruptible(®istration->mutex) != 0) - return xpcInterrupted; + return xpInterrupted; /* if XPC_CHANNEL_REGISTERED(ch_number) */ if (registration->func != NULL) { mutex_unlock(®istration->mutex); - return xpcAlreadyRegistered; + return xpAlreadyRegistered; } /* register the channel for connection */ @@ -163,7 +163,7 @@ xpc_connect(int ch_number, xpc_channel_func func, void *key, u16 payload_size, xpc_interface.connect(ch_number); - return xpcSuccess; + return xpSuccess; } EXPORT_SYMBOL_GPL(xpc_connect); diff --git a/drivers/misc/sgi-xp/xpc.h b/drivers/misc/sgi-xp/xpc.h index 9eb6d4a3269cc584f427dde437b380a7b727718d..11ac267ed68fcca68a47c5e09647e55e525d5a5c 100644 --- a/drivers/misc/sgi-xp/xpc.h +++ b/drivers/misc/sgi-xp/xpc.h @@ -172,13 +172,13 @@ struct xpc_vars { (_version >= _XPC_VERSION(3, 1)) static inline int -xpc_hb_allowed(partid_t partid, struct xpc_vars *vars) +xpc_hb_allowed(short partid, struct xpc_vars *vars) { return ((vars->heartbeating_to_mask & (1UL << partid)) != 0); } static inline void -xpc_allow_hb(partid_t partid, struct xpc_vars *vars) +xpc_allow_hb(short partid, struct xpc_vars *vars) { u64 old_mask, new_mask; @@ -190,7 +190,7 @@ xpc_allow_hb(partid_t partid, struct xpc_vars *vars) } static inline void -xpc_disallow_hb(partid_t partid, struct xpc_vars *vars) +xpc_disallow_hb(short partid, struct xpc_vars *vars) { u64 old_mask, new_mask; @@ -408,11 +408,11 @@ struct xpc_notify { * messages. */ struct xpc_channel { - partid_t partid; /* ID of remote partition connected */ + short partid; /* ID of remote partition connected */ spinlock_t lock; /* lock for updating this structure */ u32 flags; /* general flags */ - enum xpc_retval reason; /* reason why channel is disconnect'g */ + enum xp_retval reason; /* reason why channel is disconnect'g */ int reason_line; /* line# disconnect initiated from */ u16 number; /* channel # */ @@ -522,7 +522,7 @@ struct xpc_partition { spinlock_t act_lock; /* protect updating of act_state */ u8 act_state; /* from XPC HB viewpoint */ u8 remote_vars_version; /* version# of partition's vars */ - enum xpc_retval reason; /* reason partition is deactivating */ + enum xp_retval reason; /* reason partition is deactivating */ int reason_line; /* line# deactivation initiated from */ int reactivate_nasid; /* nasid in partition to reactivate */ @@ -615,7 +615,7 @@ struct xpc_partition { /* interval in seconds to print 'waiting disengagement' messages */ #define XPC_DISENGAGE_PRINTMSG_INTERVAL 10 -#define XPC_PARTID(_p) ((partid_t) ((_p) - &xpc_partitions[0])) +#define XPC_PARTID(_p) ((short)((_p) - &xpc_partitions[0])) /* found in xp_main.c */ extern struct xpc_registration xpc_registrations[]; @@ -646,31 +646,31 @@ extern void xpc_allow_IPI_ops(void); extern void xpc_restrict_IPI_ops(void); extern int xpc_identify_act_IRQ_sender(void); extern int xpc_partition_disengaged(struct xpc_partition *); -extern enum xpc_retval xpc_mark_partition_active(struct xpc_partition *); +extern enum xp_retval xpc_mark_partition_active(struct xpc_partition *); extern void xpc_mark_partition_inactive(struct xpc_partition *); extern void xpc_discovery(void); extern void xpc_check_remote_hb(void); extern void xpc_deactivate_partition(const int, struct xpc_partition *, - enum xpc_retval); -extern enum xpc_retval xpc_initiate_partid_to_nasids(partid_t, void *); + enum xp_retval); +extern enum xp_retval xpc_initiate_partid_to_nasids(short, void *); /* found in xpc_channel.c */ extern void xpc_initiate_connect(int); extern void xpc_initiate_disconnect(int); -extern enum xpc_retval xpc_initiate_allocate(partid_t, int, u32, void **); -extern enum xpc_retval xpc_initiate_send(partid_t, int, void *); -extern enum xpc_retval xpc_initiate_send_notify(partid_t, int, void *, - xpc_notify_func, void *); -extern void xpc_initiate_received(partid_t, int, void *); -extern enum xpc_retval xpc_setup_infrastructure(struct xpc_partition *); -extern enum xpc_retval xpc_pull_remote_vars_part(struct xpc_partition *); +extern enum xp_retval xpc_initiate_allocate(short, int, u32, void **); +extern enum xp_retval xpc_initiate_send(short, int, void *); +extern enum xp_retval xpc_initiate_send_notify(short, int, void *, + xpc_notify_func, void *); +extern void xpc_initiate_received(short, int, void *); +extern enum xp_retval xpc_setup_infrastructure(struct xpc_partition *); +extern enum xp_retval xpc_pull_remote_vars_part(struct xpc_partition *); extern void xpc_process_channel_activity(struct xpc_partition *); extern void xpc_connected_callout(struct xpc_channel *); extern void xpc_deliver_msg(struct xpc_channel *); extern void xpc_disconnect_channel(const int, struct xpc_channel *, - enum xpc_retval, unsigned long *); -extern void xpc_disconnect_callout(struct xpc_channel *, enum xpc_retval); -extern void xpc_partition_going_down(struct xpc_partition *, enum xpc_retval); + enum xp_retval, unsigned long *); +extern void xpc_disconnect_callout(struct xpc_channel *, enum xp_retval); +extern void xpc_partition_going_down(struct xpc_partition *, enum xp_retval); extern void xpc_teardown_infrastructure(struct xpc_partition *); static inline void @@ -901,7 +901,7 @@ xpc_IPI_receive(AMO_t *amo) return FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_CLEAR); } -static inline enum xpc_retval +static inline enum xp_retval xpc_IPI_send(AMO_t *amo, u64 flag, int nasid, int phys_cpuid, int vector) { int ret = 0; @@ -923,7 +923,7 @@ xpc_IPI_send(AMO_t *amo, u64 flag, int nasid, int phys_cpuid, int vector) local_irq_restore(irq_flags); - return ((ret == 0) ? xpcSuccess : xpcPioReadError); + return ((ret == 0) ? xpSuccess : xpPioReadError); } /* @@ -992,7 +992,7 @@ xpc_notify_IRQ_send(struct xpc_channel *ch, u8 ipi_flag, char *ipi_flag_string, unsigned long *irq_flags) { struct xpc_partition *part = &xpc_partitions[ch->partid]; - enum xpc_retval ret; + enum xp_retval ret; if (likely(part->act_state != XPC_P_DEACTIVATING)) { ret = xpc_IPI_send(part->remote_IPI_amo_va, @@ -1001,7 +1001,7 @@ xpc_notify_IRQ_send(struct xpc_channel *ch, u8 ipi_flag, char *ipi_flag_string, part->remote_IPI_phys_cpuid, SGI_XPC_NOTIFY); dev_dbg(xpc_chan, "%s sent to partid=%d, channel=%d, ret=%d\n", ipi_flag_string, ch->partid, ch->number, ret); - if (unlikely(ret != xpcSuccess)) { + if (unlikely(ret != xpSuccess)) { if (irq_flags != NULL) spin_unlock_irqrestore(&ch->lock, *irq_flags); XPC_DEACTIVATE_PARTITION(part, ret); @@ -1123,41 +1123,10 @@ xpc_IPI_init(int index) return amo; } -static inline enum xpc_retval +static inline enum xp_retval xpc_map_bte_errors(bte_result_t error) { - if (error == BTE_SUCCESS) - return xpcSuccess; - - if (is_shub2()) { - if (BTE_VALID_SH2_ERROR(error)) - return xpcBteSh2Start + error; - return xpcBteUnmappedError; - } - switch (error) { - case BTE_SUCCESS: - return xpcSuccess; - case BTEFAIL_DIR: - return xpcBteDirectoryError; - case BTEFAIL_POISON: - return xpcBtePoisonError; - case BTEFAIL_WERR: - return xpcBteWriteError; - case BTEFAIL_ACCESS: - return xpcBteAccessError; - case BTEFAIL_PWERR: - return xpcBtePWriteError; - case BTEFAIL_PRERR: - return xpcBtePReadError; - case BTEFAIL_TOUT: - return xpcBteTimeOutError; - case BTEFAIL_XTERR: - return xpcBteXtalkError; - case BTEFAIL_NOTAVAIL: - return xpcBteNotAvailable; - default: - return xpcBteUnmappedError; - } + return ((error == BTE_SUCCESS) ? xpSuccess : xpBteCopyError); } /* diff --git a/drivers/misc/sgi-xp/xpc_channel.c b/drivers/misc/sgi-xp/xpc_channel.c index bfcb9ea968e9e15aee9cf31c63fac58f8193adef..9c90c2d55c081172dc5ebcc9dbaa0ff15f20b888 100644 --- a/drivers/misc/sgi-xp/xpc_channel.c +++ b/drivers/misc/sgi-xp/xpc_channel.c @@ -53,7 +53,7 @@ xpc_kzalloc_cacheline_aligned(size_t size, gfp_t flags, void **base) * Set up the initial values for the XPartition Communication channels. */ static void -xpc_initialize_channels(struct xpc_partition *part, partid_t partid) +xpc_initialize_channels(struct xpc_partition *part, short partid) { int ch_number; struct xpc_channel *ch; @@ -90,12 +90,12 @@ xpc_initialize_channels(struct xpc_partition *part, partid_t partid) * Setup the infrastructure necessary to support XPartition Communication * between the specified remote partition and the local one. */ -enum xpc_retval +enum xp_retval xpc_setup_infrastructure(struct xpc_partition *part) { int ret, cpuid; struct timer_list *timer; - partid_t partid = XPC_PARTID(part); + short partid = XPC_PARTID(part); /* * Zero out MOST of the entry for this partition. Only the fields @@ -114,7 +114,7 @@ xpc_setup_infrastructure(struct xpc_partition *part) GFP_KERNEL); if (part->channels == NULL) { dev_err(xpc_chan, "can't get memory for channels\n"); - return xpcNoMemory; + return xpNoMemory; } part->nchannels = XPC_NCHANNELS; @@ -129,7 +129,7 @@ xpc_setup_infrastructure(struct xpc_partition *part) part->channels = NULL; dev_err(xpc_chan, "can't get memory for local get/put " "values\n"); - return xpcNoMemory; + return xpNoMemory; } part->remote_GPs = xpc_kzalloc_cacheline_aligned(XPC_GP_SIZE, @@ -143,7 +143,7 @@ xpc_setup_infrastructure(struct xpc_partition *part) part->local_GPs = NULL; kfree(part->channels); part->channels = NULL; - return xpcNoMemory; + return xpNoMemory; } /* allocate all the required open and close args */ @@ -159,7 +159,7 @@ xpc_setup_infrastructure(struct xpc_partition *part) part->local_GPs = NULL; kfree(part->channels); part->channels = NULL; - return xpcNoMemory; + return xpNoMemory; } part->remote_openclose_args = @@ -175,7 +175,7 @@ xpc_setup_infrastructure(struct xpc_partition *part) part->local_GPs = NULL; kfree(part->channels); part->channels = NULL; - return xpcNoMemory; + return xpNoMemory; } xpc_initialize_channels(part, partid); @@ -209,7 +209,7 @@ xpc_setup_infrastructure(struct xpc_partition *part) part->local_GPs = NULL; kfree(part->channels); part->channels = NULL; - return xpcLackOfResources; + return xpLackOfResources; } /* Setup a timer to check for dropped IPIs */ @@ -243,7 +243,7 @@ xpc_setup_infrastructure(struct xpc_partition *part) xpc_vars_part[partid].nchannels = part->nchannels; xpc_vars_part[partid].magic = XPC_VP_MAGIC1; - return xpcSuccess; + return xpSuccess; } /* @@ -254,7 +254,7 @@ xpc_setup_infrastructure(struct xpc_partition *part) * dst must be a cacheline aligned virtual address on this partition. * cnt must be an cacheline sized */ -static enum xpc_retval +static enum xp_retval xpc_pull_remote_cachelines(struct xpc_partition *part, void *dst, const void *src, size_t cnt) { @@ -270,7 +270,7 @@ xpc_pull_remote_cachelines(struct xpc_partition *part, void *dst, bte_ret = xp_bte_copy((u64)src, (u64)dst, (u64)cnt, (BTE_NORMAL | BTE_WACQUIRE), NULL); if (bte_ret == BTE_SUCCESS) - return xpcSuccess; + return xpSuccess; dev_dbg(xpc_chan, "xp_bte_copy() from partition %d failed, ret=%d\n", XPC_PARTID(part), bte_ret); @@ -282,7 +282,7 @@ xpc_pull_remote_cachelines(struct xpc_partition *part, void *dst, * Pull the remote per partition specific variables from the specified * partition. */ -enum xpc_retval +enum xp_retval xpc_pull_remote_vars_part(struct xpc_partition *part) { u8 buffer[L1_CACHE_BYTES * 2]; @@ -290,8 +290,8 @@ xpc_pull_remote_vars_part(struct xpc_partition *part) (struct xpc_vars_part *)L1_CACHE_ALIGN((u64)buffer); struct xpc_vars_part *pulled_entry; u64 remote_entry_cacheline_pa, remote_entry_pa; - partid_t partid = XPC_PARTID(part); - enum xpc_retval ret; + short partid = XPC_PARTID(part); + enum xp_retval ret; /* pull the cacheline that contains the variables we're interested in */ @@ -311,7 +311,7 @@ xpc_pull_remote_vars_part(struct xpc_partition *part) ret = xpc_pull_remote_cachelines(part, pulled_entry_cacheline, (void *)remote_entry_cacheline_pa, L1_CACHE_BYTES); - if (ret != xpcSuccess) { + if (ret != xpSuccess) { dev_dbg(xpc_chan, "failed to pull XPC vars_part from " "partition %d, ret=%d\n", partid, ret); return ret; @@ -326,11 +326,11 @@ xpc_pull_remote_vars_part(struct xpc_partition *part) dev_dbg(xpc_chan, "partition %d's XPC vars_part for " "partition %d has bad magic value (=0x%lx)\n", partid, sn_partition_id, pulled_entry->magic); - return xpcBadMagic; + return xpBadMagic; } /* they've not been initialized yet */ - return xpcRetry; + return xpRetry; } if (xpc_vars_part[partid].magic == XPC_VP_MAGIC1) { @@ -344,7 +344,7 @@ xpc_pull_remote_vars_part(struct xpc_partition *part) dev_err(xpc_chan, "partition %d's XPC vars_part for " "partition %d are not valid\n", partid, sn_partition_id); - return xpcInvalidAddress; + return xpInvalidAddress; } /* the variables we imported look to be valid */ @@ -366,9 +366,9 @@ xpc_pull_remote_vars_part(struct xpc_partition *part) } if (pulled_entry->magic == XPC_VP_MAGIC1) - return xpcRetry; + return xpRetry; - return xpcSuccess; + return xpSuccess; } /* @@ -379,7 +379,7 @@ xpc_get_IPI_flags(struct xpc_partition *part) { unsigned long irq_flags; u64 IPI_amo; - enum xpc_retval ret; + enum xp_retval ret; /* * See if there are any IPI flags to be handled. @@ -398,7 +398,7 @@ xpc_get_IPI_flags(struct xpc_partition *part) (void *)part-> remote_openclose_args_pa, XPC_OPENCLOSE_ARGS_SIZE); - if (ret != xpcSuccess) { + if (ret != xpSuccess) { XPC_DEACTIVATE_PARTITION(part, ret); dev_dbg(xpc_chan, "failed to pull openclose args from " @@ -414,7 +414,7 @@ xpc_get_IPI_flags(struct xpc_partition *part) ret = xpc_pull_remote_cachelines(part, part->remote_GPs, (void *)part->remote_GPs_pa, XPC_GP_SIZE); - if (ret != xpcSuccess) { + if (ret != xpSuccess) { XPC_DEACTIVATE_PARTITION(part, ret); dev_dbg(xpc_chan, "failed to pull GPs from partition " @@ -431,7 +431,7 @@ xpc_get_IPI_flags(struct xpc_partition *part) /* * Allocate the local message queue and the notify queue. */ -static enum xpc_retval +static enum xp_retval xpc_allocate_local_msgqueue(struct xpc_channel *ch) { unsigned long irq_flags; @@ -464,18 +464,18 @@ xpc_allocate_local_msgqueue(struct xpc_channel *ch) ch->local_nentries = nentries; } spin_unlock_irqrestore(&ch->lock, irq_flags); - return xpcSuccess; + return xpSuccess; } dev_dbg(xpc_chan, "can't get memory for local message queue and notify " "queue, partid=%d, channel=%d\n", ch->partid, ch->number); - return xpcNoMemory; + return xpNoMemory; } /* * Allocate the cached remote message queue. */ -static enum xpc_retval +static enum xp_retval xpc_allocate_remote_msgqueue(struct xpc_channel *ch) { unsigned long irq_flags; @@ -502,12 +502,12 @@ xpc_allocate_remote_msgqueue(struct xpc_channel *ch) ch->remote_nentries = nentries; } spin_unlock_irqrestore(&ch->lock, irq_flags); - return xpcSuccess; + return xpSuccess; } dev_dbg(xpc_chan, "can't get memory for cached remote message queue, " "partid=%d, channel=%d\n", ch->partid, ch->number); - return xpcNoMemory; + return xpNoMemory; } /* @@ -515,20 +515,20 @@ xpc_allocate_remote_msgqueue(struct xpc_channel *ch) * * Note: Assumes all of the channel sizes are filled in. */ -static enum xpc_retval +static enum xp_retval xpc_allocate_msgqueues(struct xpc_channel *ch) { unsigned long irq_flags; - enum xpc_retval ret; + enum xp_retval ret; DBUG_ON(ch->flags & XPC_C_SETUP); ret = xpc_allocate_local_msgqueue(ch); - if (ret != xpcSuccess) + if (ret != xpSuccess) return ret; ret = xpc_allocate_remote_msgqueue(ch); - if (ret != xpcSuccess) { + if (ret != xpSuccess) { kfree(ch->local_msgqueue_base); ch->local_msgqueue = NULL; kfree(ch->notify_queue); @@ -540,7 +540,7 @@ xpc_allocate_msgqueues(struct xpc_channel *ch) ch->flags |= XPC_C_SETUP; spin_unlock_irqrestore(&ch->lock, irq_flags); - return xpcSuccess; + return xpSuccess; } /* @@ -552,7 +552,7 @@ xpc_allocate_msgqueues(struct xpc_channel *ch) static void xpc_process_connect(struct xpc_channel *ch, unsigned long *irq_flags) { - enum xpc_retval ret; + enum xp_retval ret; DBUG_ON(!spin_is_locked(&ch->lock)); @@ -568,7 +568,7 @@ xpc_process_connect(struct xpc_channel *ch, unsigned long *irq_flags) ret = xpc_allocate_msgqueues(ch); spin_lock_irqsave(&ch->lock, *irq_flags); - if (ret != xpcSuccess) + if (ret != xpSuccess) XPC_DISCONNECT_CHANNEL(ch, ret, irq_flags); if (ch->flags & (XPC_C_CONNECTED | XPC_C_DISCONNECTING)) @@ -603,7 +603,7 @@ xpc_process_connect(struct xpc_channel *ch, unsigned long *irq_flags) * Notify those who wanted to be notified upon delivery of their message. */ static void -xpc_notify_senders(struct xpc_channel *ch, enum xpc_retval reason, s64 put) +xpc_notify_senders(struct xpc_channel *ch, enum xp_retval reason, s64 put) { struct xpc_notify *notify; u8 notify_type; @@ -748,7 +748,7 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags) if (ch->flags & XPC_C_DISCONNECTINGCALLOUT_MADE) { spin_unlock_irqrestore(&ch->lock, *irq_flags); - xpc_disconnect_callout(ch, xpcDisconnected); + xpc_disconnect_callout(ch, xpDisconnected); spin_lock_irqsave(&ch->lock, *irq_flags); } @@ -791,7 +791,7 @@ xpc_process_openclose_IPI(struct xpc_partition *part, int ch_number, struct xpc_openclose_args *args = &part->remote_openclose_args[ch_number]; struct xpc_channel *ch = &part->channels[ch_number]; - enum xpc_retval reason; + enum xp_retval reason; spin_lock_irqsave(&ch->lock, irq_flags); @@ -871,10 +871,10 @@ again: if (!(ch->flags & XPC_C_DISCONNECTING)) { reason = args->reason; - if (reason <= xpcSuccess || reason > xpcUnknownReason) - reason = xpcUnknownReason; - else if (reason == xpcUnregistering) - reason = xpcOtherUnregistering; + if (reason <= xpSuccess || reason > xpUnknownReason) + reason = xpUnknownReason; + else if (reason == xpUnregistering) + reason = xpOtherUnregistering; XPC_DISCONNECT_CHANNEL(ch, reason, &irq_flags); @@ -961,7 +961,7 @@ again: if (ch->flags & XPC_C_OPENREQUEST) { if (args->msg_size != ch->msg_size) { - XPC_DISCONNECT_CHANNEL(ch, xpcUnequalMsgSizes, + XPC_DISCONNECT_CHANNEL(ch, xpUnequalMsgSizes, &irq_flags); spin_unlock_irqrestore(&ch->lock, irq_flags); return; @@ -991,7 +991,7 @@ again: return; } if (!(ch->flags & XPC_C_OPENREQUEST)) { - XPC_DISCONNECT_CHANNEL(ch, xpcOpenCloseError, + XPC_DISCONNECT_CHANNEL(ch, xpOpenCloseError, &irq_flags); spin_unlock_irqrestore(&ch->lock, irq_flags); return; @@ -1042,18 +1042,18 @@ again: /* * Attempt to establish a channel connection to a remote partition. */ -static enum xpc_retval +static enum xp_retval xpc_connect_channel(struct xpc_channel *ch) { unsigned long irq_flags; struct xpc_registration *registration = &xpc_registrations[ch->number]; if (mutex_trylock(®istration->mutex) == 0) - return xpcRetry; + return xpRetry; if (!XPC_CHANNEL_REGISTERED(ch->number)) { mutex_unlock(®istration->mutex); - return xpcUnregistered; + return xpUnregistered; } spin_lock_irqsave(&ch->lock, irq_flags); @@ -1095,10 +1095,10 @@ xpc_connect_channel(struct xpc_channel *ch) * the channel lock as needed. */ mutex_unlock(®istration->mutex); - XPC_DISCONNECT_CHANNEL(ch, xpcUnequalMsgSizes, + XPC_DISCONNECT_CHANNEL(ch, xpUnequalMsgSizes, &irq_flags); spin_unlock_irqrestore(&ch->lock, irq_flags); - return xpcUnequalMsgSizes; + return xpUnequalMsgSizes; } } else { ch->msg_size = registration->msg_size; @@ -1120,7 +1120,7 @@ xpc_connect_channel(struct xpc_channel *ch) spin_unlock_irqrestore(&ch->lock, irq_flags); - return xpcSuccess; + return xpSuccess; } /* @@ -1203,7 +1203,7 @@ xpc_process_msg_IPI(struct xpc_partition *part, int ch_number) * Notify senders that messages sent have been * received and delivered by the other side. */ - xpc_notify_senders(ch, xpcMsgDelivered, + xpc_notify_senders(ch, xpMsgDelivered, ch->remote_GP.get); } @@ -1335,7 +1335,7 @@ xpc_process_channel_activity(struct xpc_partition *part) * at the same time. */ void -xpc_partition_going_down(struct xpc_partition *part, enum xpc_retval reason) +xpc_partition_going_down(struct xpc_partition *part, enum xp_retval reason) { unsigned long irq_flags; int ch_number; @@ -1375,7 +1375,7 @@ xpc_partition_going_down(struct xpc_partition *part, enum xpc_retval reason) void xpc_teardown_infrastructure(struct xpc_partition *part) { - partid_t partid = XPC_PARTID(part); + short partid = XPC_PARTID(part); /* * We start off by making this partition inaccessible to local @@ -1428,7 +1428,7 @@ xpc_teardown_infrastructure(struct xpc_partition *part) void xpc_initiate_connect(int ch_number) { - partid_t partid; + short partid; struct xpc_partition *part; struct xpc_channel *ch; @@ -1456,13 +1456,13 @@ xpc_connected_callout(struct xpc_channel *ch) /* let the registerer know that a connection has been established */ if (ch->func != NULL) { - dev_dbg(xpc_chan, "ch->func() called, reason=xpcConnected, " + dev_dbg(xpc_chan, "ch->func() called, reason=xpConnected, " "partid=%d, channel=%d\n", ch->partid, ch->number); - ch->func(xpcConnected, ch->partid, ch->number, + ch->func(xpConnected, ch->partid, ch->number, (void *)(u64)ch->local_nentries, ch->key); - dev_dbg(xpc_chan, "ch->func() returned, reason=xpcConnected, " + dev_dbg(xpc_chan, "ch->func() returned, reason=xpConnected, " "partid=%d, channel=%d\n", ch->partid, ch->number); } } @@ -1484,7 +1484,7 @@ void xpc_initiate_disconnect(int ch_number) { unsigned long irq_flags; - partid_t partid; + short partid; struct xpc_partition *part; struct xpc_channel *ch; @@ -1503,7 +1503,7 @@ xpc_initiate_disconnect(int ch_number) if (!(ch->flags & XPC_C_DISCONNECTED)) { ch->flags |= XPC_C_WDISCONNECT; - XPC_DISCONNECT_CHANNEL(ch, xpcUnregistering, + XPC_DISCONNECT_CHANNEL(ch, xpUnregistering, &irq_flags); } @@ -1528,7 +1528,7 @@ xpc_initiate_disconnect(int ch_number) */ void xpc_disconnect_channel(const int line, struct xpc_channel *ch, - enum xpc_retval reason, unsigned long *irq_flags) + enum xp_retval reason, unsigned long *irq_flags) { u32 channel_was_connected = (ch->flags & XPC_C_CONNECTED); @@ -1563,7 +1563,7 @@ xpc_disconnect_channel(const int line, struct xpc_channel *ch, } else if ((ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) && !(ch->flags & XPC_C_DISCONNECTINGCALLOUT)) { - /* start a kthread that will do the xpcDisconnecting callout */ + /* start a kthread that will do the xpDisconnecting callout */ xpc_create_kthreads(ch, 1, 1); } @@ -1575,7 +1575,7 @@ xpc_disconnect_channel(const int line, struct xpc_channel *ch, } void -xpc_disconnect_callout(struct xpc_channel *ch, enum xpc_retval reason) +xpc_disconnect_callout(struct xpc_channel *ch, enum xp_retval reason) { /* * Let the channel's registerer know that the channel is being @@ -1598,13 +1598,13 @@ xpc_disconnect_callout(struct xpc_channel *ch, enum xpc_retval reason) * Wait for a message entry to become available for the specified channel, * but don't wait any longer than 1 jiffy. */ -static enum xpc_retval +static enum xp_retval xpc_allocate_msg_wait(struct xpc_channel *ch) { - enum xpc_retval ret; + enum xp_retval ret; if (ch->flags & XPC_C_DISCONNECTING) { - DBUG_ON(ch->reason == xpcInterrupted); + DBUG_ON(ch->reason == xpInterrupted); return ch->reason; } @@ -1614,11 +1614,11 @@ xpc_allocate_msg_wait(struct xpc_channel *ch) if (ch->flags & XPC_C_DISCONNECTING) { ret = ch->reason; - DBUG_ON(ch->reason == xpcInterrupted); + DBUG_ON(ch->reason == xpInterrupted); } else if (ret == 0) { - ret = xpcTimeout; + ret = xpTimeout; } else { - ret = xpcInterrupted; + ret = xpInterrupted; } return ret; @@ -1628,12 +1628,12 @@ xpc_allocate_msg_wait(struct xpc_channel *ch) * Allocate an entry for a message from the message queue associated with the * specified channel. */ -static enum xpc_retval +static enum xp_retval xpc_allocate_msg(struct xpc_channel *ch, u32 flags, struct xpc_msg **address_of_msg) { struct xpc_msg *msg; - enum xpc_retval ret; + enum xp_retval ret; s64 put; /* this reference will be dropped in xpc_send_msg() */ @@ -1645,7 +1645,7 @@ xpc_allocate_msg(struct xpc_channel *ch, u32 flags, } if (!(ch->flags & XPC_C_CONNECTED)) { xpc_msgqueue_deref(ch); - return xpcNotConnected; + return xpNotConnected; } /* @@ -1653,7 +1653,7 @@ xpc_allocate_msg(struct xpc_channel *ch, u32 flags, * If none are available, we'll make sure that we grab the latest * GP values. */ - ret = xpcTimeout; + ret = xpTimeout; while (1) { @@ -1683,16 +1683,16 @@ xpc_allocate_msg(struct xpc_channel *ch, u32 flags, * that will cause the IPI handler to fetch the latest * GP values as if an IPI was sent by the other side. */ - if (ret == xpcTimeout) + if (ret == xpTimeout) xpc_IPI_send_local_msgrequest(ch); if (flags & XPC_NOWAIT) { xpc_msgqueue_deref(ch); - return xpcNoWait; + return xpNoWait; } ret = xpc_allocate_msg_wait(ch); - if (ret != xpcInterrupted && ret != xpcTimeout) { + if (ret != xpInterrupted && ret != xpTimeout) { xpc_msgqueue_deref(ch); return ret; } @@ -1711,7 +1711,7 @@ xpc_allocate_msg(struct xpc_channel *ch, u32 flags, *address_of_msg = msg; - return xpcSuccess; + return xpSuccess; } /* @@ -1727,11 +1727,11 @@ xpc_allocate_msg(struct xpc_channel *ch, u32 flags, * payload - address of the allocated payload area pointer (filled in on * return) in which the user-defined message is constructed. */ -enum xpc_retval -xpc_initiate_allocate(partid_t partid, int ch_number, u32 flags, void **payload) +enum xp_retval +xpc_initiate_allocate(short partid, int ch_number, u32 flags, void **payload) { struct xpc_partition *part = &xpc_partitions[partid]; - enum xpc_retval ret = xpcUnknownReason; + enum xp_retval ret = xpUnknownReason; struct xpc_msg *msg = NULL; DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS); @@ -1814,11 +1814,11 @@ xpc_send_msgs(struct xpc_channel *ch, s64 initial_put) * local message queue's Put value and sends an IPI to the partition the * message is being sent to. */ -static enum xpc_retval +static enum xp_retval xpc_send_msg(struct xpc_channel *ch, struct xpc_msg *msg, u8 notify_type, xpc_notify_func func, void *key) { - enum xpc_retval ret = xpcSuccess; + enum xp_retval ret = xpSuccess; struct xpc_notify *notify = notify; s64 put, msg_number = msg->number; @@ -1908,12 +1908,12 @@ xpc_send_msg(struct xpc_channel *ch, struct xpc_msg *msg, u8 notify_type, * payload - pointer to the payload area allocated via * xpc_initiate_allocate(). */ -enum xpc_retval -xpc_initiate_send(partid_t partid, int ch_number, void *payload) +enum xp_retval +xpc_initiate_send(short partid, int ch_number, void *payload) { struct xpc_partition *part = &xpc_partitions[partid]; struct xpc_msg *msg = XPC_MSG_ADDRESS(payload); - enum xpc_retval ret; + enum xp_retval ret; dev_dbg(xpc_chan, "msg=0x%p, partid=%d, channel=%d\n", (void *)msg, partid, ch_number); @@ -1957,13 +1957,13 @@ xpc_initiate_send(partid_t partid, int ch_number, void *payload) * receipt. THIS FUNCTION MUST BE NON-BLOCKING. * key - user-defined key to be passed to the function when it's called. */ -enum xpc_retval -xpc_initiate_send_notify(partid_t partid, int ch_number, void *payload, +enum xp_retval +xpc_initiate_send_notify(short partid, int ch_number, void *payload, xpc_notify_func func, void *key) { struct xpc_partition *part = &xpc_partitions[partid]; struct xpc_msg *msg = XPC_MSG_ADDRESS(payload); - enum xpc_retval ret; + enum xp_retval ret; dev_dbg(xpc_chan, "msg=0x%p, partid=%d, channel=%d\n", (void *)msg, partid, ch_number); @@ -1985,7 +1985,7 @@ xpc_pull_remote_msg(struct xpc_channel *ch, s64 get) struct xpc_msg *remote_msg, *msg; u32 msg_index, nmsgs; u64 msg_offset; - enum xpc_retval ret; + enum xp_retval ret; if (mutex_lock_interruptible(&ch->msg_to_pull_mutex) != 0) { /* we were interrupted by a signal */ @@ -2012,7 +2012,7 @@ xpc_pull_remote_msg(struct xpc_channel *ch, s64 get) ret = xpc_pull_remote_cachelines(part, msg, remote_msg, nmsgs * ch->msg_size); - if (ret != xpcSuccess) { + if (ret != xpSuccess) { dev_dbg(xpc_chan, "failed to pull %d msgs starting with" " msg %ld from partition %d, channel=%d, " @@ -2112,7 +2112,7 @@ xpc_deliver_msg(struct xpc_channel *ch) ch->number); /* deliver the message to its intended recipient */ - ch->func(xpcMsgReceived, ch->partid, ch->number, + ch->func(xpMsgReceived, ch->partid, ch->number, &msg->payload, ch->key); dev_dbg(xpc_chan, "ch->func() returned, msg=0x%p, " @@ -2203,7 +2203,7 @@ xpc_acknowledge_msgs(struct xpc_channel *ch, s64 initial_get, u8 msg_flags) * xpc_initiate_allocate(). */ void -xpc_initiate_received(partid_t partid, int ch_number, void *payload) +xpc_initiate_received(short partid, int ch_number, void *payload) { struct xpc_partition *part = &xpc_partitions[partid]; struct xpc_channel *ch; diff --git a/drivers/misc/sgi-xp/xpc_main.c b/drivers/misc/sgi-xp/xpc_main.c index f673ba90eb0eb2ab68187e00b723431f15d90389..08256ed0d9a6ffdf42ada557d715d88925d6cbbc 100644 --- a/drivers/misc/sgi-xp/xpc_main.c +++ b/drivers/misc/sgi-xp/xpc_main.c @@ -315,13 +315,13 @@ xpc_initiate_discovery(void *ignore) * the XPC per partition variables from the remote partition and waiting for * the remote partition to pull ours. */ -static enum xpc_retval +static enum xp_retval xpc_make_first_contact(struct xpc_partition *part) { - enum xpc_retval ret; + enum xp_retval ret; - while ((ret = xpc_pull_remote_vars_part(part)) != xpcSuccess) { - if (ret != xpcRetry) { + while ((ret = xpc_pull_remote_vars_part(part)) != xpSuccess) { + if (ret != xpRetry) { XPC_DEACTIVATE_PARTITION(part, ret); return ret; } @@ -406,7 +406,7 @@ xpc_partition_up(struct xpc_partition *part) dev_dbg(xpc_chan, "activating partition %d\n", XPC_PARTID(part)); - if (xpc_setup_infrastructure(part) != xpcSuccess) + if (xpc_setup_infrastructure(part) != xpSuccess) return; /* @@ -418,7 +418,7 @@ xpc_partition_up(struct xpc_partition *part) (void)xpc_part_ref(part); /* this will always succeed */ - if (xpc_make_first_contact(part) == xpcSuccess) + if (xpc_make_first_contact(part) == xpSuccess) xpc_channel_mgr(part); xpc_part_deref(part); @@ -429,7 +429,7 @@ xpc_partition_up(struct xpc_partition *part) static int xpc_activating(void *__partid) { - partid_t partid = (u64)__partid; + short partid = (u64)__partid; struct xpc_partition *part = &xpc_partitions[partid]; unsigned long irq_flags; @@ -470,7 +470,7 @@ xpc_activating(void *__partid) spin_lock_irqsave(&part->act_lock, irq_flags); part->act_state = XPC_P_INACTIVE; - XPC_SET_REASON(part, xpcPhysAddrRegFailed, __LINE__); + XPC_SET_REASON(part, xpPhysAddrRegFailed, __LINE__); spin_unlock_irqrestore(&part->act_lock, irq_flags); part->remote_rp_pa = 0; return 0; @@ -488,7 +488,7 @@ xpc_activating(void *__partid) xpc_disallow_hb(partid, xpc_vars); xpc_mark_partition_inactive(part); - if (part->reason == xpcReactivating) { + if (part->reason == xpReactivating) { /* interrupting ourselves results in activating partition */ xpc_IPI_send_reactivate(part); } @@ -499,7 +499,7 @@ xpc_activating(void *__partid) void xpc_activate_partition(struct xpc_partition *part) { - partid_t partid = XPC_PARTID(part); + short partid = XPC_PARTID(part); unsigned long irq_flags; struct task_struct *kthread; @@ -508,7 +508,7 @@ xpc_activate_partition(struct xpc_partition *part) DBUG_ON(part->act_state != XPC_P_INACTIVE); part->act_state = XPC_P_ACTIVATION_REQ; - XPC_SET_REASON(part, xpcCloneKThread, __LINE__); + XPC_SET_REASON(part, xpCloneKThread, __LINE__); spin_unlock_irqrestore(&part->act_lock, irq_flags); @@ -517,7 +517,7 @@ xpc_activate_partition(struct xpc_partition *part) if (IS_ERR(kthread)) { spin_lock_irqsave(&part->act_lock, irq_flags); part->act_state = XPC_P_INACTIVE; - XPC_SET_REASON(part, xpcCloneKThreadFailed, __LINE__); + XPC_SET_REASON(part, xpCloneKThreadFailed, __LINE__); spin_unlock_irqrestore(&part->act_lock, irq_flags); } } @@ -541,7 +541,7 @@ xpc_activate_partition(struct xpc_partition *part) irqreturn_t xpc_notify_IRQ_handler(int irq, void *dev_id) { - partid_t partid = (partid_t) (u64)dev_id; + short partid = (short)(u64)dev_id; struct xpc_partition *part = &xpc_partitions[partid]; DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS); @@ -643,7 +643,7 @@ xpc_kthread_waitmsgs(struct xpc_partition *part, struct xpc_channel *ch) static int xpc_kthread_start(void *args) { - partid_t partid = XPC_UNPACK_ARG1(args); + short partid = XPC_UNPACK_ARG1(args); u16 ch_number = XPC_UNPACK_ARG2(args); struct xpc_partition *part = &xpc_partitions[partid]; struct xpc_channel *ch; @@ -696,7 +696,7 @@ xpc_kthread_start(void *args) ch->flags |= XPC_C_DISCONNECTINGCALLOUT; spin_unlock_irqrestore(&ch->lock, irq_flags); - xpc_disconnect_callout(ch, xpcDisconnecting); + xpc_disconnect_callout(ch, xpDisconnecting); spin_lock_irqsave(&ch->lock, irq_flags); ch->flags |= XPC_C_DISCONNECTINGCALLOUT_MADE; @@ -776,7 +776,7 @@ xpc_create_kthreads(struct xpc_channel *ch, int needed, * then we'll deadlock if all other kthreads assigned * to this channel are blocked in the channel's * registerer, because the only thing that will unblock - * them is the xpcDisconnecting callout that this + * them is the xpDisconnecting callout that this * failed kthread_run() would have made. */ @@ -796,7 +796,7 @@ xpc_create_kthreads(struct xpc_channel *ch, int needed, * to function. */ spin_lock_irqsave(&ch->lock, irq_flags); - XPC_DISCONNECT_CHANNEL(ch, xpcLackOfResources, + XPC_DISCONNECT_CHANNEL(ch, xpLackOfResources, &irq_flags); spin_unlock_irqrestore(&ch->lock, irq_flags); } @@ -809,7 +809,7 @@ void xpc_disconnect_wait(int ch_number) { unsigned long irq_flags; - partid_t partid; + short partid; struct xpc_partition *part; struct xpc_channel *ch; int wakeup_channel_mgr; @@ -857,9 +857,9 @@ xpc_disconnect_wait(int ch_number) } static void -xpc_do_exit(enum xpc_retval reason) +xpc_do_exit(enum xp_retval reason) { - partid_t partid; + short partid; int active_part_count, printed_waiting_msg = 0; struct xpc_partition *part; unsigned long printmsg_time, disengage_request_timeout = 0; @@ -955,7 +955,7 @@ xpc_do_exit(enum xpc_retval reason) del_timer_sync(&xpc_hb_timer); DBUG_ON(xpc_vars->heartbeating_to_mask != 0); - if (reason == xpcUnloading) { + if (reason == xpUnloading) { /* take ourselves off of the reboot_notifier_list */ (void)unregister_reboot_notifier(&xpc_reboot_notifier); @@ -981,20 +981,20 @@ xpc_do_exit(enum xpc_retval reason) static int xpc_system_reboot(struct notifier_block *nb, unsigned long event, void *unused) { - enum xpc_retval reason; + enum xp_retval reason; switch (event) { case SYS_RESTART: - reason = xpcSystemReboot; + reason = xpSystemReboot; break; case SYS_HALT: - reason = xpcSystemHalt; + reason = xpSystemHalt; break; case SYS_POWER_OFF: - reason = xpcSystemPoweroff; + reason = xpSystemPoweroff; break; default: - reason = xpcSystemGoingDown; + reason = xpSystemGoingDown; } xpc_do_exit(reason); @@ -1008,7 +1008,7 @@ static void xpc_die_disengage(void) { struct xpc_partition *part; - partid_t partid; + short partid; unsigned long engaged; long time, printmsg_time, disengage_request_timeout; @@ -1124,7 +1124,7 @@ int __init xpc_init(void) { int ret; - partid_t partid; + short partid; struct xpc_partition *part; struct task_struct *kthread; size_t buf_size; @@ -1279,7 +1279,7 @@ xpc_init(void) /* mark this new thread as a non-starter */ complete(&xpc_discovery_exited); - xpc_do_exit(xpcUnloading); + xpc_do_exit(xpUnloading); return -EBUSY; } @@ -1297,7 +1297,7 @@ module_init(xpc_init); void __exit xpc_exit(void) { - xpc_do_exit(xpcUnloading); + xpc_do_exit(xpUnloading); } module_exit(xpc_exit); diff --git a/drivers/misc/sgi-xp/xpc_partition.c b/drivers/misc/sgi-xp/xpc_partition.c index acd3fd4285d7c954c824286a804c48c6a75d39ce..7dd4b5812c422e844b399a1cb5624833cb0f5eb3 100644 --- a/drivers/misc/sgi-xp/xpc_partition.c +++ b/drivers/misc/sgi-xp/xpc_partition.c @@ -403,7 +403,7 @@ xpc_check_remote_hb(void) { struct xpc_vars *remote_vars; struct xpc_partition *part; - partid_t partid; + short partid; bte_result_t bres; remote_vars = (struct xpc_vars *)xpc_remote_copy_buffer; @@ -444,7 +444,7 @@ xpc_check_remote_hb(void) (remote_vars->heartbeat_offline == 0)) || !xpc_hb_allowed(sn_partition_id, remote_vars)) { - XPC_DEACTIVATE_PARTITION(part, xpcNoHeartbeat); + XPC_DEACTIVATE_PARTITION(part, xpNoHeartbeat); continue; } @@ -459,7 +459,7 @@ xpc_check_remote_hb(void) * is large enough to contain a copy of their reserved page header and * part_nasids mask. */ -static enum xpc_retval +static enum xp_retval xpc_get_remote_rp(int nasid, u64 *discovered_nasids, struct xpc_rsvd_page *remote_rp, u64 *remote_rp_pa) { @@ -469,7 +469,7 @@ xpc_get_remote_rp(int nasid, u64 *discovered_nasids, *remote_rp_pa = xpc_get_rsvd_page_pa(nasid); if (*remote_rp_pa == 0) - return xpcNoRsvdPageAddr; + return xpNoRsvdPageAddr; /* pull over the reserved page header and part_nasids mask */ bres = xp_bte_copy(*remote_rp_pa, (u64)remote_rp, @@ -489,18 +489,18 @@ xpc_get_remote_rp(int nasid, u64 *discovered_nasids, if (remote_rp->partid < 1 || remote_rp->partid > (XP_MAX_PARTITIONS - 1)) { - return xpcInvalidPartid; + return xpInvalidPartid; } if (remote_rp->partid == sn_partition_id) - return xpcLocalPartid; + return xpLocalPartid; if (XPC_VERSION_MAJOR(remote_rp->version) != XPC_VERSION_MAJOR(XPC_RP_VERSION)) { - return xpcBadVersion; + return xpBadVersion; } - return xpcSuccess; + return xpSuccess; } /* @@ -509,13 +509,13 @@ xpc_get_remote_rp(int nasid, u64 *discovered_nasids, * remote_vars points to a buffer that is cacheline aligned for BTE copies and * assumed to be of size XPC_RP_VARS_SIZE. */ -static enum xpc_retval +static enum xp_retval xpc_get_remote_vars(u64 remote_vars_pa, struct xpc_vars *remote_vars) { int bres; if (remote_vars_pa == 0) - return xpcVarsNotSet; + return xpVarsNotSet; /* pull over the cross partition variables */ bres = xp_bte_copy(remote_vars_pa, (u64)remote_vars, XPC_RP_VARS_SIZE, @@ -525,10 +525,10 @@ xpc_get_remote_vars(u64 remote_vars_pa, struct xpc_vars *remote_vars) if (XPC_VERSION_MAJOR(remote_vars->version) != XPC_VERSION_MAJOR(XPC_V_VERSION)) { - return xpcBadVersion; + return xpBadVersion; } - return xpcSuccess; + return xpSuccess; } /* @@ -604,16 +604,16 @@ xpc_identify_act_IRQ_req(int nasid) int reactivate = 0; int stamp_diff; struct timespec remote_rp_stamp = { 0, 0 }; - partid_t partid; + short partid; struct xpc_partition *part; - enum xpc_retval ret; + enum xp_retval ret; /* pull over the reserved page structure */ remote_rp = (struct xpc_rsvd_page *)xpc_remote_copy_buffer; ret = xpc_get_remote_rp(nasid, NULL, remote_rp, &remote_rp_pa); - if (ret != xpcSuccess) { + if (ret != xpSuccess) { dev_warn(xpc_part, "unable to get reserved page from nasid %d, " "which sent interrupt, reason=%d\n", nasid, ret); return; @@ -632,7 +632,7 @@ xpc_identify_act_IRQ_req(int nasid) remote_vars = (struct xpc_vars *)xpc_remote_copy_buffer; ret = xpc_get_remote_vars(remote_vars_pa, remote_vars); - if (ret != xpcSuccess) { + if (ret != xpSuccess) { dev_warn(xpc_part, "unable to get XPC variables from nasid %d, " "which sent interrupt, reason=%d\n", nasid, ret); @@ -699,7 +699,7 @@ xpc_identify_act_IRQ_req(int nasid) &remote_rp_stamp, remote_rp_pa, remote_vars_pa, remote_vars); part->reactivate_nasid = nasid; - XPC_DEACTIVATE_PARTITION(part, xpcReactivating); + XPC_DEACTIVATE_PARTITION(part, xpReactivating); return; } @@ -754,11 +754,11 @@ xpc_identify_act_IRQ_req(int nasid) if (reactivate) { part->reactivate_nasid = nasid; - XPC_DEACTIVATE_PARTITION(part, xpcReactivating); + XPC_DEACTIVATE_PARTITION(part, xpReactivating); } else if (XPC_SUPPORTS_DISENGAGE_REQUEST(part->remote_vars_version) && xpc_partition_disengage_requested(1UL << partid)) { - XPC_DEACTIVATE_PARTITION(part, xpcOtherGoingDown); + XPC_DEACTIVATE_PARTITION(part, xpOtherGoingDown); } } @@ -825,7 +825,7 @@ xpc_identify_act_IRQ_sender(void) int xpc_partition_disengaged(struct xpc_partition *part) { - partid_t partid = XPC_PARTID(part); + short partid = XPC_PARTID(part); int disengaged; disengaged = (xpc_partition_engaged(1UL << partid) == 0); @@ -870,20 +870,20 @@ xpc_partition_disengaged(struct xpc_partition *part) /* * Mark specified partition as active. */ -enum xpc_retval +enum xp_retval xpc_mark_partition_active(struct xpc_partition *part) { unsigned long irq_flags; - enum xpc_retval ret; + enum xp_retval ret; dev_dbg(xpc_part, "setting partition %d to ACTIVE\n", XPC_PARTID(part)); spin_lock_irqsave(&part->act_lock, irq_flags); if (part->act_state == XPC_P_ACTIVATING) { part->act_state = XPC_P_ACTIVE; - ret = xpcSuccess; + ret = xpSuccess; } else { - DBUG_ON(part->reason == xpcSuccess); + DBUG_ON(part->reason == xpSuccess); ret = part->reason; } spin_unlock_irqrestore(&part->act_lock, irq_flags); @@ -896,7 +896,7 @@ xpc_mark_partition_active(struct xpc_partition *part) */ void xpc_deactivate_partition(const int line, struct xpc_partition *part, - enum xpc_retval reason) + enum xp_retval reason) { unsigned long irq_flags; @@ -905,15 +905,15 @@ xpc_deactivate_partition(const int line, struct xpc_partition *part, if (part->act_state == XPC_P_INACTIVE) { XPC_SET_REASON(part, reason, line); spin_unlock_irqrestore(&part->act_lock, irq_flags); - if (reason == xpcReactivating) { + if (reason == xpReactivating) { /* we interrupt ourselves to reactivate partition */ xpc_IPI_send_reactivate(part); } return; } if (part->act_state == XPC_P_DEACTIVATING) { - if ((part->reason == xpcUnloading && reason != xpcUnloading) || - reason == xpcReactivating) { + if ((part->reason == xpUnloading && reason != xpUnloading) || + reason == xpReactivating) { XPC_SET_REASON(part, reason, line); } spin_unlock_irqrestore(&part->act_lock, irq_flags); @@ -982,10 +982,10 @@ xpc_discovery(void) int max_regions; int nasid; struct xpc_rsvd_page *rp; - partid_t partid; + short partid; struct xpc_partition *part; u64 *discovered_nasids; - enum xpc_retval ret; + enum xp_retval ret; remote_rp = xpc_kmalloc_cacheline_aligned(XPC_RP_HEADER_SIZE + xp_nasid_mask_bytes, @@ -1063,12 +1063,12 @@ xpc_discovery(void) ret = xpc_get_remote_rp(nasid, discovered_nasids, remote_rp, &remote_rp_pa); - if (ret != xpcSuccess) { + if (ret != xpSuccess) { dev_dbg(xpc_part, "unable to get reserved page " "from nasid %d, reason=%d\n", nasid, ret); - if (ret == xpcLocalPartid) + if (ret == xpLocalPartid) break; continue; @@ -1082,7 +1082,7 @@ xpc_discovery(void) /* pull over the cross partition variables */ ret = xpc_get_remote_vars(remote_vars_pa, remote_vars); - if (ret != xpcSuccess) { + if (ret != xpSuccess) { dev_dbg(xpc_part, "unable to get XPC variables " "from nasid %d, reason=%d\n", nasid, ret); @@ -1116,7 +1116,7 @@ xpc_discovery(void) "register xp_addr region 0x%016lx\n", partid, remote_vars->amos_page_pa); - XPC_SET_REASON(part, xpcPhysAddrRegFailed, + XPC_SET_REASON(part, xpPhysAddrRegFailed, __LINE__); break; } @@ -1151,8 +1151,8 @@ xpc_discovery(void) * Given a partid, get the nasids owned by that partition from the * remote partition's reserved page. */ -enum xpc_retval -xpc_initiate_partid_to_nasids(partid_t partid, void *nasid_mask) +enum xp_retval +xpc_initiate_partid_to_nasids(short partid, void *nasid_mask) { struct xpc_partition *part; u64 part_nasid_pa; @@ -1160,7 +1160,7 @@ xpc_initiate_partid_to_nasids(partid_t partid, void *nasid_mask) part = &xpc_partitions[partid]; if (part->remote_rp_pa == 0) - return xpcPartitionDown; + return xpPartitionDown; memset(nasid_mask, 0, XP_NASID_MASK_BYTES); diff --git a/drivers/misc/sgi-xp/xpnet.c b/drivers/misc/sgi-xp/xpnet.c index a9543c65814d82d1560c211e9f00958c7d95c5c3..822dc8e8d7f0662b9f37d2aa50d2c7b4eb0d4a95 100644 --- a/drivers/misc/sgi-xp/xpnet.c +++ b/drivers/misc/sgi-xp/xpnet.c @@ -166,7 +166,7 @@ struct device *xpnet = &xpnet_dbg_subname; * Packet was recevied by XPC and forwarded to us. */ static void -xpnet_receive(partid_t partid, int channel, struct xpnet_message *msg) +xpnet_receive(short partid, int channel, struct xpnet_message *msg) { struct sk_buff *skb; bte_result_t bret; @@ -282,7 +282,7 @@ xpnet_receive(partid_t partid, int channel, struct xpnet_message *msg) * state or message reception on a connection. */ static void -xpnet_connection_activity(enum xpc_retval reason, partid_t partid, int channel, +xpnet_connection_activity(enum xp_retval reason, short partid, int channel, void *data, void *key) { long bp; @@ -291,13 +291,13 @@ xpnet_connection_activity(enum xpc_retval reason, partid_t partid, int channel, DBUG_ON(channel != XPC_NET_CHANNEL); switch (reason) { - case xpcMsgReceived: /* message received */ + case xpMsgReceived: /* message received */ DBUG_ON(data == NULL); xpnet_receive(partid, channel, (struct xpnet_message *)data); break; - case xpcConnected: /* connection completed to a partition */ + case xpConnected: /* connection completed to a partition */ spin_lock_bh(&xpnet_broadcast_lock); xpnet_broadcast_partitions |= 1UL << (partid - 1); bp = xpnet_broadcast_partitions; @@ -330,7 +330,7 @@ xpnet_connection_activity(enum xpc_retval reason, partid_t partid, int channel, static int xpnet_dev_open(struct net_device *dev) { - enum xpc_retval ret; + enum xp_retval ret; dev_dbg(xpnet, "calling xpc_connect(%d, 0x%p, NULL, %ld, %ld, %ld, " "%ld)\n", XPC_NET_CHANNEL, xpnet_connection_activity, @@ -340,7 +340,7 @@ xpnet_dev_open(struct net_device *dev) ret = xpc_connect(XPC_NET_CHANNEL, xpnet_connection_activity, NULL, XPNET_MSG_SIZE, XPNET_MSG_NENTRIES, XPNET_MAX_KTHREADS, XPNET_MAX_IDLE_KTHREADS); - if (ret != xpcSuccess) { + if (ret != xpSuccess) { dev_err(xpnet, "ifconfig up of %s failed on XPC connect, " "ret=%d\n", dev->name, ret); @@ -407,7 +407,7 @@ xpnet_dev_get_stats(struct net_device *dev) * release the skb and then release our pending message structure. */ static void -xpnet_send_completed(enum xpc_retval reason, partid_t partid, int channel, +xpnet_send_completed(enum xp_retval reason, short partid, int channel, void *__qm) { struct xpnet_pending_msg *queued_msg = (struct xpnet_pending_msg *)__qm; @@ -439,12 +439,12 @@ static int xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct xpnet_pending_msg *queued_msg; - enum xpc_retval ret; + enum xp_retval ret; struct xpnet_message *msg; u64 start_addr, end_addr; long dp; u8 second_mac_octet; - partid_t dest_partid; + short dest_partid; struct xpnet_dev_private *priv; u16 embedded_bytes; @@ -528,7 +528,7 @@ xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) ret = xpc_allocate(dest_partid, XPC_NET_CHANNEL, XPC_NOWAIT, (void **)&msg); - if (unlikely(ret != xpcSuccess)) + if (unlikely(ret != xpSuccess)) continue; msg->embedded_bytes = embedded_bytes; @@ -557,7 +557,7 @@ xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) ret = xpc_send_notify(dest_partid, XPC_NET_CHANNEL, msg, xpnet_send_completed, queued_msg); - if (unlikely(ret != xpcSuccess)) { + if (unlikely(ret != xpSuccess)) { atomic_dec(&queued_msg->use_count); continue; } diff --git a/drivers/mmc/card/Kconfig b/drivers/mmc/card/Kconfig index aa8a4e461942801db89ec3963c7dabf605dfb006..dd0f398ee2f5398593b61100ad58850ca9e9d0b6 100644 --- a/drivers/mmc/card/Kconfig +++ b/drivers/mmc/card/Kconfig @@ -39,3 +39,15 @@ config SDIO_UART SDIO function driver for SDIO cards that implements the UART class, as well as the GPS class which appears like a UART. +config MMC_TEST + tristate "MMC host test driver" + default n + help + Development driver that performs a series of reads and writes + to a memory card in order to expose certain well known bugs + in host controllers. The tests are executed by writing to the + "test" file in sysfs under each card. Note that whatever is + on your card will be overwritten by these tests. + + This driver is only of interest to those developing or + testing a host driver. Most people should say N here. diff --git a/drivers/mmc/card/Makefile b/drivers/mmc/card/Makefile index fc5a784cfa1a7410f2025fdfcdddd08f06e8ec4b..0d407514f67dd556c675649cd4f974958a6d7aea 100644 --- a/drivers/mmc/card/Makefile +++ b/drivers/mmc/card/Makefile @@ -8,6 +8,7 @@ endif obj-$(CONFIG_MMC_BLOCK) += mmc_block.o mmc_block-objs := block.o queue.o +obj-$(CONFIG_MMC_TEST) += mmc_test.o obj-$(CONFIG_SDIO_UART) += sdio_uart.o diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c new file mode 100644 index 0000000000000000000000000000000000000000..ffadee549a414cd99a8f3a5c5db71f3554d019c8 --- /dev/null +++ b/drivers/mmc/card/mmc_test.c @@ -0,0 +1,892 @@ +/* + * linux/drivers/mmc/card/mmc_test.c + * + * Copyright 2007 Pierre Ossman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + */ + +#include +#include +#include +#include + +#include + +#define RESULT_OK 0 +#define RESULT_FAIL 1 +#define RESULT_UNSUP_HOST 2 +#define RESULT_UNSUP_CARD 3 + +#define BUFFER_SIZE (PAGE_SIZE * 4) + +struct mmc_test_card { + struct mmc_card *card; + + u8 *buffer; +}; + +/*******************************************************************/ +/* Helper functions */ +/*******************************************************************/ + +static int mmc_test_set_blksize(struct mmc_test_card *test, unsigned size) +{ + struct mmc_command cmd; + int ret; + + cmd.opcode = MMC_SET_BLOCKLEN; + cmd.arg = size; + cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; + ret = mmc_wait_for_cmd(test->card->host, &cmd, 0); + if (ret) + return ret; + + return 0; +} + +static int __mmc_test_transfer(struct mmc_test_card *test, int write, + unsigned broken_xfer, u8 *buffer, unsigned addr, + unsigned blocks, unsigned blksz) +{ + int ret, busy; + + struct mmc_request mrq; + struct mmc_command cmd; + struct mmc_command stop; + struct mmc_data data; + + struct scatterlist sg; + + memset(&mrq, 0, sizeof(struct mmc_request)); + + mrq.cmd = &cmd; + mrq.data = &data; + + memset(&cmd, 0, sizeof(struct mmc_command)); + + if (broken_xfer) { + if (blocks > 1) { + cmd.opcode = write ? + MMC_WRITE_BLOCK : MMC_READ_SINGLE_BLOCK; + } else { + cmd.opcode = MMC_SEND_STATUS; + } + } else { + if (blocks > 1) { + cmd.opcode = write ? + MMC_WRITE_MULTIPLE_BLOCK : MMC_READ_MULTIPLE_BLOCK; + } else { + cmd.opcode = write ? + MMC_WRITE_BLOCK : MMC_READ_SINGLE_BLOCK; + } + } + + if (broken_xfer && blocks == 1) + cmd.arg = test->card->rca << 16; + else + cmd.arg = addr; + cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; + + memset(&stop, 0, sizeof(struct mmc_command)); + + if (!broken_xfer && (blocks > 1)) { + stop.opcode = MMC_STOP_TRANSMISSION; + stop.arg = 0; + stop.flags = MMC_RSP_R1B | MMC_CMD_AC; + + mrq.stop = &stop; + } + + memset(&data, 0, sizeof(struct mmc_data)); + + data.blksz = blksz; + data.blocks = blocks; + data.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ; + data.sg = &sg; + data.sg_len = 1; + + sg_init_one(&sg, buffer, blocks * blksz); + + mmc_set_data_timeout(&data, test->card); + + mmc_wait_for_req(test->card->host, &mrq); + + ret = 0; + + if (broken_xfer) { + if (!ret && cmd.error) + ret = cmd.error; + if (!ret && data.error == 0) + ret = RESULT_FAIL; + if (!ret && data.error != -ETIMEDOUT) + ret = data.error; + if (!ret && stop.error) + ret = stop.error; + if (blocks > 1) { + if (!ret && data.bytes_xfered > blksz) + ret = RESULT_FAIL; + } else { + if (!ret && data.bytes_xfered > 0) + ret = RESULT_FAIL; + } + } else { + if (!ret && cmd.error) + ret = cmd.error; + if (!ret && data.error) + ret = data.error; + if (!ret && stop.error) + ret = stop.error; + if (!ret && data.bytes_xfered != blocks * blksz) + ret = RESULT_FAIL; + } + + if (ret == -EINVAL) + ret = RESULT_UNSUP_HOST; + + busy = 0; + do { + int ret2; + + memset(&cmd, 0, sizeof(struct mmc_command)); + + cmd.opcode = MMC_SEND_STATUS; + cmd.arg = test->card->rca << 16; + cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; + + ret2 = mmc_wait_for_cmd(test->card->host, &cmd, 0); + if (ret2) + break; + + if (!busy && !(cmd.resp[0] & R1_READY_FOR_DATA)) { + busy = 1; + printk(KERN_INFO "%s: Warning: Host did not " + "wait for busy state to end.\n", + mmc_hostname(test->card->host)); + } + } while (!(cmd.resp[0] & R1_READY_FOR_DATA)); + + return ret; +} + +static int mmc_test_transfer(struct mmc_test_card *test, int write, + u8 *buffer, unsigned addr, unsigned blocks, unsigned blksz) +{ + return __mmc_test_transfer(test, write, 0, buffer, + addr, blocks, blksz); +} + +static int mmc_test_prepare_verify(struct mmc_test_card *test, int write) +{ + int ret, i; + + ret = mmc_test_set_blksize(test, 512); + if (ret) + return ret; + + if (write) + memset(test->buffer, 0xDF, BUFFER_SIZE); + else { + for (i = 0;i < BUFFER_SIZE;i++) + test->buffer[i] = i; + } + + for (i = 0;i < BUFFER_SIZE / 512;i++) { + ret = mmc_test_transfer(test, 1, test->buffer + i * 512, + i * 512, 1, 512); + if (ret) + return ret; + } + + return 0; +} + +static int mmc_test_prepare_verify_write(struct mmc_test_card *test) +{ + return mmc_test_prepare_verify(test, 1); +} + +static int mmc_test_prepare_verify_read(struct mmc_test_card *test) +{ + return mmc_test_prepare_verify(test, 0); +} + +static int mmc_test_verified_transfer(struct mmc_test_card *test, int write, + u8 *buffer, unsigned addr, unsigned blocks, unsigned blksz) +{ + int ret, i, sectors; + + /* + * It is assumed that the above preparation has been done. + */ + + memset(test->buffer, 0, BUFFER_SIZE); + + if (write) { + for (i = 0;i < blocks * blksz;i++) + buffer[i] = i; + } + + ret = mmc_test_set_blksize(test, blksz); + if (ret) + return ret; + + ret = mmc_test_transfer(test, write, buffer, addr, blocks, blksz); + if (ret) + return ret; + + if (write) { + ret = mmc_test_set_blksize(test, 512); + if (ret) + return ret; + + sectors = (blocks * blksz + 511) / 512; + if ((sectors * 512) == (blocks * blksz)) + sectors++; + + if ((sectors * 512) > BUFFER_SIZE) + return -EINVAL; + + memset(test->buffer, 0, sectors * 512); + + for (i = 0;i < sectors;i++) { + ret = mmc_test_transfer(test, 0, + test->buffer + i * 512, + addr + i * 512, 1, 512); + if (ret) + return ret; + } + + for (i = 0;i < blocks * blksz;i++) { + if (test->buffer[i] != (u8)i) + return RESULT_FAIL; + } + + for (;i < sectors * 512;i++) { + if (test->buffer[i] != 0xDF) + return RESULT_FAIL; + } + } else { + for (i = 0;i < blocks * blksz;i++) { + if (buffer[i] != (u8)i) + return RESULT_FAIL; + } + } + + return 0; +} + +static int mmc_test_cleanup_verify(struct mmc_test_card *test) +{ + int ret, i; + + ret = mmc_test_set_blksize(test, 512); + if (ret) + return ret; + + memset(test->buffer, 0, BUFFER_SIZE); + + for (i = 0;i < BUFFER_SIZE / 512;i++) { + ret = mmc_test_transfer(test, 1, test->buffer + i * 512, + i * 512, 1, 512); + if (ret) + return ret; + } + + return 0; +} + +/*******************************************************************/ +/* Tests */ +/*******************************************************************/ + +struct mmc_test_case { + const char *name; + + int (*prepare)(struct mmc_test_card *); + int (*run)(struct mmc_test_card *); + int (*cleanup)(struct mmc_test_card *); +}; + +static int mmc_test_basic_write(struct mmc_test_card *test) +{ + int ret; + + ret = mmc_test_set_blksize(test, 512); + if (ret) + return ret; + + ret = mmc_test_transfer(test, 1, test->buffer, 0, 1, 512); + if (ret) + return ret; + + return 0; +} + +static int mmc_test_basic_read(struct mmc_test_card *test) +{ + int ret; + + ret = mmc_test_set_blksize(test, 512); + if (ret) + return ret; + + ret = mmc_test_transfer(test, 0, test->buffer, 0, 1, 512); + if (ret) + return ret; + + return 0; +} + +static int mmc_test_verify_write(struct mmc_test_card *test) +{ + int ret; + + ret = mmc_test_verified_transfer(test, 1, test->buffer, 0, 1, 512); + if (ret) + return ret; + + return 0; +} + +static int mmc_test_verify_read(struct mmc_test_card *test) +{ + int ret; + + ret = mmc_test_verified_transfer(test, 0, test->buffer, 0, 1, 512); + if (ret) + return ret; + + return 0; +} + +static int mmc_test_multi_write(struct mmc_test_card *test) +{ + int ret; + unsigned int size; + + if (test->card->host->max_blk_count == 1) + return RESULT_UNSUP_HOST; + + size = PAGE_SIZE * 2; + size = min(size, test->card->host->max_req_size); + size = min(size, test->card->host->max_seg_size); + size = min(size, test->card->host->max_blk_count * 512); + + if (size < 1024) + return RESULT_UNSUP_HOST; + + ret = mmc_test_verified_transfer(test, 1, test->buffer, 0, + size / 512, 512); + if (ret) + return ret; + + return 0; +} + +static int mmc_test_multi_read(struct mmc_test_card *test) +{ + int ret; + unsigned int size; + + if (test->card->host->max_blk_count == 1) + return RESULT_UNSUP_HOST; + + size = PAGE_SIZE * 2; + size = min(size, test->card->host->max_req_size); + size = min(size, test->card->host->max_seg_size); + size = min(size, test->card->host->max_blk_count * 512); + + if (size < 1024) + return RESULT_UNSUP_HOST; + + ret = mmc_test_verified_transfer(test, 0, test->buffer, 0, + size / 512, 512); + if (ret) + return ret; + + return 0; +} + +static int mmc_test_pow2_write(struct mmc_test_card *test) +{ + int ret, i; + + if (!test->card->csd.write_partial) + return RESULT_UNSUP_CARD; + + for (i = 1; i < 512;i <<= 1) { + ret = mmc_test_verified_transfer(test, 1, + test->buffer, 0, 1, i); + if (ret) + return ret; + } + + return 0; +} + +static int mmc_test_pow2_read(struct mmc_test_card *test) +{ + int ret, i; + + if (!test->card->csd.read_partial) + return RESULT_UNSUP_CARD; + + for (i = 1; i < 512;i <<= 1) { + ret = mmc_test_verified_transfer(test, 0, + test->buffer, 0, 1, i); + if (ret) + return ret; + } + + return 0; +} + +static int mmc_test_weird_write(struct mmc_test_card *test) +{ + int ret, i; + + if (!test->card->csd.write_partial) + return RESULT_UNSUP_CARD; + + for (i = 3; i < 512;i += 7) { + ret = mmc_test_verified_transfer(test, 1, + test->buffer, 0, 1, i); + if (ret) + return ret; + } + + return 0; +} + +static int mmc_test_weird_read(struct mmc_test_card *test) +{ + int ret, i; + + if (!test->card->csd.read_partial) + return RESULT_UNSUP_CARD; + + for (i = 3; i < 512;i += 7) { + ret = mmc_test_verified_transfer(test, 0, + test->buffer, 0, 1, i); + if (ret) + return ret; + } + + return 0; +} + +static int mmc_test_align_write(struct mmc_test_card *test) +{ + int ret, i; + + for (i = 1;i < 4;i++) { + ret = mmc_test_verified_transfer(test, 1, test->buffer + i, + 0, 1, 512); + if (ret) + return ret; + } + + return 0; +} + +static int mmc_test_align_read(struct mmc_test_card *test) +{ + int ret, i; + + for (i = 1;i < 4;i++) { + ret = mmc_test_verified_transfer(test, 0, test->buffer + i, + 0, 1, 512); + if (ret) + return ret; + } + + return 0; +} + +static int mmc_test_align_multi_write(struct mmc_test_card *test) +{ + int ret, i; + unsigned int size; + + if (test->card->host->max_blk_count == 1) + return RESULT_UNSUP_HOST; + + size = PAGE_SIZE * 2; + size = min(size, test->card->host->max_req_size); + size = min(size, test->card->host->max_seg_size); + size = min(size, test->card->host->max_blk_count * 512); + + if (size < 1024) + return RESULT_UNSUP_HOST; + + for (i = 1;i < 4;i++) { + ret = mmc_test_verified_transfer(test, 1, test->buffer + i, + 0, size / 512, 512); + if (ret) + return ret; + } + + return 0; +} + +static int mmc_test_align_multi_read(struct mmc_test_card *test) +{ + int ret, i; + unsigned int size; + + if (test->card->host->max_blk_count == 1) + return RESULT_UNSUP_HOST; + + size = PAGE_SIZE * 2; + size = min(size, test->card->host->max_req_size); + size = min(size, test->card->host->max_seg_size); + size = min(size, test->card->host->max_blk_count * 512); + + if (size < 1024) + return RESULT_UNSUP_HOST; + + for (i = 1;i < 4;i++) { + ret = mmc_test_verified_transfer(test, 0, test->buffer + i, + 0, size / 512, 512); + if (ret) + return ret; + } + + return 0; +} + +static int mmc_test_xfersize_write(struct mmc_test_card *test) +{ + int ret; + + ret = mmc_test_set_blksize(test, 512); + if (ret) + return ret; + + ret = __mmc_test_transfer(test, 1, 1, test->buffer, 0, 1, 512); + if (ret) + return ret; + + return 0; +} + +static int mmc_test_xfersize_read(struct mmc_test_card *test) +{ + int ret; + + ret = mmc_test_set_blksize(test, 512); + if (ret) + return ret; + + ret = __mmc_test_transfer(test, 0, 1, test->buffer, 0, 1, 512); + if (ret) + return ret; + + return 0; +} + +static int mmc_test_multi_xfersize_write(struct mmc_test_card *test) +{ + int ret; + + if (test->card->host->max_blk_count == 1) + return RESULT_UNSUP_HOST; + + ret = mmc_test_set_blksize(test, 512); + if (ret) + return ret; + + ret = __mmc_test_transfer(test, 1, 1, test->buffer, 0, 2, 512); + if (ret) + return ret; + + return 0; +} + +static int mmc_test_multi_xfersize_read(struct mmc_test_card *test) +{ + int ret; + + if (test->card->host->max_blk_count == 1) + return RESULT_UNSUP_HOST; + + ret = mmc_test_set_blksize(test, 512); + if (ret) + return ret; + + ret = __mmc_test_transfer(test, 0, 1, test->buffer, 0, 2, 512); + if (ret) + return ret; + + return 0; +} + +static const struct mmc_test_case mmc_test_cases[] = { + { + .name = "Basic write (no data verification)", + .run = mmc_test_basic_write, + }, + + { + .name = "Basic read (no data verification)", + .run = mmc_test_basic_read, + }, + + { + .name = "Basic write (with data verification)", + .prepare = mmc_test_prepare_verify_write, + .run = mmc_test_verify_write, + .cleanup = mmc_test_cleanup_verify, + }, + + { + .name = "Basic read (with data verification)", + .prepare = mmc_test_prepare_verify_read, + .run = mmc_test_verify_read, + .cleanup = mmc_test_cleanup_verify, + }, + + { + .name = "Multi-block write", + .prepare = mmc_test_prepare_verify_write, + .run = mmc_test_multi_write, + .cleanup = mmc_test_cleanup_verify, + }, + + { + .name = "Multi-block read", + .prepare = mmc_test_prepare_verify_read, + .run = mmc_test_multi_read, + .cleanup = mmc_test_cleanup_verify, + }, + + { + .name = "Power of two block writes", + .prepare = mmc_test_prepare_verify_write, + .run = mmc_test_pow2_write, + .cleanup = mmc_test_cleanup_verify, + }, + + { + .name = "Power of two block reads", + .prepare = mmc_test_prepare_verify_read, + .run = mmc_test_pow2_read, + .cleanup = mmc_test_cleanup_verify, + }, + + { + .name = "Weird sized block writes", + .prepare = mmc_test_prepare_verify_write, + .run = mmc_test_weird_write, + .cleanup = mmc_test_cleanup_verify, + }, + + { + .name = "Weird sized block reads", + .prepare = mmc_test_prepare_verify_read, + .run = mmc_test_weird_read, + .cleanup = mmc_test_cleanup_verify, + }, + + { + .name = "Badly aligned write", + .prepare = mmc_test_prepare_verify_write, + .run = mmc_test_align_write, + .cleanup = mmc_test_cleanup_verify, + }, + + { + .name = "Badly aligned read", + .prepare = mmc_test_prepare_verify_read, + .run = mmc_test_align_read, + .cleanup = mmc_test_cleanup_verify, + }, + + { + .name = "Badly aligned multi-block write", + .prepare = mmc_test_prepare_verify_write, + .run = mmc_test_align_multi_write, + .cleanup = mmc_test_cleanup_verify, + }, + + { + .name = "Badly aligned multi-block read", + .prepare = mmc_test_prepare_verify_read, + .run = mmc_test_align_multi_read, + .cleanup = mmc_test_cleanup_verify, + }, + + { + .name = "Correct xfer_size at write (start failure)", + .run = mmc_test_xfersize_write, + }, + + { + .name = "Correct xfer_size at read (start failure)", + .run = mmc_test_xfersize_read, + }, + + { + .name = "Correct xfer_size at write (midway failure)", + .run = mmc_test_multi_xfersize_write, + }, + + { + .name = "Correct xfer_size at read (midway failure)", + .run = mmc_test_multi_xfersize_read, + }, +}; + +static struct mutex mmc_test_lock; + +static void mmc_test_run(struct mmc_test_card *test) +{ + int i, ret; + + printk(KERN_INFO "%s: Starting tests of card %s...\n", + mmc_hostname(test->card->host), mmc_card_id(test->card)); + + mmc_claim_host(test->card->host); + + for (i = 0;i < ARRAY_SIZE(mmc_test_cases);i++) { + printk(KERN_INFO "%s: Test case %d. %s...\n", + mmc_hostname(test->card->host), i + 1, + mmc_test_cases[i].name); + + if (mmc_test_cases[i].prepare) { + ret = mmc_test_cases[i].prepare(test); + if (ret) { + printk(KERN_INFO "%s: Result: Prepare " + "stage failed! (%d)\n", + mmc_hostname(test->card->host), + ret); + continue; + } + } + + ret = mmc_test_cases[i].run(test); + switch (ret) { + case RESULT_OK: + printk(KERN_INFO "%s: Result: OK\n", + mmc_hostname(test->card->host)); + break; + case RESULT_FAIL: + printk(KERN_INFO "%s: Result: FAILED\n", + mmc_hostname(test->card->host)); + break; + case RESULT_UNSUP_HOST: + printk(KERN_INFO "%s: Result: UNSUPPORTED " + "(by host)\n", + mmc_hostname(test->card->host)); + break; + case RESULT_UNSUP_CARD: + printk(KERN_INFO "%s: Result: UNSUPPORTED " + "(by card)\n", + mmc_hostname(test->card->host)); + break; + default: + printk(KERN_INFO "%s: Result: ERROR (%d)\n", + mmc_hostname(test->card->host), ret); + } + + if (mmc_test_cases[i].cleanup) { + ret = mmc_test_cases[i].cleanup(test); + if (ret) { + printk(KERN_INFO "%s: Warning: Cleanup " + "stage failed! (%d)\n", + mmc_hostname(test->card->host), + ret); + } + } + } + + mmc_release_host(test->card->host); + + printk(KERN_INFO "%s: Tests completed.\n", + mmc_hostname(test->card->host)); +} + +static ssize_t mmc_test_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + mutex_lock(&mmc_test_lock); + mutex_unlock(&mmc_test_lock); + + return 0; +} + +static ssize_t mmc_test_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct mmc_card *card; + struct mmc_test_card *test; + + card = container_of(dev, struct mmc_card, dev); + + test = kzalloc(sizeof(struct mmc_test_card), GFP_KERNEL); + if (!test) + return -ENOMEM; + + test->card = card; + + test->buffer = kzalloc(BUFFER_SIZE, GFP_KERNEL); + if (test->buffer) { + mutex_lock(&mmc_test_lock); + mmc_test_run(test); + mutex_unlock(&mmc_test_lock); + } + + kfree(test->buffer); + kfree(test); + + return count; +} + +static DEVICE_ATTR(test, S_IWUSR | S_IRUGO, mmc_test_show, mmc_test_store); + +static int mmc_test_probe(struct mmc_card *card) +{ + int ret; + + mutex_init(&mmc_test_lock); + + ret = device_create_file(&card->dev, &dev_attr_test); + if (ret) + return ret; + + return 0; +} + +static void mmc_test_remove(struct mmc_card *card) +{ + device_remove_file(&card->dev, &dev_attr_test); +} + +static struct mmc_driver mmc_driver = { + .drv = { + .name = "mmc_test", + }, + .probe = mmc_test_probe, + .remove = mmc_test_remove, +}; + +static int __init mmc_test_init(void) +{ + return mmc_register_driver(&mmc_driver); +} + +static void __exit mmc_test_exit(void) +{ + mmc_unregister_driver(&mmc_driver); +} + +module_init(mmc_test_init); +module_exit(mmc_test_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Multimedia Card (MMC) host test driver"); +MODULE_AUTHOR("Pierre Ossman"); diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index a28fc2f68ce24dbf525628bdf640f2315b06713e..8979ad330a4d5e6e154b4e8be4794a0b28765eba 100644 --- a/drivers/mmc/host/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c @@ -663,9 +663,12 @@ static void at91_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) gpio_set_value(host->board->vcc_pin, 0); break; case MMC_POWER_UP: - case MMC_POWER_ON: gpio_set_value(host->board->vcc_pin, 1); break; + case MMC_POWER_ON: + break; + default: + WARN_ON(1); } } } diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 626ac083f4e09c294c4d465dd3c85e886082867d..da5fecad74d9a79152076730981a36d35cfe3bed 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -425,7 +425,7 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) host->cclk = host->mclk; } else { clk = host->mclk / (2 * ios->clock) - 1; - if (clk > 256) + if (clk >= 256) clk = 255; host->cclk = host->mclk / (2 * (clk + 1)); } @@ -512,6 +512,18 @@ static int mmci_probe(struct amba_device *dev, void *id) host->plat = plat; host->mclk = clk_get_rate(host->clk); + /* + * According to the spec, mclk is max 100 MHz, + * so we try to adjust the clock down to this, + * (if possible). + */ + if (host->mclk > 100000000) { + ret = clk_set_rate(host->clk, 100000000); + if (ret < 0) + goto clk_disable; + host->mclk = clk_get_rate(host->clk); + DBG(host, "eventual mclk rate: %u Hz\n", host->mclk); + } host->mmc = mmc; host->base = ioremap(dev->res.start, SZ_4K); if (!host->base) { diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index 14759e9f42adb922fc15fa84b40347b43caed1d6..549517c35675971b3448a988f83cb2b2369b305d 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c @@ -1003,7 +1003,7 @@ static void mmc_omap_dma_cb(int lch, u16 ch_status, void *data) static int mmc_omap_get_dma_channel(struct mmc_omap_host *host, struct mmc_data *data) { - const char *dev_name; + const char *dma_dev_name; int sync_dev, dma_ch, is_read, r; is_read = !(data->flags & MMC_DATA_WRITE); @@ -1018,21 +1018,21 @@ static int mmc_omap_get_dma_channel(struct mmc_omap_host *host, struct mmc_data if (is_read) { if (host->id == 1) { sync_dev = OMAP_DMA_MMC_RX; - dev_name = "MMC1 read"; + dma_dev_name = "MMC1 read"; } else { sync_dev = OMAP_DMA_MMC2_RX; - dev_name = "MMC2 read"; + dma_dev_name = "MMC2 read"; } } else { if (host->id == 1) { sync_dev = OMAP_DMA_MMC_TX; - dev_name = "MMC1 write"; + dma_dev_name = "MMC1 write"; } else { sync_dev = OMAP_DMA_MMC2_TX; - dev_name = "MMC2 write"; + dma_dev_name = "MMC2 write"; } } - r = omap_request_dma(sync_dev, dev_name, mmc_omap_dma_cb, + r = omap_request_dma(sync_dev, dma_dev_name, mmc_omap_dma_cb, host, &dma_ch); if (r != 0) { dev_dbg(mmc_dev(host->mmc), "omap_request_dma() failed with %d\n", r); diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 7fb02e177a3d13cd4b3439486b8dfb297bec2756..299118de8933e892c1953ac66856af7f12dd3a8e 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -187,7 +187,7 @@ struct sdhci_host { struct mmc_request *mrq; /* Current request */ struct mmc_command *cmd; /* Current command */ struct mmc_data *data; /* Current data request */ - int data_early:1; /* Data finished before cmd */ + unsigned int data_early:1; /* Data finished before cmd */ struct scatterlist *cur_sg; /* We're working on this */ int num_sg; /* Entries left */ diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index 1bd69aa9e22acd2905a28e0e5c76d27d0bd00c94..17bc87a43ff415d151125673b1cda275c4d7b28d 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig @@ -374,7 +374,7 @@ config MTD_REDWOOD config MTD_SOLUTIONENGINE tristate "CFI Flash device mapped on Hitachi SolutionEngine" - depends on SUPERH && MTD_CFI && MTD_REDBOOT_PARTS + depends on SUPERH && SOLUTION_ENGINE && MTD_CFI && MTD_REDBOOT_PARTS help This enables access to the flash chips on the Hitachi SolutionEngine and similar boards. Say 'Y' if you are building a kernel for such a board. @@ -480,13 +480,6 @@ config MTD_H720X This enables access to the flash chips on the Hynix evaluation boards. If you have such a board, say 'Y'. -config MTD_MPC1211 - tristate "CFI Flash device mapped on Interface MPC-1211" - depends on SH_MPC1211 && MTD_CFI - help - This enables access to the flash chips on the Interface MPC-1211(CTP/PCI/MPC-SH02). - If you have such a board, say 'Y'. - config MTD_OMAP_NOR tristate "TI OMAP board mappings" depends on MTD_CFI && ARCH_OMAP diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile index a9cbe80f99a0d909eec2f89e109dfd53a7365a50..957fb5f70f5efdc592f18df82a0a43c09e2c6b27 100644 --- a/drivers/mtd/maps/Makefile +++ b/drivers/mtd/maps/Makefile @@ -58,7 +58,6 @@ obj-$(CONFIG_MTD_WALNUT) += walnut.o obj-$(CONFIG_MTD_H720X) += h720x-flash.o obj-$(CONFIG_MTD_SBC8240) += sbc8240.o obj-$(CONFIG_MTD_NOR_TOTO) += omap-toto-flash.o -obj-$(CONFIG_MTD_MPC1211) += mpc1211.o obj-$(CONFIG_MTD_IXP4XX) += ixp4xx.o obj-$(CONFIG_MTD_IXP2000) += ixp2000.o obj-$(CONFIG_MTD_WRSBC8260) += wr_sbc82xx_flash.o diff --git a/drivers/mtd/maps/mpc1211.c b/drivers/mtd/maps/mpc1211.c deleted file mode 100644 index 45a00fac88acbcf0f8804afd3e92b6a2ea3b0722..0000000000000000000000000000000000000000 --- a/drivers/mtd/maps/mpc1211.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Flash on MPC-1211 - * - * $Id: mpc1211.c,v 1.4 2004/09/16 23:27:13 gleixner Exp $ - * - * (C) 2002 Interface, Saito.K & Jeanne - * - * GPL'd - */ - -#include -#include -#include -#include -#include -#include -#include - -static struct mtd_info *flash_mtd; -static struct mtd_partition *parsed_parts; - -struct map_info mpc1211_flash_map = { - .name = "MPC-1211 FLASH", - .size = 0x80000, - .bankwidth = 1, -}; - -static struct mtd_partition mpc1211_partitions[] = { - { - .name = "IPL & ETH-BOOT", - .offset = 0x00000000, - .size = 0x10000, - }, - { - .name = "Flash FS", - .offset = 0x00010000, - .size = MTDPART_SIZ_FULL, - } -}; - -static int __init init_mpc1211_maps(void) -{ - int nr_parts; - - mpc1211_flash_map.phys = 0; - mpc1211_flash_map.virt = (void __iomem *)P2SEGADDR(0); - - simple_map_init(&mpc1211_flash_map); - - printk(KERN_NOTICE "Probing for flash chips at 0x00000000:\n"); - flash_mtd = do_map_probe("jedec_probe", &mpc1211_flash_map); - if (!flash_mtd) { - printk(KERN_NOTICE "Flash chips not detected at either possible location.\n"); - return -ENXIO; - } - printk(KERN_NOTICE "MPC-1211: Flash at 0x%08lx\n", mpc1211_flash_map.virt & 0x1fffffff); - flash_mtd->module = THIS_MODULE; - - parsed_parts = mpc1211_partitions; - nr_parts = ARRAY_SIZE(mpc1211_partitions); - - add_mtd_partitions(flash_mtd, parsed_parts, nr_parts); - return 0; -} - -static void __exit cleanup_mpc1211_maps(void) -{ - if (parsed_parts) - del_mtd_partitions(flash_mtd); - else - del_mtd_device(flash_mtd); - map_destroy(flash_mtd); -} - -module_init(init_mpc1211_maps); -module_exit(cleanup_mpc1211_maps); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Saito.K & Jeanne "); -MODULE_DESCRIPTION("MTD map driver for MPC-1211 boards. Interface"); diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index 6f8e7d4cf74dbdd224fdbd4d7d1b5924c206ade0..2edda8cc7f9999af1e5f772df389c20719373190 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c @@ -319,7 +319,7 @@ static struct vortex_chip_info { {"3c920B-EMB-WNM (ATI Radeon 9100 IGP)", PCI_USES_MASTER, IS_TORNADO|HAS_MII|HAS_HWCKSM, 128, }, {"3c980 Cyclone", - PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, + PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM|EXTRA_PREAMBLE, 128, }, {"3c980C Python-T", PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, }, @@ -600,7 +600,6 @@ struct vortex_private { struct sk_buff* tx_skbuff[TX_RING_SIZE]; unsigned int cur_rx, cur_tx; /* The next free ring entry */ unsigned int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */ - struct net_device_stats stats; /* Generic stats */ struct vortex_extra_stats xstats; /* NIC-specific extra stats */ struct sk_buff *tx_skb; /* Packet being eaten by bus master ctrl. */ dma_addr_t tx_skb_dma; /* Allocated DMA address for bus master ctrl DMA. */ @@ -1875,7 +1874,7 @@ static void vortex_tx_timeout(struct net_device *dev) issue_and_wait(dev, TxReset); - vp->stats.tx_errors++; + dev->stats.tx_errors++; if (vp->full_bus_master_tx) { printk(KERN_DEBUG "%s: Resetting the Tx ring pointer.\n", dev->name); if (vp->cur_tx - vp->dirty_tx > 0 && ioread32(ioaddr + DownListPtr) == 0) @@ -1887,7 +1886,7 @@ static void vortex_tx_timeout(struct net_device *dev) iowrite8(PKT_BUF_SZ>>8, ioaddr + TxFreeThreshold); iowrite16(DownUnstall, ioaddr + EL3_CMD); } else { - vp->stats.tx_dropped++; + dev->stats.tx_dropped++; netif_wake_queue(dev); } @@ -1928,8 +1927,8 @@ vortex_error(struct net_device *dev, int status) } dump_tx_ring(dev); } - if (tx_status & 0x14) vp->stats.tx_fifo_errors++; - if (tx_status & 0x38) vp->stats.tx_aborted_errors++; + if (tx_status & 0x14) dev->stats.tx_fifo_errors++; + if (tx_status & 0x38) dev->stats.tx_aborted_errors++; if (tx_status & 0x08) vp->xstats.tx_max_collisions++; iowrite8(0, ioaddr + TxStatus); if (tx_status & 0x30) { /* txJabber or txUnderrun */ @@ -2051,8 +2050,8 @@ vortex_start_xmit(struct sk_buff *skb, struct net_device *dev) if (vortex_debug > 2) printk(KERN_DEBUG "%s: Tx error, status %2.2x.\n", dev->name, tx_status); - if (tx_status & 0x04) vp->stats.tx_fifo_errors++; - if (tx_status & 0x38) vp->stats.tx_aborted_errors++; + if (tx_status & 0x04) dev->stats.tx_fifo_errors++; + if (tx_status & 0x38) dev->stats.tx_aborted_errors++; if (tx_status & 0x30) { issue_and_wait(dev, TxReset); } @@ -2350,7 +2349,7 @@ boomerang_interrupt(int irq, void *dev_id) } else { printk(KERN_DEBUG "boomerang_interrupt: no skb!\n"); } - /* vp->stats.tx_packets++; Counted below. */ + /* dev->stats.tx_packets++; Counted below. */ dirty_tx++; } vp->dirty_tx = dirty_tx; @@ -2409,12 +2408,12 @@ static int vortex_rx(struct net_device *dev) unsigned char rx_error = ioread8(ioaddr + RxErrors); if (vortex_debug > 2) printk(KERN_DEBUG " Rx error: status %2.2x.\n", rx_error); - vp->stats.rx_errors++; - if (rx_error & 0x01) vp->stats.rx_over_errors++; - if (rx_error & 0x02) vp->stats.rx_length_errors++; - if (rx_error & 0x04) vp->stats.rx_frame_errors++; - if (rx_error & 0x08) vp->stats.rx_crc_errors++; - if (rx_error & 0x10) vp->stats.rx_length_errors++; + dev->stats.rx_errors++; + if (rx_error & 0x01) dev->stats.rx_over_errors++; + if (rx_error & 0x02) dev->stats.rx_length_errors++; + if (rx_error & 0x04) dev->stats.rx_frame_errors++; + if (rx_error & 0x08) dev->stats.rx_crc_errors++; + if (rx_error & 0x10) dev->stats.rx_length_errors++; } else { /* The packet length: up to 4.5K!. */ int pkt_len = rx_status & 0x1fff; @@ -2446,7 +2445,7 @@ static int vortex_rx(struct net_device *dev) skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); dev->last_rx = jiffies; - vp->stats.rx_packets++; + dev->stats.rx_packets++; /* Wait a limited time to go to next packet. */ for (i = 200; i >= 0; i--) if ( ! (ioread16(ioaddr + EL3_STATUS) & CmdInProgress)) @@ -2455,7 +2454,7 @@ static int vortex_rx(struct net_device *dev) } else if (vortex_debug > 0) printk(KERN_NOTICE "%s: No memory to allocate a sk_buff of " "size %d.\n", dev->name, pkt_len); - vp->stats.rx_dropped++; + dev->stats.rx_dropped++; } issue_and_wait(dev, RxDiscard); } @@ -2482,12 +2481,12 @@ boomerang_rx(struct net_device *dev) unsigned char rx_error = rx_status >> 16; if (vortex_debug > 2) printk(KERN_DEBUG " Rx error: status %2.2x.\n", rx_error); - vp->stats.rx_errors++; - if (rx_error & 0x01) vp->stats.rx_over_errors++; - if (rx_error & 0x02) vp->stats.rx_length_errors++; - if (rx_error & 0x04) vp->stats.rx_frame_errors++; - if (rx_error & 0x08) vp->stats.rx_crc_errors++; - if (rx_error & 0x10) vp->stats.rx_length_errors++; + dev->stats.rx_errors++; + if (rx_error & 0x01) dev->stats.rx_over_errors++; + if (rx_error & 0x02) dev->stats.rx_length_errors++; + if (rx_error & 0x04) dev->stats.rx_frame_errors++; + if (rx_error & 0x08) dev->stats.rx_crc_errors++; + if (rx_error & 0x10) dev->stats.rx_length_errors++; } else { /* The packet length: up to 4.5K!. */ int pkt_len = rx_status & 0x1fff; @@ -2529,7 +2528,7 @@ boomerang_rx(struct net_device *dev) } netif_rx(skb); dev->last_rx = jiffies; - vp->stats.rx_packets++; + dev->stats.rx_packets++; } entry = (++vp->cur_rx) % RX_RING_SIZE; } @@ -2591,7 +2590,7 @@ vortex_down(struct net_device *dev, int final_down) del_timer_sync(&vp->rx_oom_timer); del_timer_sync(&vp->timer); - /* Turn off statistics ASAP. We update vp->stats below. */ + /* Turn off statistics ASAP. We update dev->stats below. */ iowrite16(StatsDisable, ioaddr + EL3_CMD); /* Disable the receiver and transmitter. */ @@ -2728,7 +2727,7 @@ static struct net_device_stats *vortex_get_stats(struct net_device *dev) update_stats(ioaddr, dev); spin_unlock_irqrestore (&vp->lock, flags); } - return &vp->stats; + return &dev->stats; } /* Update statistics. @@ -2748,18 +2747,18 @@ static void update_stats(void __iomem *ioaddr, struct net_device *dev) /* Unlike the 3c5x9 we need not turn off stats updates while reading. */ /* Switch to the stats window, and read everything. */ EL3WINDOW(6); - vp->stats.tx_carrier_errors += ioread8(ioaddr + 0); - vp->stats.tx_heartbeat_errors += ioread8(ioaddr + 1); - vp->stats.tx_window_errors += ioread8(ioaddr + 4); - vp->stats.rx_fifo_errors += ioread8(ioaddr + 5); - vp->stats.tx_packets += ioread8(ioaddr + 6); - vp->stats.tx_packets += (ioread8(ioaddr + 9)&0x30) << 4; + dev->stats.tx_carrier_errors += ioread8(ioaddr + 0); + dev->stats.tx_heartbeat_errors += ioread8(ioaddr + 1); + dev->stats.tx_window_errors += ioread8(ioaddr + 4); + dev->stats.rx_fifo_errors += ioread8(ioaddr + 5); + dev->stats.tx_packets += ioread8(ioaddr + 6); + dev->stats.tx_packets += (ioread8(ioaddr + 9)&0x30) << 4; /* Rx packets */ ioread8(ioaddr + 7); /* Must read to clear */ /* Don't bother with register 9, an extension of registers 6&7. If we do use the 6&7 values the atomic update assumption above is invalid. */ - vp->stats.rx_bytes += ioread16(ioaddr + 10); - vp->stats.tx_bytes += ioread16(ioaddr + 12); + dev->stats.rx_bytes += ioread16(ioaddr + 10); + dev->stats.tx_bytes += ioread16(ioaddr + 12); /* Extra stats for get_ethtool_stats() */ vp->xstats.tx_multiple_collisions += ioread8(ioaddr + 2); vp->xstats.tx_single_collisions += ioread8(ioaddr + 3); @@ -2767,14 +2766,14 @@ static void update_stats(void __iomem *ioaddr, struct net_device *dev) EL3WINDOW(4); vp->xstats.rx_bad_ssd += ioread8(ioaddr + 12); - vp->stats.collisions = vp->xstats.tx_multiple_collisions + dev->stats.collisions = vp->xstats.tx_multiple_collisions + vp->xstats.tx_single_collisions + vp->xstats.tx_max_collisions; { u8 up = ioread8(ioaddr + 13); - vp->stats.rx_bytes += (up & 0x0f) << 16; - vp->stats.tx_bytes += (up & 0xf0) << 12; + dev->stats.rx_bytes += (up & 0x0f) << 16; + dev->stats.tx_bytes += (up & 0xf0) << 12; } EL3WINDOW(old_window >> 13); diff --git a/drivers/net/82596.c b/drivers/net/82596.c index 2797da7eeee665c4c99a3eb9c6ffbc350460e812..da292e647eb117c496e3c4c6f6108e0e8c316c94 100644 --- a/drivers/net/82596.c +++ b/drivers/net/82596.c @@ -1162,6 +1162,7 @@ struct net_device * __init i82596_probe(int unit) memcpy(eth_addr, (void *) 0xfffc1f2c, 6); /* YUCK! Get addr from NOVRAM */ dev->base_addr = MVME_I596_BASE; dev->irq = (unsigned) MVME16x_IRQ_I596; + goto found; } #endif #ifdef ENABLE_BVME6000_NET @@ -1176,6 +1177,7 @@ struct net_device * __init i82596_probe(int unit) rtc[3] = msr; dev->base_addr = BVME_I596_BASE; dev->irq = (unsigned) BVME_IRQ_I596; + goto found; } #endif #ifdef ENABLE_APRICOT @@ -1212,8 +1214,13 @@ struct net_device * __init i82596_probe(int unit) } dev->irq = 10; + goto found; } #endif + err = -ENODEV; + goto out; + +found: dev->mem_start = (int)__get_free_pages(GFP_ATOMIC, 0); if (!dev->mem_start) { err = -ENOMEM; diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index af46341827f27b2220ad63216e38fd7e1ae07366..9f6cc8a5607371b346622756bc96610b998204ac 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -1273,20 +1273,6 @@ config PCNET32 To compile this driver as a module, choose M here. The module will be called pcnet32. -config PCNET32_NAPI - bool "Use RX polling (NAPI)" - depends on PCNET32 - help - NAPI is a new driver API designed to reduce CPU and interrupt load - when the driver is receiving lots of packets from the card. It is - still somewhat experimental and thus not yet enabled by default. - - If your estimated Rx load is 10kpps or more, or if the card will be - deployed on potentially unfriendly networks (e.g. in a firewall), - then say Y here. - - If in doubt, say N. - config AMD8111_ETH tristate "AMD 8111 (new PCI lance) support" depends on NET_PCI && PCI @@ -2440,7 +2426,7 @@ config CHELSIO_T3 config EHEA tristate "eHEA Ethernet support" - depends on IBMEBUS && INET && SPARSEMEM + depends on IBMEBUS && INET && SPARSEMEM && MEMORY_HOTPLUG select INET_LRO ---help--- This driver supports the IBM pSeries eHEA ethernet adapter. diff --git a/drivers/net/apne.c b/drivers/net/apne.c index 47a8275d396281bd79f6a2631dbfd1da93273529..867f6fff543c848bfd95a741173c746005344017 100644 --- a/drivers/net/apne.c +++ b/drivers/net/apne.c @@ -127,6 +127,9 @@ struct net_device * __init apne_probe(int unit) #endif int err; + if (!MACH_IS_AMIGA) + return ERR_PTR(-ENODEV); + if (apne_owned) return ERR_PTR(-ENODEV); diff --git a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c index 82e9a5bd0dd29f7a4297500910e292668832b817..a0b4c8516073d7384c4baeb2fd1064ec7dc31234 100644 --- a/drivers/net/appletalk/cops.c +++ b/drivers/net/appletalk/cops.c @@ -499,19 +499,13 @@ static void cops_reset(struct net_device *dev, int sleep) { outb(0, ioaddr+DAYNA_RESET); /* Assert the reset port */ inb(ioaddr+DAYNA_RESET); /* Clear the reset */ - if(sleep) - { - long snap=jiffies; - - /* Let card finish initializing, about 1/3 second */ - while (time_before(jiffies, snap + HZ/3)) - schedule(); - } - else - mdelay(333); + if (sleep) + msleep(333); + else + mdelay(333); } + netif_wake_queue(dev); - return; } static void cops_load (struct net_device *dev) diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c index 0afe522b8f7b901e2a078ff33739a0a9866299c3..9c2394d49428615aac14eff78cf42969dcb0672d 100644 --- a/drivers/net/atlx/atl1.c +++ b/drivers/net/atlx/atl1.c @@ -1,7 +1,7 @@ /* * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved. * Copyright(c) 2006 - 2007 Chris Snook - * Copyright(c) 2006 Jay Cliburn + * Copyright(c) 2006 - 2008 Jay Cliburn * * Derived from Intel e1000 driver * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. @@ -36,7 +36,6 @@ * A very incomplete list of things that need to be dealt with: * * TODO: - * Wake on LAN. * Add more ethtool functions. * Fix abstruse irq enable/disable condition described here: * http://marc.theaimsgroup.com/?l=linux-netdev&m=116398508500553&w=2 @@ -638,21 +637,18 @@ static s32 atl1_phy_leave_power_saving(struct atl1_hw *hw) } /* - *TODO: do something or get rid of this + * Force the PHY into power saving mode using vendor magic. */ #ifdef CONFIG_PM -static s32 atl1_phy_enter_power_saving(struct atl1_hw *hw) +static void atl1_phy_enter_power_saving(struct atl1_hw *hw) { -/* s32 ret_val; - * u16 phy_data; - */ + atl1_write_phy_reg(hw, MII_DBG_ADDR, 0); + atl1_write_phy_reg(hw, MII_DBG_DATA, 0x124E); + atl1_write_phy_reg(hw, MII_DBG_ADDR, 2); + atl1_write_phy_reg(hw, MII_DBG_DATA, 0x3000); + atl1_write_phy_reg(hw, MII_DBG_ADDR, 3); + atl1_write_phy_reg(hw, MII_DBG_DATA, 0); -/* - ret_val = atl1_write_phy_reg(hw, ...); - ret_val = atl1_write_phy_reg(hw, ...); - .... -*/ - return 0; } #endif @@ -2784,64 +2780,93 @@ static int atl1_suspend(struct pci_dev *pdev, pm_message_t state) struct atl1_hw *hw = &adapter->hw; u32 ctrl = 0; u32 wufc = adapter->wol; + u32 val; + int retval; + u16 speed; + u16 duplex; netif_device_detach(netdev); if (netif_running(netdev)) atl1_down(adapter); + retval = pci_save_state(pdev); + if (retval) + return retval; + atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl); atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl); - if (ctrl & BMSR_LSTATUS) + val = ctrl & BMSR_LSTATUS; + if (val) wufc &= ~ATLX_WUFC_LNKC; - /* reduce speed to 10/100M */ - if (wufc) { - atl1_phy_enter_power_saving(hw); - /* if resume, let driver to re- setup link */ - hw->phy_configured = false; - atl1_set_mac_addr(hw); - atlx_set_multi(netdev); + if (val && wufc) { + val = atl1_get_speed_and_duplex(hw, &speed, &duplex); + if (val) { + if (netif_msg_ifdown(adapter)) + dev_printk(KERN_DEBUG, &pdev->dev, + "error getting speed/duplex\n"); + goto disable_wol; + } ctrl = 0; - /* turn on magic packet wol */ - if (wufc & ATLX_WUFC_MAG) - ctrl = WOL_MAGIC_EN | WOL_MAGIC_PME_EN; - /* turn on Link change WOL */ - if (wufc & ATLX_WUFC_LNKC) - ctrl |= (WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN); + /* enable magic packet WOL */ + if (wufc & ATLX_WUFC_MAG) + ctrl |= (WOL_MAGIC_EN | WOL_MAGIC_PME_EN); iowrite32(ctrl, hw->hw_addr + REG_WOL_CTRL); - - /* turn on all-multi mode if wake on multicast is enabled */ - ctrl = ioread32(hw->hw_addr + REG_MAC_CTRL); - ctrl &= ~MAC_CTRL_DBG; - ctrl &= ~MAC_CTRL_PROMIS_EN; - if (wufc & ATLX_WUFC_MC) - ctrl |= MAC_CTRL_MC_ALL_EN; - else - ctrl &= ~MAC_CTRL_MC_ALL_EN; - - /* turn on broadcast mode if wake on-BC is enabled */ - if (wufc & ATLX_WUFC_BC) + ioread32(hw->hw_addr + REG_WOL_CTRL); + + /* configure the mac */ + ctrl = MAC_CTRL_RX_EN; + ctrl |= ((u32)((speed == SPEED_1000) ? MAC_CTRL_SPEED_1000 : + MAC_CTRL_SPEED_10_100) << MAC_CTRL_SPEED_SHIFT); + if (duplex == FULL_DUPLEX) + ctrl |= MAC_CTRL_DUPLX; + ctrl |= (((u32)adapter->hw.preamble_len & + MAC_CTRL_PRMLEN_MASK) << MAC_CTRL_PRMLEN_SHIFT); + if (adapter->vlgrp) + ctrl |= MAC_CTRL_RMV_VLAN; + if (wufc & ATLX_WUFC_MAG) ctrl |= MAC_CTRL_BC_EN; - else - ctrl &= ~MAC_CTRL_BC_EN; - - /* enable RX */ - ctrl |= MAC_CTRL_RX_EN; iowrite32(ctrl, hw->hw_addr + REG_MAC_CTRL); - pci_enable_wake(pdev, PCI_D3hot, 1); - pci_enable_wake(pdev, PCI_D3cold, 1); - } else { - iowrite32(0, hw->hw_addr + REG_WOL_CTRL); - pci_enable_wake(pdev, PCI_D3hot, 0); - pci_enable_wake(pdev, PCI_D3cold, 0); + ioread32(hw->hw_addr + REG_MAC_CTRL); + + /* poke the PHY */ + ctrl = ioread32(hw->hw_addr + REG_PCIE_PHYMISC); + ctrl |= PCIE_PHYMISC_FORCE_RCV_DET; + iowrite32(ctrl, hw->hw_addr + REG_PCIE_PHYMISC); + ioread32(hw->hw_addr + REG_PCIE_PHYMISC); + + pci_enable_wake(pdev, pci_choose_state(pdev, state), 1); + goto exit; } - pci_save_state(pdev); + if (!val && wufc) { + ctrl |= (WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN); + iowrite32(ctrl, hw->hw_addr + REG_WOL_CTRL); + ioread32(hw->hw_addr + REG_WOL_CTRL); + iowrite32(0, hw->hw_addr + REG_MAC_CTRL); + ioread32(hw->hw_addr + REG_MAC_CTRL); + hw->phy_configured = false; + pci_enable_wake(pdev, pci_choose_state(pdev, state), 1); + goto exit; + } + +disable_wol: + iowrite32(0, hw->hw_addr + REG_WOL_CTRL); + ioread32(hw->hw_addr + REG_WOL_CTRL); + ctrl = ioread32(hw->hw_addr + REG_PCIE_PHYMISC); + ctrl |= PCIE_PHYMISC_FORCE_RCV_DET; + iowrite32(ctrl, hw->hw_addr + REG_PCIE_PHYMISC); + ioread32(hw->hw_addr + REG_PCIE_PHYMISC); + atl1_phy_enter_power_saving(hw); + hw->phy_configured = false; + pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); +exit: + if (netif_running(netdev)) + pci_disable_msi(adapter->pdev); pci_disable_device(pdev); - - pci_set_power_state(pdev, PCI_D3hot); + pci_set_power_state(pdev, pci_choose_state(pdev, state)); return 0; } @@ -2855,20 +2880,26 @@ static int atl1_resume(struct pci_dev *pdev) pci_set_power_state(pdev, PCI_D0); pci_restore_state(pdev); - /* FIXME: check and handle */ err = pci_enable_device(pdev); + if (err) { + if (netif_msg_ifup(adapter)) + dev_printk(KERN_DEBUG, &pdev->dev, + "error enabling pci device\n"); + return err; + } + + pci_set_master(pdev); + iowrite32(0, adapter->hw.hw_addr + REG_WOL_CTRL); pci_enable_wake(pdev, PCI_D3hot, 0); pci_enable_wake(pdev, PCI_D3cold, 0); - iowrite32(0, adapter->hw.hw_addr + REG_WOL_CTRL); - atl1_reset(adapter); + atl1_reset_hw(&adapter->hw); + adapter->cmb.cmb->int_stats = 0; if (netif_running(netdev)) atl1_up(adapter); netif_device_attach(netdev); - atl1_via_workaround(adapter); - return 0; } #else @@ -2876,6 +2907,13 @@ static int atl1_resume(struct pci_dev *pdev) #define atl1_resume NULL #endif +static void atl1_shutdown(struct pci_dev *pdev) +{ +#ifdef CONFIG_PM + atl1_suspend(pdev, PMSG_SUSPEND); +#endif +} + #ifdef CONFIG_NET_POLL_CONTROLLER static void atl1_poll_controller(struct net_device *netdev) { @@ -3122,7 +3160,8 @@ static struct pci_driver atl1_driver = { .probe = atl1_probe, .remove = __devexit_p(atl1_remove), .suspend = atl1_suspend, - .resume = atl1_resume + .resume = atl1_resume, + .shutdown = atl1_shutdown }; /* diff --git a/drivers/net/atlx/atl1.h b/drivers/net/atlx/atl1.h index 51893d66eae1a5508bcbc4fce5ff2f775527d327..a5015b14a42969849968e9edb2a246b09cbc00fa 100644 --- a/drivers/net/atlx/atl1.h +++ b/drivers/net/atlx/atl1.h @@ -1,7 +1,7 @@ /* * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved. * Copyright(c) 2006 - 2007 Chris Snook - * Copyright(c) 2006 Jay Cliburn + * Copyright(c) 2006 - 2008 Jay Cliburn * * Derived from Intel e1000 driver * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. diff --git a/drivers/net/atlx/atlx.c b/drivers/net/atlx/atlx.c index f06b854e2501b88ed7f3799bc53438357876add4..b3e7fcf0f6e7be18b6ea4901d1f62050e2e3c19e 100644 --- a/drivers/net/atlx/atlx.c +++ b/drivers/net/atlx/atlx.c @@ -2,7 +2,7 @@ * * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved. * Copyright(c) 2006 - 2007 Chris Snook - * Copyright(c) 2006 Jay Cliburn + * Copyright(c) 2006 - 2008 Jay Cliburn * Copyright(c) 2007 Atheros Corporation. All rights reserved. * * Derived from Intel e1000 driver diff --git a/drivers/net/atlx/atlx.h b/drivers/net/atlx/atlx.h index 3be7c09734d48bda7ab0906e0562e085f108ea94..297a03da6b7f5452a154f922adcd2f20d9cbe93a 100644 --- a/drivers/net/atlx/atlx.h +++ b/drivers/net/atlx/atlx.h @@ -2,7 +2,7 @@ * * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved. * Copyright(c) 2006 - 2007 Chris Snook - * Copyright(c) 2006 Jay Cliburn + * Copyright(c) 2006 - 2008 Jay Cliburn * Copyright(c) 2007 Atheros Corporation. All rights reserved. * * Derived from Intel e1000 driver @@ -29,7 +29,7 @@ #include #include -#define ATLX_DRIVER_VERSION "2.1.1" +#define ATLX_DRIVER_VERSION "2.1.3" MODULE_AUTHOR("Xiong Huang , \ Chris Snook , Jay Cliburn "); MODULE_LICENSE("GPL"); @@ -460,6 +460,9 @@ MODULE_VERSION(ATLX_DRIVER_VERSION); #define MII_ATLX_PSSR_100MBS 0x4000 /* 01=100Mbs */ #define MII_ATLX_PSSR_1000MBS 0x8000 /* 10=1000Mbs */ +#define MII_DBG_ADDR 0x1D +#define MII_DBG_DATA 0x1E + /* PCI Command Register Bit Definitions */ #define PCI_REG_COMMAND 0x04 /* PCI Command Register */ #define CMD_IO_SPACE 0x0001 diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 6425603bc37976bebbec44283b37f4d377325c65..50a40e4331542e63f711d4536ad936ce9a0fa009 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1425,13 +1425,13 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) res = netdev_set_master(slave_dev, bond_dev); if (res) { dprintk("Error %d calling netdev_set_master\n", res); - goto err_close; + goto err_restore_mac; } /* open the slave since the application closed it */ res = dev_open(slave_dev); if (res) { dprintk("Openning slave %s failed\n", slave_dev->name); - goto err_restore_mac; + goto err_unset_master; } new_slave->dev = slave_dev; @@ -1444,7 +1444,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) */ res = bond_alb_init_slave(bond, new_slave); if (res) { - goto err_unset_master; + goto err_close; } } @@ -1619,7 +1619,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) res = bond_create_slave_symlinks(bond_dev, slave_dev); if (res) - goto err_unset_master; + goto err_close; printk(KERN_INFO DRV_NAME ": %s: enslaving %s as a%s interface with a%s link.\n", @@ -1631,12 +1631,12 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) return 0; /* Undo stages on error */ -err_unset_master: - netdev_set_master(slave_dev, NULL); - err_close: dev_close(slave_dev); +err_unset_master: + netdev_set_master(slave_dev, NULL); + err_restore_mac: if (!bond->params.fail_over_mac) { memcpy(addr.sa_data, new_slave->perm_hwaddr, ETH_ALEN); @@ -4936,7 +4936,9 @@ int bond_create(char *name, struct bond_params *params, struct bonding **newbond if (res < 0) { rtnl_lock(); down_write(&bonding_rwsem); - goto out_bond; + bond_deinit(bond_dev); + unregister_netdevice(bond_dev); + goto out_rtnl; } return 0; @@ -4990,9 +4992,10 @@ err: destroy_workqueue(bond->wq); } + bond_destroy_sysfs(); + rtnl_lock(); bond_free_all(); - bond_destroy_sysfs(); rtnl_unlock(); out: return res; @@ -5004,9 +5007,10 @@ static void __exit bonding_exit(void) unregister_netdevice_notifier(&bond_netdev_notifier); unregister_inetaddr_notifier(&bond_inetaddr_notifier); + bond_destroy_sysfs(); + rtnl_lock(); bond_free_all(); - bond_destroy_sysfs(); rtnl_unlock(); } diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 979c2d05ff9c91c19ab7dbee9964cfc608afc299..68c41a00d93d3bd41e84f9c455503a1119895cab 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c @@ -146,29 +146,29 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t ": Unable remove bond %s due to open references.\n", ifname); res = -EPERM; - goto out; + goto out_unlock; } printk(KERN_INFO DRV_NAME ": %s is being deleted...\n", bond->dev->name); bond_destroy(bond); - up_write(&bonding_rwsem); - rtnl_unlock(); - goto out; + goto out_unlock; } printk(KERN_ERR DRV_NAME ": unable to delete non-existent bond %s\n", ifname); res = -ENODEV; - up_write(&bonding_rwsem); - rtnl_unlock(); - goto out; + goto out_unlock; } err_no_cmd: printk(KERN_ERR DRV_NAME ": no command found in bonding_masters. Use +ifname or -ifname.\n"); - res = -EPERM; + return -EPERM; + +out_unlock: + up_write(&bonding_rwsem); + rtnl_unlock(); /* Always return either count or an error. If you return 0, you'll * get called forever, which is bad. diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h index 4fdb13f8447b36a979a36a7aaf6f8fff0af8439b..acebe431d06897bd06ac7ca1ffd978cfaf757383 100644 --- a/drivers/net/cxgb3/adapter.h +++ b/drivers/net/cxgb3/adapter.h @@ -71,6 +71,7 @@ enum { /* adapter flags */ USING_MSIX = (1 << 2), QUEUES_BOUND = (1 << 3), TP_PARITY_INIT = (1 << 4), + NAPI_INIT = (1 << 5), }; struct fl_pg_chunk { diff --git a/drivers/net/cxgb3/common.h b/drivers/net/cxgb3/common.h index 91ee7277b813bba19ca9a2513820d29d3181bdd1..579bee42a5cb9ee10fcd945ba5c4f4b1d937d397 100644 --- a/drivers/net/cxgb3/common.h +++ b/drivers/net/cxgb3/common.h @@ -698,6 +698,7 @@ void mac_prep(struct cmac *mac, struct adapter *adapter, int index); void early_hw_init(struct adapter *adapter, const struct adapter_info *ai); int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai, int reset); +int t3_replay_prep_adapter(struct adapter *adapter); void t3_led_ready(struct adapter *adapter); void t3_fatal_err(struct adapter *adapter); void t3_set_vlan_accel(struct adapter *adapter, unsigned int ports, int on); diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index 05e5f59e87fa56f2e71f359f0a312ba446bdae5b..3a31272167913dc4b7a621d7c07e2f08b70a3a6d 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c @@ -421,6 +421,13 @@ static void init_napi(struct adapter *adap) netif_napi_add(qs->netdev, &qs->napi, qs->napi.poll, 64); } + + /* + * netif_napi_add() can be called only once per napi_struct because it + * adds each new napi_struct to a list. Be careful not to call it a + * second time, e.g., during EEH recovery, by making a note of it. + */ + adap->flags |= NAPI_INIT; } /* @@ -896,7 +903,8 @@ static int cxgb_up(struct adapter *adap) goto out; setup_rss(adap); - init_napi(adap); + if (!(adap->flags & NAPI_INIT)) + init_napi(adap); adap->flags |= FULL_INIT_DONE; } @@ -999,7 +1007,7 @@ static int offload_open(struct net_device *dev) return 0; if (!adap_up && (err = cxgb_up(adapter)) < 0) - return err; + goto out; t3_tp_set_offload_mode(adapter, 1); tdev->lldev = adapter->port[0]; @@ -1061,10 +1069,8 @@ static int cxgb_open(struct net_device *dev) int other_ports = adapter->open_device_map & PORT_MASK; int err; - if (!adapter->open_device_map && (err = cxgb_up(adapter)) < 0) { - quiesce_rx(adapter); + if (!adapter->open_device_map && (err = cxgb_up(adapter)) < 0) return err; - } set_bit(pi->port_id, &adapter->open_device_map); if (is_offload(adapter) && !ofld_disable) { @@ -1894,11 +1900,11 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr) u8 *fw_data; struct ch_mem_range t; - if (!capable(CAP_NET_ADMIN)) + if (!capable(CAP_SYS_RAWIO)) return -EPERM; if (copy_from_user(&t, useraddr, sizeof(t))) return -EFAULT; - + /* Check t.len sanity ? */ fw_data = kmalloc(t.len, GFP_KERNEL); if (!fw_data) return -ENOMEM; @@ -2424,14 +2430,11 @@ static pci_ers_result_t t3_io_error_detected(struct pci_dev *pdev, test_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map)) offload_close(&adapter->tdev); - /* Free sge resources */ - t3_free_sge_resources(adapter); - adapter->flags &= ~FULL_INIT_DONE; pci_disable_device(pdev); - /* Request a slot slot reset. */ + /* Request a slot reset. */ return PCI_ERS_RESULT_NEED_RESET; } @@ -2448,13 +2451,20 @@ static pci_ers_result_t t3_io_slot_reset(struct pci_dev *pdev) if (pci_enable_device(pdev)) { dev_err(&pdev->dev, "Cannot re-enable PCI device after reset.\n"); - return PCI_ERS_RESULT_DISCONNECT; + goto err; } pci_set_master(pdev); + pci_restore_state(pdev); - t3_prep_adapter(adapter, adapter->params.info, 1); + /* Free sge resources */ + t3_free_sge_resources(adapter); + + if (t3_replay_prep_adapter(adapter)) + goto err; return PCI_ERS_RESULT_RECOVERED; +err: + return PCI_ERS_RESULT_DISCONNECT; } /** @@ -2483,13 +2493,6 @@ static void t3_io_resume(struct pci_dev *pdev) netif_device_attach(netdev); } } - - if (is_offload(adapter)) { - __set_bit(OFFLOAD_DEVMAP_BIT, &adapter->registered_device_map); - if (offload_open(adapter->port[0])) - printk(KERN_WARNING - "Could not bring back offload capabilities\n"); - } } static struct pci_error_handlers t3_err_handler = { @@ -2608,6 +2611,7 @@ static int __devinit init_one(struct pci_dev *pdev, } pci_set_master(pdev); + pci_save_state(pdev); mmio_start = pci_resource_start(pdev, 0); mmio_len = pci_resource_len(pdev, 0); diff --git a/drivers/net/cxgb3/regs.h b/drivers/net/cxgb3/regs.h index 02dbbb300929e35458fd3a60a42e04e98a3ab6d6..5671788793452c9bacaf5b48c5e21e7fc6454c71 100644 --- a/drivers/net/cxgb3/regs.h +++ b/drivers/net/cxgb3/regs.h @@ -444,6 +444,14 @@ #define A_PCIE_CFG 0x88 +#define S_ENABLELINKDWNDRST 21 +#define V_ENABLELINKDWNDRST(x) ((x) << S_ENABLELINKDWNDRST) +#define F_ENABLELINKDWNDRST V_ENABLELINKDWNDRST(1U) + +#define S_ENABLELINKDOWNRST 20 +#define V_ENABLELINKDOWNRST(x) ((x) << S_ENABLELINKDOWNRST) +#define F_ENABLELINKDOWNRST V_ENABLELINKDOWNRST(1U) + #define S_PCIE_CLIDECEN 16 #define V_PCIE_CLIDECEN(x) ((x) << S_PCIE_CLIDECEN) #define F_PCIE_CLIDECEN V_PCIE_CLIDECEN(1U) diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c index 98a6bbd11d4c92232df793d3475082b0db12f63a..796eb305cdc3ccb7348492818a128c7e69105006 100644 --- a/drivers/net/cxgb3/sge.c +++ b/drivers/net/cxgb3/sge.c @@ -538,6 +538,31 @@ static void *alloc_ring(struct pci_dev *pdev, size_t nelem, size_t elem_size, return p; } +/** + * t3_reset_qset - reset a sge qset + * @q: the queue set + * + * Reset the qset structure. + * the NAPI structure is preserved in the event of + * the qset's reincarnation, for example during EEH recovery. + */ +static void t3_reset_qset(struct sge_qset *q) +{ + if (q->adap && + !(q->adap->flags & NAPI_INIT)) { + memset(q, 0, sizeof(*q)); + return; + } + + q->adap = NULL; + memset(&q->rspq, 0, sizeof(q->rspq)); + memset(q->fl, 0, sizeof(struct sge_fl) * SGE_RXQ_PER_SET); + memset(q->txq, 0, sizeof(struct sge_txq) * SGE_TXQ_PER_SET); + q->txq_stopped = 0; + memset(&q->tx_reclaim_timer, 0, sizeof(q->tx_reclaim_timer)); +} + + /** * free_qset - free the resources of an SGE queue set * @adapter: the adapter owning the queue set @@ -594,7 +619,7 @@ static void t3_free_qset(struct adapter *adapter, struct sge_qset *q) q->rspq.desc, q->rspq.phys_addr); } - memset(q, 0, sizeof(*q)); + t3_reset_qset(q); } /** @@ -1365,7 +1390,7 @@ static void restart_ctrlq(unsigned long data) */ int t3_mgmt_tx(struct adapter *adap, struct sk_buff *skb) { - int ret; + int ret; local_bh_disable(); ret = ctrl_xmit(adap, &adap->sge.qs[0].txq[TXQ_CTRL], skb); local_bh_enable(); diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c index a99496a431c423f260b41fc6ae06fa4cd3ae1dcf..d405a932c73a72864c315f209faa666a441a0d90 100644 --- a/drivers/net/cxgb3/t3_hw.c +++ b/drivers/net/cxgb3/t3_hw.c @@ -3264,6 +3264,7 @@ static void config_pcie(struct adapter *adap) t3_write_reg(adap, A_PCIE_PEX_ERR, 0xffffffff); t3_set_reg_field(adap, A_PCIE_CFG, 0, + F_ENABLELINKDWNDRST | F_ENABLELINKDOWNRST | F_PCIE_DMASTOPEN | F_PCIE_CLIDECEN); } @@ -3655,3 +3656,30 @@ void t3_led_ready(struct adapter *adapter) t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, F_GPIO0_OUT_VAL, F_GPIO0_OUT_VAL); } + +int t3_replay_prep_adapter(struct adapter *adapter) +{ + const struct adapter_info *ai = adapter->params.info; + unsigned int i, j = 0; + int ret; + + early_hw_init(adapter, ai); + ret = init_parity(adapter); + if (ret) + return ret; + + for_each_port(adapter, i) { + struct port_info *p = adap2pinfo(adapter, i); + while (!adapter->params.vpd.port_type[j]) + ++j; + + p->port_type->phy_prep(&p->phy, adapter, ai->phy_base_addr + j, + ai->mdio_ops); + + p->phy.ops->power_down(&p->phy, 1); + ++j; + } + +return 0; +} + diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index e6fe2614ea6dc3a9f2db6928cce6393b75498475..d45bcd2660afea3817fee5e1ff74b5aacd2fbb0c 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c @@ -117,6 +117,9 @@ typedef struct board_info { struct mutex addr_lock; /* phy and eeprom access lock */ + struct delayed_work phy_poll; + struct net_device *ndev; + spinlock_t lock; struct mii_if_info mii; @@ -297,6 +300,10 @@ static void dm9000_set_io(struct board_info *db, int byte_width) } } +static void dm9000_schedule_poll(board_info_t *db) +{ + schedule_delayed_work(&db->phy_poll, HZ * 2); +} /* Our watchdog timed out. Called by the networking layer */ static void dm9000_timeout(struct net_device *dev) @@ -465,6 +472,17 @@ static const struct ethtool_ops dm9000_ethtool_ops = { .set_eeprom = dm9000_set_eeprom, }; +static void +dm9000_poll_work(struct work_struct *w) +{ + struct delayed_work *dw = container_of(w, struct delayed_work, work); + board_info_t *db = container_of(dw, board_info_t, phy_poll); + + mii_check_media(&db->mii, netif_msg_link(db), 0); + + if (netif_running(db->ndev)) + dm9000_schedule_poll(db); +} /* dm9000_release_board * @@ -503,7 +521,7 @@ dm9000_release_board(struct platform_device *pdev, struct board_info *db) /* * Search DM9000 board, allocate space and register it */ -static int +static int __devinit dm9000_probe(struct platform_device *pdev) { struct dm9000_plat_data *pdata = pdev->dev.platform_data; @@ -525,17 +543,21 @@ dm9000_probe(struct platform_device *pdev) SET_NETDEV_DEV(ndev, &pdev->dev); - dev_dbg(&pdev->dev, "dm9000_probe()"); + dev_dbg(&pdev->dev, "dm9000_probe()\n"); /* setup board info structure */ db = (struct board_info *) ndev->priv; memset(db, 0, sizeof (*db)); db->dev = &pdev->dev; + db->ndev = ndev; spin_lock_init(&db->lock); mutex_init(&db->addr_lock); + INIT_DELAYED_WORK(&db->phy_poll, dm9000_poll_work); + + if (pdev->num_resources < 2) { ret = -ENODEV; goto out; @@ -761,6 +783,8 @@ dm9000_open(struct net_device *dev) mii_check_media(&db->mii, netif_msg_link(db), 1); netif_start_queue(dev); + + dm9000_schedule_poll(db); return 0; } @@ -879,6 +903,8 @@ dm9000_stop(struct net_device *ndev) if (netif_msg_ifdown(db)) dev_dbg(db->dev, "shutting down %s\n", ndev->name); + cancel_delayed_work(&db->phy_poll); + netif_stop_queue(ndev); netif_carrier_off(ndev); @@ -1288,6 +1314,8 @@ dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg) spin_unlock_irqrestore(&db->lock,flags); mutex_unlock(&db->addr_lock); + + dm9000_dbg(db, 5, "phy_read[%02x] -> %04x\n", reg, ret); return ret; } @@ -1301,6 +1329,7 @@ dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg, int value) unsigned long flags; unsigned long reg_save; + dm9000_dbg(db, 5, "phy_write[%02x] = %04x\n", reg, value); mutex_lock(&db->addr_lock); spin_lock_irqsave(&db->lock,flags); @@ -1372,7 +1401,7 @@ dm9000_drv_resume(struct platform_device *dev) return 0; } -static int +static int __devexit dm9000_drv_remove(struct platform_device *pdev) { struct net_device *ndev = platform_get_drvdata(pdev); @@ -1393,7 +1422,7 @@ static struct platform_driver dm9000_driver = { .owner = THIS_MODULE, }, .probe = dm9000_probe, - .remove = dm9000_drv_remove, + .remove = __devexit_p(dm9000_drv_remove), .suspend = dm9000_drv_suspend, .resume = dm9000_drv_resume, }; diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h index 2a53875cddbf5601ab6da33b89f36caf3e6f8650..f823b8ba5785060e939300397130e290be8543cd 100644 --- a/drivers/net/e1000e/defines.h +++ b/drivers/net/e1000e/defines.h @@ -648,6 +648,8 @@ #define IFE_E_PHY_ID 0x02A80330 #define IFE_PLUS_E_PHY_ID 0x02A80320 #define IFE_C_E_PHY_ID 0x02A80310 +#define BME1000_E_PHY_ID 0x01410CB0 +#define BME1000_E_PHY_ID_R2 0x01410CB1 /* M88E1000 Specific Registers */ #define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Register */ @@ -701,6 +703,14 @@ #define M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK 0x0E00 #define M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X 0x0800 +/* BME1000 PHY Specific Control Register */ +#define BME1000_PSCR_ENABLE_DOWNSHIFT 0x0800 /* 1 = enable downshift */ + + +#define PHY_PAGE_SHIFT 5 +#define PHY_REG(page, reg) (((page) << PHY_PAGE_SHIFT) | \ + ((reg) & MAX_PHY_REG_ADDRESS)) + /* * Bits... * 15-5: page diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index 38bfd0d261fee3f272f80415da323311eb8ddf43..d3bc6f8101fa7b90be4455d33821a9901a82d50e 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h @@ -127,7 +127,7 @@ struct e1000_buffer { /* arrays of page information for packet split */ struct e1000_ps_page *ps_pages; }; - + struct page *page; }; struct e1000_ring { @@ -304,6 +304,7 @@ struct e1000_info { #define FLAG_HAS_CTRLEXT_ON_LOAD (1 << 5) #define FLAG_HAS_SWSM_ON_LOAD (1 << 6) #define FLAG_HAS_JUMBO_FRAMES (1 << 7) +#define FLAG_IS_ICH (1 << 9) #define FLAG_HAS_SMART_POWER_DOWN (1 << 11) #define FLAG_IS_QUAD_PORT_A (1 << 12) #define FLAG_IS_QUAD_PORT (1 << 13) @@ -386,6 +387,7 @@ extern void e1000e_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw, bool state); extern void e1000e_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw); extern void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw); +extern void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw); extern s32 e1000e_check_for_copper_link(struct e1000_hw *hw); extern s32 e1000e_check_for_fiber_link(struct e1000_hw *hw); @@ -443,6 +445,9 @@ extern s32 e1000e_get_phy_info_m88(struct e1000_hw *hw); extern s32 e1000e_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data); extern s32 e1000e_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data); extern enum e1000_phy_type e1000e_get_phy_type_from_id(u32 phy_id); +extern s32 e1000e_determine_phy_address(struct e1000_hw *hw); +extern s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data); +extern s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data); extern void e1000e_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl); extern s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data); extern s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data); diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index ce045acce63e99b79685e291a8993e3acd940508..a14561f40db0fddd497b4894c6b67db1d8996dc2 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c @@ -494,8 +494,12 @@ static int e1000_get_eeprom(struct net_device *netdev, for (i = 0; i < last_word - first_word + 1; i++) { ret_val = e1000_read_nvm(hw, first_word + i, 1, &eeprom_buff[i]); - if (ret_val) + if (ret_val) { + /* a read error occurred, throw away the + * result */ + memset(eeprom_buff, 0xff, sizeof(eeprom_buff)); break; + } } } @@ -803,8 +807,7 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data) /* restore previous status */ ew32(STATUS, before); - if ((mac->type != e1000_ich8lan) && - (mac->type != e1000_ich9lan)) { + if (!(adapter->flags & FLAG_IS_ICH)) { REG_PATTERN_TEST(E1000_FCAL, 0xFFFFFFFF, 0xFFFFFFFF); REG_PATTERN_TEST(E1000_FCAH, 0x0000FFFF, 0xFFFFFFFF); REG_PATTERN_TEST(E1000_FCT, 0x0000FFFF, 0xFFFFFFFF); @@ -824,15 +827,13 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data) REG_SET_AND_CHECK(E1000_RCTL, 0xFFFFFFFF, 0x00000000); - before = (((mac->type == e1000_ich8lan) || - (mac->type == e1000_ich9lan)) ? 0x06C3B33E : 0x06DFB3FE); + before = ((adapter->flags & FLAG_IS_ICH) ? 0x06C3B33E : 0x06DFB3FE); REG_SET_AND_CHECK(E1000_RCTL, before, 0x003FFFFB); REG_SET_AND_CHECK(E1000_TCTL, 0xFFFFFFFF, 0x00000000); REG_SET_AND_CHECK(E1000_RCTL, before, 0xFFFFFFFF); REG_PATTERN_TEST(E1000_RDBAL, 0xFFFFFFF0, 0xFFFFFFFF); - if ((mac->type != e1000_ich8lan) && - (mac->type != e1000_ich9lan)) + if (!(adapter->flags & FLAG_IS_ICH)) REG_PATTERN_TEST(E1000_TXCW, 0xC000FFFF, 0x0000FFFF); REG_PATTERN_TEST(E1000_TDBAL, 0xFFFFFFF0, 0xFFFFFFFF); REG_PATTERN_TEST(E1000_TIDV, 0x0000FFFF, 0x0000FFFF); @@ -911,9 +912,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data) /* Test each interrupt */ for (i = 0; i < 10; i++) { - - if (((adapter->hw.mac.type == e1000_ich8lan) || - (adapter->hw.mac.type == e1000_ich9lan)) && i == 8) + if ((adapter->flags & FLAG_IS_ICH) && (i == 8)) continue; /* Interrupt to test */ @@ -1184,6 +1183,7 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter) struct e1000_hw *hw = &adapter->hw; u32 ctrl_reg = 0; u32 stat_reg = 0; + u16 phy_reg = 0; hw->mac.autoneg = 0; @@ -1211,6 +1211,28 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter) E1000_CTRL_SPD_100 |/* Force Speed to 100 */ E1000_CTRL_FD); /* Force Duplex to FULL */ break; + case e1000_phy_bm: + /* Set Default MAC Interface speed to 1GB */ + e1e_rphy(hw, PHY_REG(2, 21), &phy_reg); + phy_reg &= ~0x0007; + phy_reg |= 0x006; + e1e_wphy(hw, PHY_REG(2, 21), phy_reg); + /* Assert SW reset for above settings to take effect */ + e1000e_commit_phy(hw); + mdelay(1); + /* Force Full Duplex */ + e1e_rphy(hw, PHY_REG(769, 16), &phy_reg); + e1e_wphy(hw, PHY_REG(769, 16), phy_reg | 0x000C); + /* Set Link Up (in force link) */ + e1e_rphy(hw, PHY_REG(776, 16), &phy_reg); + e1e_wphy(hw, PHY_REG(776, 16), phy_reg | 0x0040); + /* Force Link */ + e1e_rphy(hw, PHY_REG(769, 16), &phy_reg); + e1e_wphy(hw, PHY_REG(769, 16), phy_reg | 0x0040); + /* Set Early Link Enable */ + e1e_rphy(hw, PHY_REG(769, 20), &phy_reg); + e1e_wphy(hw, PHY_REG(769, 20), phy_reg | 0x0400); + /* fall through */ default: /* force 1000, set loopback */ e1e_wphy(hw, PHY_CONTROL, 0x4140); @@ -1224,8 +1246,7 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter) E1000_CTRL_SPD_1000 |/* Force Speed to 1000 */ E1000_CTRL_FD); /* Force Duplex to FULL */ - if ((adapter->hw.mac.type == e1000_ich8lan) || - (adapter->hw.mac.type == e1000_ich9lan)) + if (adapter->flags & FLAG_IS_ICH) ctrl_reg |= E1000_CTRL_SLU; /* Set Link Up */ } diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h index a930e6d9cf02bdd34d8beb88d67f84c47d8fb6d1..74f263acb17245c7e9158997c42d663e78fe998a 100644 --- a/drivers/net/e1000e/hw.h +++ b/drivers/net/e1000e/hw.h @@ -216,6 +216,21 @@ enum e1e_registers { #define IGP01E1000_PHY_LINK_HEALTH 0x13 /* PHY Link Health */ #define IGP02E1000_PHY_POWER_MGMT 0x19 /* Power Management */ #define IGP01E1000_PHY_PAGE_SELECT 0x1F /* Page Select */ +#define BM_PHY_PAGE_SELECT 22 /* Page Select for BM */ +#define IGP_PAGE_SHIFT 5 +#define PHY_REG_MASK 0x1F + +#define BM_WUC_PAGE 800 +#define BM_WUC_ADDRESS_OPCODE 0x11 +#define BM_WUC_DATA_OPCODE 0x12 +#define BM_WUC_ENABLE_PAGE 769 +#define BM_WUC_ENABLE_REG 17 +#define BM_WUC_ENABLE_BIT (1 << 2) +#define BM_WUC_HOST_WU_BIT (1 << 4) + +#define BM_WUC PHY_REG(BM_WUC_PAGE, 1) +#define BM_WUFC PHY_REG(BM_WUC_PAGE, 2) +#define BM_WUS PHY_REG(BM_WUC_PAGE, 3) #define IGP01E1000_PHY_PCS_INIT_REG 0x00B4 #define IGP01E1000_PHY_POLARITY_MASK 0x0078 @@ -331,10 +346,16 @@ enum e1e_registers { #define E1000_DEV_ID_ICH8_IFE_G 0x10C5 #define E1000_DEV_ID_ICH8_IGP_M 0x104D #define E1000_DEV_ID_ICH9_IGP_AMT 0x10BD +#define E1000_DEV_ID_ICH9_IGP_M_AMT 0x10F5 +#define E1000_DEV_ID_ICH9_IGP_M 0x10BF +#define E1000_DEV_ID_ICH9_IGP_M_V 0x10CB #define E1000_DEV_ID_ICH9_IGP_C 0x294C #define E1000_DEV_ID_ICH9_IFE 0x10C0 #define E1000_DEV_ID_ICH9_IFE_GT 0x10C3 #define E1000_DEV_ID_ICH9_IFE_G 0x10C2 +#define E1000_DEV_ID_ICH10_R_BM_LM 0x10CC +#define E1000_DEV_ID_ICH10_R_BM_LF 0x10CD +#define E1000_DEV_ID_ICH10_R_BM_V 0x10CE #define E1000_FUNC_1 1 @@ -378,6 +399,7 @@ enum e1000_phy_type { e1000_phy_gg82563, e1000_phy_igp_3, e1000_phy_ife, + e1000_phy_bm, }; enum e1000_bus_width { diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index 768485dbb2c6e1ee29e74e122dd295b1495989b0..9e38452a738cc4cd6038cf8829c0ff37787df64e 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c @@ -38,6 +38,12 @@ * 82566DM Gigabit Network Connection * 82566MC Gigabit Network Connection * 82566MM Gigabit Network Connection + * 82567LM Gigabit Network Connection + * 82567LF Gigabit Network Connection + * 82567LM-2 Gigabit Network Connection + * 82567LF-2 Gigabit Network Connection + * 82567V-2 Gigabit Network Connection + * 82562GT-3 10/100 Network Connection */ #include @@ -198,6 +204,19 @@ static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw) phy->addr = 1; phy->reset_delay_us = 100; + /* + * We may need to do this twice - once for IGP and if that fails, + * we'll set BM func pointers and try again + */ + ret_val = e1000e_determine_phy_address(hw); + if (ret_val) { + hw->phy.ops.write_phy_reg = e1000e_write_phy_reg_bm; + hw->phy.ops.read_phy_reg = e1000e_read_phy_reg_bm; + ret_val = e1000e_determine_phy_address(hw); + if (ret_val) + return ret_val; + } + phy->id = 0; while ((e1000_phy_unknown == e1000e_get_phy_type_from_id(phy->id)) && (i++ < 100)) { @@ -219,6 +238,13 @@ static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw) phy->type = e1000_phy_ife; phy->autoneg_mask = E1000_ALL_NOT_GIG; break; + case BME1000_E_PHY_ID: + phy->type = e1000_phy_bm; + phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; + hw->phy.ops.read_phy_reg = e1000e_read_phy_reg_bm; + hw->phy.ops.write_phy_reg = e1000e_write_phy_reg_bm; + hw->phy.ops.commit_phy = e1000e_phy_sw_reset; + break; default: return -E1000_ERR_PHY; break; @@ -664,6 +690,7 @@ static s32 e1000_get_phy_info_ich8lan(struct e1000_hw *hw) return e1000_get_phy_info_ife_ich8lan(hw); break; case e1000_phy_igp_3: + case e1000_phy_bm: return e1000e_get_phy_info_igp(hw); break; default: @@ -728,7 +755,7 @@ static s32 e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw, bool active) s32 ret_val = 0; u16 data; - if (phy->type != e1000_phy_igp_3) + if (phy->type == e1000_phy_ife) return ret_val; phy_ctrl = er32(PHY_CTRL); @@ -1918,8 +1945,35 @@ static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw) ret_val = e1000e_copper_link_setup_igp(hw); if (ret_val) return ret_val; + } else if (hw->phy.type == e1000_phy_bm) { + ret_val = e1000e_copper_link_setup_m88(hw); + if (ret_val) + return ret_val; } + if (hw->phy.type == e1000_phy_ife) { + ret_val = e1e_rphy(hw, IFE_PHY_MDIX_CONTROL, ®_data); + if (ret_val) + return ret_val; + + reg_data &= ~IFE_PMC_AUTO_MDIX; + + switch (hw->phy.mdix) { + case 1: + reg_data &= ~IFE_PMC_FORCE_MDIX; + break; + case 2: + reg_data |= IFE_PMC_FORCE_MDIX; + break; + case 0: + default: + reg_data |= IFE_PMC_AUTO_MDIX; + break; + } + ret_val = e1e_wphy(hw, IFE_PHY_MDIX_CONTROL, reg_data); + if (ret_val) + return ret_val; + } return e1000e_setup_copper_link(hw); } @@ -2126,6 +2180,31 @@ void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw) reg_data); } +/** + * e1000e_disable_gig_wol_ich8lan - disable gig during WoL + * @hw: pointer to the HW structure + * + * During S0 to Sx transition, it is possible the link remains at gig + * instead of negotiating to a lower speed. Before going to Sx, set + * 'LPLU Enabled' and 'Gig Disable' to force link speed negotiation + * to a lower speed. + * + * Should only be called for ICH9 devices. + **/ +void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw) +{ + u32 phy_ctrl; + + if (hw->mac.type == e1000_ich9lan) { + phy_ctrl = er32(PHY_CTRL); + phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU | + E1000_PHY_CTRL_GBE_DISABLE; + ew32(PHY_CTRL, phy_ctrl); + } + + return; +} + /** * e1000_cleanup_led_ich8lan - Restore the default LED operation * @hw: pointer to the HW structure @@ -2247,6 +2326,7 @@ static struct e1000_nvm_operations ich8_nvm_ops = { struct e1000_info e1000_ich8_info = { .mac = e1000_ich8lan, .flags = FLAG_HAS_WOL + | FLAG_IS_ICH | FLAG_RX_CSUM_ENABLED | FLAG_HAS_CTRLEXT_ON_LOAD | FLAG_HAS_AMT @@ -2262,6 +2342,7 @@ struct e1000_info e1000_ich8_info = { struct e1000_info e1000_ich9_info = { .mac = e1000_ich9lan, .flags = FLAG_HAS_JUMBO_FRAMES + | FLAG_IS_ICH | FLAG_HAS_WOL | FLAG_RX_CSUM_ENABLED | FLAG_HAS_CTRLEXT_ON_LOAD diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 8991ab8911e2f506e1d2be85fbad7a7f4a8ad4fb..8cbb40f3a5061cc9287e003543a0fb3c54650e0f 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -43,10 +43,11 @@ #include #include #include +#include #include "e1000.h" -#define DRV_VERSION "0.2.1" +#define DRV_VERSION "0.3.3.3-k2" char e1000e_driver_name[] = "e1000e"; const char e1000e_driver_version[] = DRV_VERSION; @@ -340,6 +341,89 @@ no_buffers: } } +/** + * e1000_alloc_jumbo_rx_buffers - Replace used jumbo receive buffers + * @adapter: address of board private structure + * @rx_ring: pointer to receive ring structure + * @cleaned_count: number of buffers to allocate this pass + **/ + +static void e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter, + int cleaned_count) +{ + struct net_device *netdev = adapter->netdev; + struct pci_dev *pdev = adapter->pdev; + struct e1000_rx_desc *rx_desc; + struct e1000_ring *rx_ring = adapter->rx_ring; + struct e1000_buffer *buffer_info; + struct sk_buff *skb; + unsigned int i; + unsigned int bufsz = 256 - + 16 /* for skb_reserve */ - + NET_IP_ALIGN; + + i = rx_ring->next_to_use; + buffer_info = &rx_ring->buffer_info[i]; + + while (cleaned_count--) { + skb = buffer_info->skb; + if (skb) { + skb_trim(skb, 0); + goto check_page; + } + + skb = netdev_alloc_skb(netdev, bufsz); + if (unlikely(!skb)) { + /* Better luck next round */ + adapter->alloc_rx_buff_failed++; + break; + } + + /* Make buffer alignment 2 beyond a 16 byte boundary + * this will result in a 16 byte aligned IP header after + * the 14 byte MAC header is removed + */ + skb_reserve(skb, NET_IP_ALIGN); + + buffer_info->skb = skb; +check_page: + /* allocate a new page if necessary */ + if (!buffer_info->page) { + buffer_info->page = alloc_page(GFP_ATOMIC); + if (unlikely(!buffer_info->page)) { + adapter->alloc_rx_buff_failed++; + break; + } + } + + if (!buffer_info->dma) + buffer_info->dma = pci_map_page(pdev, + buffer_info->page, 0, + PAGE_SIZE, + PCI_DMA_FROMDEVICE); + + rx_desc = E1000_RX_DESC(*rx_ring, i); + rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma); + + if (unlikely(++i == rx_ring->count)) + i = 0; + buffer_info = &rx_ring->buffer_info[i]; + } + + if (likely(rx_ring->next_to_use != i)) { + rx_ring->next_to_use = i; + if (unlikely(i-- == 0)) + i = (rx_ring->count - 1); + + /* Force memory writes to complete before letting h/w + * know there are new descriptors to fetch. (Only + * applicable for weak-ordered memory model archs, + * such as IA-64). */ + wmb(); + writel(i, adapter->hw.hw_addr + rx_ring->tail); + } +} + /** * e1000_clean_rx_irq - Send received data up the network stack; legacy * @adapter: board private structure @@ -782,6 +866,186 @@ next_desc: return cleaned; } +/** + * e1000_consume_page - helper function + **/ +static void e1000_consume_page(struct e1000_buffer *bi, struct sk_buff *skb, + u16 length) +{ + bi->page = NULL; + skb->len += length; + skb->data_len += length; + skb->truesize += length; +} + +/** + * e1000_clean_jumbo_rx_irq - Send received data up the network stack; legacy + * @adapter: board private structure + * + * the return value indicates whether actual cleaning was done, there + * is no guarantee that everything was cleaned + **/ + +static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter, + int *work_done, int work_to_do) +{ + struct net_device *netdev = adapter->netdev; + struct pci_dev *pdev = adapter->pdev; + struct e1000_ring *rx_ring = adapter->rx_ring; + struct e1000_rx_desc *rx_desc, *next_rxd; + struct e1000_buffer *buffer_info, *next_buffer; + u32 length; + unsigned int i; + int cleaned_count = 0; + bool cleaned = false; + unsigned int total_rx_bytes=0, total_rx_packets=0; + + i = rx_ring->next_to_clean; + rx_desc = E1000_RX_DESC(*rx_ring, i); + buffer_info = &rx_ring->buffer_info[i]; + + while (rx_desc->status & E1000_RXD_STAT_DD) { + struct sk_buff *skb; + u8 status; + + if (*work_done >= work_to_do) + break; + (*work_done)++; + + status = rx_desc->status; + skb = buffer_info->skb; + buffer_info->skb = NULL; + + ++i; + if (i == rx_ring->count) + i = 0; + next_rxd = E1000_RX_DESC(*rx_ring, i); + prefetch(next_rxd); + + next_buffer = &rx_ring->buffer_info[i]; + + cleaned = true; + cleaned_count++; + pci_unmap_page(pdev, buffer_info->dma, PAGE_SIZE, + PCI_DMA_FROMDEVICE); + buffer_info->dma = 0; + + length = le16_to_cpu(rx_desc->length); + + /* errors is only valid for DD + EOP descriptors */ + if (unlikely((status & E1000_RXD_STAT_EOP) && + (rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK))) { + /* recycle both page and skb */ + buffer_info->skb = skb; + /* an error means any chain goes out the window + * too */ + if (rx_ring->rx_skb_top) + dev_kfree_skb(rx_ring->rx_skb_top); + rx_ring->rx_skb_top = NULL; + goto next_desc; + } + +#define rxtop rx_ring->rx_skb_top + if (!(status & E1000_RXD_STAT_EOP)) { + /* this descriptor is only the beginning (or middle) */ + if (!rxtop) { + /* this is the beginning of a chain */ + rxtop = skb; + skb_fill_page_desc(rxtop, 0, buffer_info->page, + 0, length); + } else { + /* this is the middle of a chain */ + skb_fill_page_desc(rxtop, + skb_shinfo(rxtop)->nr_frags, + buffer_info->page, 0, length); + /* re-use the skb, only consumed the page */ + buffer_info->skb = skb; + } + e1000_consume_page(buffer_info, rxtop, length); + goto next_desc; + } else { + if (rxtop) { + /* end of the chain */ + skb_fill_page_desc(rxtop, + skb_shinfo(rxtop)->nr_frags, + buffer_info->page, 0, length); + /* re-use the current skb, we only consumed the + * page */ + buffer_info->skb = skb; + skb = rxtop; + rxtop = NULL; + e1000_consume_page(buffer_info, skb, length); + } else { + /* no chain, got EOP, this buf is the packet + * copybreak to save the put_page/alloc_page */ + if (length <= copybreak && + skb_tailroom(skb) >= length) { + u8 *vaddr; + vaddr = kmap_atomic(buffer_info->page, + KM_SKB_DATA_SOFTIRQ); + memcpy(skb_tail_pointer(skb), vaddr, + length); + kunmap_atomic(vaddr, + KM_SKB_DATA_SOFTIRQ); + /* re-use the page, so don't erase + * buffer_info->page */ + skb_put(skb, length); + } else { + skb_fill_page_desc(skb, 0, + buffer_info->page, 0, + length); + e1000_consume_page(buffer_info, skb, + length); + } + } + } + + /* Receive Checksum Offload XXX recompute due to CRC strip? */ + e1000_rx_checksum(adapter, + (u32)(status) | + ((u32)(rx_desc->errors) << 24), + le16_to_cpu(rx_desc->csum), skb); + + /* probably a little skewed due to removing CRC */ + total_rx_bytes += skb->len; + total_rx_packets++; + + /* eth type trans needs skb->data to point to something */ + if (!pskb_may_pull(skb, ETH_HLEN)) { + ndev_err(netdev, "pskb_may_pull failed.\n"); + dev_kfree_skb(skb); + goto next_desc; + } + + e1000_receive_skb(adapter, netdev, skb, status, + rx_desc->special); + +next_desc: + rx_desc->status = 0; + + /* return some buffers to hardware, one at a time is too slow */ + if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) { + adapter->alloc_rx_buf(adapter, cleaned_count); + cleaned_count = 0; + } + + /* use prefetched values */ + rx_desc = next_rxd; + buffer_info = next_buffer; + } + rx_ring->next_to_clean = i; + + cleaned_count = e1000_desc_unused(rx_ring); + if (cleaned_count) + adapter->alloc_rx_buf(adapter, cleaned_count); + + adapter->total_rx_bytes += total_rx_bytes; + adapter->total_rx_packets += total_rx_packets; + adapter->net_stats.rx_bytes += total_rx_bytes; + adapter->net_stats.rx_packets += total_rx_packets; + return cleaned; +} + /** * e1000_clean_rx_ring - Free Rx Buffers per Queue * @adapter: board private structure @@ -802,6 +1066,10 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter) pci_unmap_single(pdev, buffer_info->dma, adapter->rx_buffer_len, PCI_DMA_FROMDEVICE); + else if (adapter->clean_rx == e1000_clean_jumbo_rx_irq) + pci_unmap_page(pdev, buffer_info->dma, + PAGE_SIZE, + PCI_DMA_FROMDEVICE); else if (adapter->clean_rx == e1000_clean_rx_irq_ps) pci_unmap_single(pdev, buffer_info->dma, adapter->rx_ps_bsize0, @@ -809,6 +1077,11 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter) buffer_info->dma = 0; } + if (buffer_info->page) { + put_page(buffer_info->page); + buffer_info->page = NULL; + } + if (buffer_info->skb) { dev_kfree_skb(buffer_info->skb); buffer_info->skb = NULL; @@ -1755,10 +2028,12 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter) * a lot of memory, since we allocate 3 pages at all times * per packet. */ - adapter->rx_ps_pages = 0; pages = PAGE_USE_COUNT(adapter->netdev->mtu); - if ((pages <= 3) && (PAGE_SIZE <= 16384) && (rctl & E1000_RCTL_LPE)) + if (!(adapter->flags & FLAG_IS_ICH) && (pages <= 3) && + (PAGE_SIZE <= 16384) && (rctl & E1000_RCTL_LPE)) adapter->rx_ps_pages = pages; + else + adapter->rx_ps_pages = 0; if (adapter->rx_ps_pages) { /* Configure extra packet-split registers */ @@ -1819,9 +2094,12 @@ static void e1000_configure_rx(struct e1000_adapter *adapter) sizeof(union e1000_rx_desc_packet_split); adapter->clean_rx = e1000_clean_rx_irq_ps; adapter->alloc_rx_buf = e1000_alloc_rx_buffers_ps; + } else if (adapter->netdev->mtu > ETH_FRAME_LEN + ETH_FCS_LEN) { + rdlen = rx_ring->count * sizeof(struct e1000_rx_desc); + adapter->clean_rx = e1000_clean_jumbo_rx_irq; + adapter->alloc_rx_buf = e1000_alloc_jumbo_rx_buffers; } else { - rdlen = rx_ring->count * - sizeof(struct e1000_rx_desc); + rdlen = rx_ring->count * sizeof(struct e1000_rx_desc); adapter->clean_rx = e1000_clean_rx_irq; adapter->alloc_rx_buf = e1000_alloc_rx_buffers; } @@ -1885,8 +2163,21 @@ static void e1000_configure_rx(struct e1000_adapter *adapter) * units), e.g. using jumbo frames when setting to E1000_ERT_2048 */ if ((adapter->flags & FLAG_HAS_ERT) && - (adapter->netdev->mtu > ETH_DATA_LEN)) - ew32(ERT, E1000_ERT_2048); + (adapter->netdev->mtu > ETH_DATA_LEN)) { + u32 rxdctl = er32(RXDCTL(0)); + ew32(RXDCTL(0), rxdctl | 0x3); + ew32(ERT, E1000_ERT_2048 | (1 << 13)); + /* + * With jumbo frames and early-receive enabled, excessive + * C4->C2 latencies result in dropped transactions. + */ + pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY, + e1000e_driver_name, 55); + } else { + pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY, + e1000e_driver_name, + PM_QOS_DEFAULT_VALUE); + } /* Enable Receives */ ew32(RCTL, rctl); @@ -2155,6 +2446,14 @@ void e1000e_reset(struct e1000_adapter *adapter) /* Allow time for pending master requests to run */ mac->ops.reset_hw(hw); + + /* + * For parts with AMT enabled, let the firmware know + * that the network interface is in control + */ + if ((adapter->flags & FLAG_HAS_AMT) && e1000e_check_mng_mode(hw)) + e1000_get_hw_control(adapter); + ew32(WUC, 0); if (mac->ops.init_hw(hw)) @@ -3469,6 +3768,8 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu) * means we reserve 2 more, this pushes us to allocate from the next * larger slab size. * i.e. RXBUFFER_2048 --> size-4096 slab + * However with the new *_jumbo_rx* routines, jumbo receives will use + * fragmented skbs */ if (max_frame <= 256) @@ -3626,6 +3927,9 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state) ew32(CTRL_EXT, ctrl_ext); } + if (adapter->flags & FLAG_IS_ICH) + e1000e_disable_gig_wol_ich8lan(&adapter->hw); + /* Allow time for pending master requests to run */ e1000e_disable_pcie_master(&adapter->hw); @@ -4292,6 +4596,13 @@ static struct pci_device_id e1000_pci_tbl[] = { { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_GT), board_ich9lan }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_AMT), board_ich9lan }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_C), board_ich9lan }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M), board_ich9lan }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M_AMT), board_ich9lan }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M_V), board_ich9lan }, + + { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_LM), board_ich9lan }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_LF), board_ich9lan }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_V), board_ich9lan }, { } /* terminate list */ }; @@ -4326,7 +4637,9 @@ static int __init e1000_init_module(void) printk(KERN_INFO "%s: Copyright (c) 1999-2008 Intel Corporation.\n", e1000e_driver_name); ret = pci_register_driver(&e1000_driver); - + pm_qos_add_requirement(PM_QOS_CPU_DMA_LATENCY, e1000e_driver_name, + PM_QOS_DEFAULT_VALUE); + return ret; } module_init(e1000_init_module); @@ -4340,6 +4653,7 @@ module_init(e1000_init_module); static void __exit e1000_exit_module(void) { pci_unregister_driver(&e1000_driver); + pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY, e1000e_driver_name); } module_exit(e1000_exit_module); diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c index e102332a6beed4e49588f2c37063a0429fef85f8..b133dcf0e950e9d8067df175ba75e4b461bef250 100644 --- a/drivers/net/e1000e/phy.c +++ b/drivers/net/e1000e/phy.c @@ -34,6 +34,9 @@ static s32 e1000_get_phy_cfg_done(struct e1000_hw *hw); static s32 e1000_phy_force_speed_duplex(struct e1000_hw *hw); static s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active); static s32 e1000_wait_autoneg(struct e1000_hw *hw); +static u32 e1000_get_phy_addr_for_bm_page(u32 page, u32 reg); +static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset, + u16 *data, bool read); /* Cable length tables */ static const u16 e1000_m88_cable_length_table[] = @@ -465,6 +468,10 @@ s32 e1000e_copper_link_setup_m88(struct e1000_hw *hw) if (phy->disable_polarity_correction == 1) phy_data |= M88E1000_PSCR_POLARITY_REVERSAL; + /* Enable downshift on BM (disabled by default) */ + if (phy->type == e1000_phy_bm) + phy_data |= BME1000_PSCR_ENABLE_DOWNSHIFT; + ret_val = e1e_wphy(hw, M88E1000_PHY_SPEC_CTRL, phy_data); if (ret_val) return ret_val; @@ -1776,6 +1783,10 @@ enum e1000_phy_type e1000e_get_phy_type_from_id(u32 phy_id) case IFE_C_E_PHY_ID: phy_type = e1000_phy_ife; break; + case BME1000_E_PHY_ID: + case BME1000_E_PHY_ID_R2: + phy_type = e1000_phy_bm; + break; default: phy_type = e1000_phy_unknown; break; @@ -1783,6 +1794,273 @@ enum e1000_phy_type e1000e_get_phy_type_from_id(u32 phy_id) return phy_type; } +/** + * e1000e_determine_phy_address - Determines PHY address. + * @hw: pointer to the HW structure + * + * This uses a trial and error method to loop through possible PHY + * addresses. It tests each by reading the PHY ID registers and + * checking for a match. + **/ +s32 e1000e_determine_phy_address(struct e1000_hw *hw) +{ + s32 ret_val = -E1000_ERR_PHY_TYPE; + u32 phy_addr= 0; + u32 i = 0; + enum e1000_phy_type phy_type = e1000_phy_unknown; + + do { + for (phy_addr = 0; phy_addr < 4; phy_addr++) { + hw->phy.addr = phy_addr; + e1000e_get_phy_id(hw); + phy_type = e1000e_get_phy_type_from_id(hw->phy.id); + + /* + * If phy_type is valid, break - we found our + * PHY address + */ + if (phy_type != e1000_phy_unknown) { + ret_val = 0; + break; + } + } + i++; + } while ((ret_val != 0) && (i < 100)); + + return ret_val; +} + +/** + * e1000_get_phy_addr_for_bm_page - Retrieve PHY page address + * @page: page to access + * + * Returns the phy address for the page requested. + **/ +static u32 e1000_get_phy_addr_for_bm_page(u32 page, u32 reg) +{ + u32 phy_addr = 2; + + if ((page >= 768) || (page == 0 && reg == 25) || (reg == 31)) + phy_addr = 1; + + return phy_addr; +} + +/** + * e1000e_write_phy_reg_bm - Write BM PHY register + * @hw: pointer to the HW structure + * @offset: register offset to write to + * @data: data to write at register offset + * + * Acquires semaphore, if necessary, then writes the data to PHY register + * at the offset. Release any acquired semaphores before exiting. + **/ +s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data) +{ + s32 ret_val; + u32 page_select = 0; + u32 page = offset >> IGP_PAGE_SHIFT; + u32 page_shift = 0; + + /* Page 800 works differently than the rest so it has its own func */ + if (page == BM_WUC_PAGE) { + ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data, + false); + goto out; + } + + ret_val = hw->phy.ops.acquire_phy(hw); + if (ret_val) + goto out; + + hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset); + + if (offset > MAX_PHY_MULTI_PAGE_REG) { + /* + * Page select is register 31 for phy address 1 and 22 for + * phy address 2 and 3. Page select is shifted only for + * phy address 1. + */ + if (hw->phy.addr == 1) { + page_shift = IGP_PAGE_SHIFT; + page_select = IGP01E1000_PHY_PAGE_SELECT; + } else { + page_shift = 0; + page_select = BM_PHY_PAGE_SELECT; + } + + /* Page is shifted left, PHY expects (page x 32) */ + ret_val = e1000e_write_phy_reg_mdic(hw, page_select, + (page << page_shift)); + if (ret_val) { + hw->phy.ops.release_phy(hw); + goto out; + } + } + + ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, + data); + + hw->phy.ops.release_phy(hw); + +out: + return ret_val; +} + +/** + * e1000e_read_phy_reg_bm - Read BM PHY register + * @hw: pointer to the HW structure + * @offset: register offset to be read + * @data: pointer to the read data + * + * Acquires semaphore, if necessary, then reads the PHY register at offset + * and storing the retrieved information in data. Release any acquired + * semaphores before exiting. + **/ +s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data) +{ + s32 ret_val; + u32 page_select = 0; + u32 page = offset >> IGP_PAGE_SHIFT; + u32 page_shift = 0; + + /* Page 800 works differently than the rest so it has its own func */ + if (page == BM_WUC_PAGE) { + ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data, + true); + goto out; + } + + ret_val = hw->phy.ops.acquire_phy(hw); + if (ret_val) + goto out; + + hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset); + + if (offset > MAX_PHY_MULTI_PAGE_REG) { + /* + * Page select is register 31 for phy address 1 and 22 for + * phy address 2 and 3. Page select is shifted only for + * phy address 1. + */ + if (hw->phy.addr == 1) { + page_shift = IGP_PAGE_SHIFT; + page_select = IGP01E1000_PHY_PAGE_SELECT; + } else { + page_shift = 0; + page_select = BM_PHY_PAGE_SELECT; + } + + /* Page is shifted left, PHY expects (page x 32) */ + ret_val = e1000e_write_phy_reg_mdic(hw, page_select, + (page << page_shift)); + if (ret_val) { + hw->phy.ops.release_phy(hw); + goto out; + } + } + + ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, + data); + hw->phy.ops.release_phy(hw); + +out: + return ret_val; +} + +/** + * e1000_access_phy_wakeup_reg_bm - Read BM PHY wakeup register + * @hw: pointer to the HW structure + * @offset: register offset to be read or written + * @data: pointer to the data to read or write + * @read: determines if operation is read or write + * + * Acquires semaphore, if necessary, then reads the PHY register at offset + * and storing the retrieved information in data. Release any acquired + * semaphores before exiting. Note that procedure to read the wakeup + * registers are different. It works as such: + * 1) Set page 769, register 17, bit 2 = 1 + * 2) Set page to 800 for host (801 if we were manageability) + * 3) Write the address using the address opcode (0x11) + * 4) Read or write the data using the data opcode (0x12) + * 5) Restore 769_17.2 to its original value + **/ +static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset, + u16 *data, bool read) +{ + s32 ret_val; + u16 reg = ((u16)offset) & PHY_REG_MASK; + u16 phy_reg = 0; + u8 phy_acquired = 1; + + + ret_val = hw->phy.ops.acquire_phy(hw); + if (ret_val) { + phy_acquired = 0; + goto out; + } + + /* All operations in this function are phy address 1 */ + hw->phy.addr = 1; + + /* Set page 769 */ + e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, + (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT)); + + ret_val = e1000e_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, &phy_reg); + if (ret_val) + goto out; + + /* First clear bit 4 to avoid a power state change */ + phy_reg &= ~(BM_WUC_HOST_WU_BIT); + ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg); + if (ret_val) + goto out; + + /* Write bit 2 = 1, and clear bit 4 to 769_17 */ + ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, + phy_reg | BM_WUC_ENABLE_BIT); + if (ret_val) + goto out; + + /* Select page 800 */ + ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, + (BM_WUC_PAGE << IGP_PAGE_SHIFT)); + + /* Write the page 800 offset value using opcode 0x11 */ + ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ADDRESS_OPCODE, reg); + if (ret_val) + goto out; + + if (read) { + /* Read the page 800 value using opcode 0x12 */ + ret_val = e1000e_read_phy_reg_mdic(hw, BM_WUC_DATA_OPCODE, + data); + } else { + /* Read the page 800 value using opcode 0x12 */ + ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_DATA_OPCODE, + *data); + } + + if (ret_val) + goto out; + + /* + * Restore 769_17.2 to its original value + * Set page 769 + */ + e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, + (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT)); + + /* Clear 769_17.2 */ + ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg); + +out: + if (phy_acquired == 1) + hw->phy.ops.release_phy(hw); + return ret_val; +} + /** * e1000e_commit_phy - Soft PHY reset * @hw: pointer to the HW structure diff --git a/drivers/net/eexpress.c b/drivers/net/eexpress.c index 2eb82aba4a8bc7c0a2ee5e26b959a1c33dbce4ba..795c594a4b7c550e1d4200206205961aff4820a5 100644 --- a/drivers/net/eexpress.c +++ b/drivers/net/eexpress.c @@ -202,7 +202,7 @@ static unsigned short start_code[] = { 0x0000,Cmd_MCast, 0x0076, /* link to next command */ #define CONF_NR_MULTICAST 0x44 - 0x0000, /* number of multicast addresses */ + 0x0000, /* number of bytes in multicast address(es) */ #define CONF_MULTICAST 0x46 0x0000, 0x0000, 0x0000, /* some addresses */ 0x0000, 0x0000, 0x0000, @@ -1569,7 +1569,7 @@ static void eexp_hw_init586(struct net_device *dev) static void eexp_setup_filter(struct net_device *dev) { - struct dev_mc_list *dmi = dev->mc_list; + struct dev_mc_list *dmi; unsigned short ioaddr = dev->base_addr; int count = dev->mc_count; int i; @@ -1580,9 +1580,9 @@ static void eexp_setup_filter(struct net_device *dev) } outw(CONF_NR_MULTICAST & ~31, ioaddr+SM_PTR); - outw(count, ioaddr+SHADOW(CONF_NR_MULTICAST)); - for (i = 0; i < count; i++) { - unsigned short *data = (unsigned short *)dmi->dmi_addr; + outw(6*count, ioaddr+SHADOW(CONF_NR_MULTICAST)); + for (i = 0, dmi = dev->mc_list; i < count; i++, dmi = dmi->next) { + unsigned short *data; if (!dmi) { printk(KERN_INFO "%s: too few multicast addresses\n", dev->name); break; @@ -1591,6 +1591,7 @@ static void eexp_setup_filter(struct net_device *dev) printk(KERN_INFO "%s: invalid multicast address length given.\n", dev->name); continue; } + data = (unsigned short *)dmi->dmi_addr; outw((CONF_MULTICAST+(6*i)) & ~31, ioaddr+SM_PTR); outw(data[0], ioaddr+SHADOW(CONF_MULTICAST+(6*i))); outw((CONF_MULTICAST+(6*i)+2) & ~31, ioaddr+SM_PTR); diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h index f5dacceab95b35327fc87bda7583a4358479b405..fe872fbd671e3c740705f910be4e6af3d7549373 100644 --- a/drivers/net/ehea/ehea.h +++ b/drivers/net/ehea/ehea.h @@ -40,7 +40,7 @@ #include #define DRV_NAME "ehea" -#define DRV_VERSION "EHEA_0090" +#define DRV_VERSION "EHEA_0091" /* eHEA capability flags */ #define DLPAR_PORT_ADD_REM 1 @@ -118,6 +118,13 @@ #define EHEA_MR_ACC_CTRL 0x00800000 #define EHEA_BUSMAP_START 0x8000000000000000ULL +#define EHEA_INVAL_ADDR 0xFFFFFFFFFFFFFFFFULL +#define EHEA_DIR_INDEX_SHIFT 13 /* 8k Entries in 64k block */ +#define EHEA_TOP_INDEX_SHIFT (EHEA_DIR_INDEX_SHIFT * 2) +#define EHEA_MAP_ENTRIES (1 << EHEA_DIR_INDEX_SHIFT) +#define EHEA_MAP_SIZE (0x10000) /* currently fixed map size */ +#define EHEA_INDEX_MASK (EHEA_MAP_ENTRIES - 1) + #define EHEA_WATCH_DOG_TIMEOUT 10*HZ @@ -192,10 +199,20 @@ struct h_epas { set to 0 if unused */ }; -struct ehea_busmap { - unsigned int entries; /* total number of entries */ - unsigned int valid_sections; /* number of valid sections */ - u64 *vaddr; +/* + * Memory map data structures + */ +struct ehea_dir_bmap +{ + u64 ent[EHEA_MAP_ENTRIES]; +}; +struct ehea_top_bmap +{ + struct ehea_dir_bmap *dir[EHEA_MAP_ENTRIES]; +}; +struct ehea_bmap +{ + struct ehea_top_bmap *top[EHEA_MAP_ENTRIES]; }; struct ehea_qp; diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index f9bc21c74b59222a7c8775dfaba80a91d9abb626..d1b6d4e7495d1dee77247c74e1aa061b23e89026 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -3503,6 +3504,24 @@ void ehea_crash_handler(void) 0, H_DEREG_BCMC); } +static int ehea_mem_notifier(struct notifier_block *nb, + unsigned long action, void *data) +{ + switch (action) { + case MEM_OFFLINE: + ehea_info("memory has been removed"); + ehea_rereg_mrs(NULL); + break; + default: + break; + } + return NOTIFY_OK; +} + +static struct notifier_block ehea_mem_nb = { + .notifier_call = ehea_mem_notifier, +}; + static int ehea_reboot_notifier(struct notifier_block *nb, unsigned long action, void *unused) { @@ -3581,6 +3600,10 @@ int __init ehea_module_init(void) if (ret) ehea_info("failed registering reboot notifier"); + ret = register_memory_notifier(&ehea_mem_nb); + if (ret) + ehea_info("failed registering memory remove notifier"); + ret = crash_shutdown_register(&ehea_crash_handler); if (ret) ehea_info("failed registering crash handler"); @@ -3604,6 +3627,7 @@ int __init ehea_module_init(void) out3: ibmebus_unregister_driver(&ehea_driver); out2: + unregister_memory_notifier(&ehea_mem_nb); unregister_reboot_notifier(&ehea_reboot_nb); crash_shutdown_unregister(&ehea_crash_handler); out: @@ -3621,6 +3645,7 @@ static void __exit ehea_module_exit(void) ret = crash_shutdown_unregister(&ehea_crash_handler); if (ret) ehea_info("failed unregistering crash handler"); + unregister_memory_notifier(&ehea_mem_nb); kfree(ehea_fw_handles.arr); kfree(ehea_bcmc_regs.arr); ehea_destroy_busmap(); diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c index d522e905f460585364a659d8f8cfb2c11d818d14..140f05baafd822b97946e183e9f221cf602a8d41 100644 --- a/drivers/net/ehea/ehea_qmr.c +++ b/drivers/net/ehea/ehea_qmr.c @@ -31,8 +31,8 @@ #include "ehea_phyp.h" #include "ehea_qmr.h" +struct ehea_bmap *ehea_bmap = NULL; -struct ehea_busmap ehea_bmap = { 0, 0, NULL }; static void *hw_qpageit_get_inc(struct hw_queue *queue) @@ -559,125 +559,253 @@ int ehea_destroy_qp(struct ehea_qp *qp) return 0; } -int ehea_create_busmap(void) +static inline int ehea_calc_index(unsigned long i, unsigned long s) { - u64 vaddr = EHEA_BUSMAP_START; - unsigned long high_section_index = 0; - int i; + return (i >> s) & EHEA_INDEX_MASK; +} - /* - * Sections are not in ascending order -> Loop over all sections and - * find the highest PFN to compute the required map size. - */ - ehea_bmap.valid_sections = 0; +static inline int ehea_init_top_bmap(struct ehea_top_bmap *ehea_top_bmap, + int dir) +{ + if(!ehea_top_bmap->dir[dir]) { + ehea_top_bmap->dir[dir] = + kzalloc(sizeof(struct ehea_dir_bmap), GFP_KERNEL); + if (!ehea_top_bmap->dir[dir]) + return -ENOMEM; + } + return 0; +} - for (i = 0; i < NR_MEM_SECTIONS; i++) - if (valid_section_nr(i)) - high_section_index = i; +static inline int ehea_init_bmap(struct ehea_bmap *ehea_bmap, int top, int dir) +{ + if(!ehea_bmap->top[top]) { + ehea_bmap->top[top] = + kzalloc(sizeof(struct ehea_top_bmap), GFP_KERNEL); + if (!ehea_bmap->top[top]) + return -ENOMEM; + } + return ehea_init_top_bmap(ehea_bmap->top[top], dir); +} - ehea_bmap.entries = high_section_index + 1; - ehea_bmap.vaddr = vmalloc(ehea_bmap.entries * sizeof(*ehea_bmap.vaddr)); +static int ehea_create_busmap_callback(unsigned long pfn, + unsigned long nr_pages, void *arg) +{ + unsigned long i, mr_len, start_section, end_section; + start_section = (pfn * PAGE_SIZE) / EHEA_SECTSIZE; + end_section = start_section + ((nr_pages * PAGE_SIZE) / EHEA_SECTSIZE); + mr_len = *(unsigned long *)arg; - if (!ehea_bmap.vaddr) + ehea_bmap = kzalloc(sizeof(struct ehea_bmap), GFP_KERNEL); + if (!ehea_bmap) return -ENOMEM; - for (i = 0 ; i < ehea_bmap.entries; i++) { - unsigned long pfn = section_nr_to_pfn(i); + for (i = start_section; i < end_section; i++) { + int ret; + int top, dir, idx; + u64 vaddr; + + top = ehea_calc_index(i, EHEA_TOP_INDEX_SHIFT); + dir = ehea_calc_index(i, EHEA_DIR_INDEX_SHIFT); + + ret = ehea_init_bmap(ehea_bmap, top, dir); + if(ret) + return ret; - if (pfn_valid(pfn)) { - ehea_bmap.vaddr[i] = vaddr; - vaddr += EHEA_SECTSIZE; - ehea_bmap.valid_sections++; - } else - ehea_bmap.vaddr[i] = 0; + idx = i & EHEA_INDEX_MASK; + vaddr = EHEA_BUSMAP_START + mr_len + i * EHEA_SECTSIZE; + + ehea_bmap->top[top]->dir[dir]->ent[idx] = vaddr; } + mr_len += nr_pages * PAGE_SIZE; + *(unsigned long *)arg = mr_len; + return 0; } +static unsigned long ehea_mr_len; + +static DEFINE_MUTEX(ehea_busmap_mutex); + +int ehea_create_busmap(void) +{ + int ret; + mutex_lock(&ehea_busmap_mutex); + ehea_mr_len = 0; + ret = walk_memory_resource(0, 1ULL << MAX_PHYSMEM_BITS, &ehea_mr_len, + ehea_create_busmap_callback); + mutex_unlock(&ehea_busmap_mutex); + return ret; +} + void ehea_destroy_busmap(void) { - vfree(ehea_bmap.vaddr); + int top, dir; + mutex_lock(&ehea_busmap_mutex); + if (!ehea_bmap) + goto out_destroy; + + for (top = 0; top < EHEA_MAP_ENTRIES; top++) { + if (!ehea_bmap->top[top]) + continue; + + for (dir = 0; dir < EHEA_MAP_ENTRIES; dir++) { + if (!ehea_bmap->top[top]->dir[dir]) + continue; + + kfree(ehea_bmap->top[top]->dir[dir]); + } + + kfree(ehea_bmap->top[top]); + } + + kfree(ehea_bmap); + ehea_bmap = NULL; +out_destroy: + mutex_unlock(&ehea_busmap_mutex); } u64 ehea_map_vaddr(void *caddr) { - u64 mapped_addr; - unsigned long index = __pa(caddr) >> SECTION_SIZE_BITS; - - if (likely(index < ehea_bmap.entries)) { - mapped_addr = ehea_bmap.vaddr[index]; - if (likely(mapped_addr)) - mapped_addr |= (((unsigned long)caddr) - & (EHEA_SECTSIZE - 1)); - else - mapped_addr = -1; - } else - mapped_addr = -1; - - if (unlikely(mapped_addr == -1)) - if (!test_and_set_bit(__EHEA_STOP_XFER, &ehea_driver_flags)) - schedule_work(&ehea_rereg_mr_task); - - return mapped_addr; + int top, dir, idx; + unsigned long index, offset; + + if (!ehea_bmap) + return EHEA_INVAL_ADDR; + + index = virt_to_abs(caddr) >> SECTION_SIZE_BITS; + top = (index >> EHEA_TOP_INDEX_SHIFT) & EHEA_INDEX_MASK; + if (!ehea_bmap->top[top]) + return EHEA_INVAL_ADDR; + + dir = (index >> EHEA_DIR_INDEX_SHIFT) & EHEA_INDEX_MASK; + if (!ehea_bmap->top[top]->dir[dir]) + return EHEA_INVAL_ADDR; + + idx = index & EHEA_INDEX_MASK; + if (!ehea_bmap->top[top]->dir[dir]->ent[idx]) + return EHEA_INVAL_ADDR; + + offset = (unsigned long)caddr & (EHEA_SECTSIZE - 1); + return ehea_bmap->top[top]->dir[dir]->ent[idx] | offset; +} + +static inline void *ehea_calc_sectbase(int top, int dir, int idx) +{ + unsigned long ret = idx; + ret |= dir << EHEA_DIR_INDEX_SHIFT; + ret |= top << EHEA_TOP_INDEX_SHIFT; + return abs_to_virt(ret << SECTION_SIZE_BITS); +} + +static u64 ehea_reg_mr_section(int top, int dir, int idx, u64 *pt, + struct ehea_adapter *adapter, + struct ehea_mr *mr) +{ + void *pg; + u64 j, m, hret; + unsigned long k = 0; + u64 pt_abs = virt_to_abs(pt); + + void *sectbase = ehea_calc_sectbase(top, dir, idx); + + for (j = 0; j < (EHEA_PAGES_PER_SECTION / EHEA_MAX_RPAGE); j++) { + + for (m = 0; m < EHEA_MAX_RPAGE; m++) { + pg = sectbase + ((k++) * EHEA_PAGESIZE); + pt[m] = virt_to_abs(pg); + } + hret = ehea_h_register_rpage_mr(adapter->handle, mr->handle, 0, + 0, pt_abs, EHEA_MAX_RPAGE); + + if ((hret != H_SUCCESS) + && (hret != H_PAGE_REGISTERED)) { + ehea_h_free_resource(adapter->handle, mr->handle, + FORCE_FREE); + ehea_error("register_rpage_mr failed"); + return hret; + } + } + return hret; +} + +static u64 ehea_reg_mr_sections(int top, int dir, u64 *pt, + struct ehea_adapter *adapter, + struct ehea_mr *mr) +{ + u64 hret = H_SUCCESS; + int idx; + + for (idx = 0; idx < EHEA_MAP_ENTRIES; idx++) { + if (!ehea_bmap->top[top]->dir[dir]->ent[idx]) + continue; + + hret = ehea_reg_mr_section(top, dir, idx, pt, adapter, mr); + if ((hret != H_SUCCESS) && (hret != H_PAGE_REGISTERED)) + return hret; + } + return hret; +} + +static u64 ehea_reg_mr_dir_sections(int top, u64 *pt, + struct ehea_adapter *adapter, + struct ehea_mr *mr) +{ + u64 hret = H_SUCCESS; + int dir; + + for (dir = 0; dir < EHEA_MAP_ENTRIES; dir++) { + if (!ehea_bmap->top[top]->dir[dir]) + continue; + + hret = ehea_reg_mr_sections(top, dir, pt, adapter, mr); + if ((hret != H_SUCCESS) && (hret != H_PAGE_REGISTERED)) + return hret; + } + return hret; } int ehea_reg_kernel_mr(struct ehea_adapter *adapter, struct ehea_mr *mr) { int ret; u64 *pt; - void *pg; - u64 hret, pt_abs, i, j, m, mr_len; + u64 hret; u32 acc_ctrl = EHEA_MR_ACC_CTRL; - mr_len = ehea_bmap.valid_sections * EHEA_SECTSIZE; + unsigned long top; - pt = kzalloc(PAGE_SIZE, GFP_KERNEL); + pt = kzalloc(PAGE_SIZE, GFP_KERNEL); if (!pt) { ehea_error("no mem"); ret = -ENOMEM; goto out; } - pt_abs = virt_to_abs(pt); - hret = ehea_h_alloc_resource_mr(adapter->handle, - EHEA_BUSMAP_START, mr_len, - acc_ctrl, adapter->pd, + hret = ehea_h_alloc_resource_mr(adapter->handle, EHEA_BUSMAP_START, + ehea_mr_len, acc_ctrl, adapter->pd, &mr->handle, &mr->lkey); + if (hret != H_SUCCESS) { ehea_error("alloc_resource_mr failed"); ret = -EIO; goto out; } - for (i = 0 ; i < ehea_bmap.entries; i++) - if (ehea_bmap.vaddr[i]) { - void *sectbase = __va(i << SECTION_SIZE_BITS); - unsigned long k = 0; - - for (j = 0; j < (EHEA_PAGES_PER_SECTION / - EHEA_MAX_RPAGE); j++) { - - for (m = 0; m < EHEA_MAX_RPAGE; m++) { - pg = sectbase + ((k++) * EHEA_PAGESIZE); - pt[m] = virt_to_abs(pg); - } - - hret = ehea_h_register_rpage_mr(adapter->handle, - mr->handle, - 0, 0, pt_abs, - EHEA_MAX_RPAGE); - if ((hret != H_SUCCESS) - && (hret != H_PAGE_REGISTERED)) { - ehea_h_free_resource(adapter->handle, - mr->handle, - FORCE_FREE); - ehea_error("register_rpage_mr failed"); - ret = -EIO; - goto out; - } - } - } + if (!ehea_bmap) { + ehea_h_free_resource(adapter->handle, mr->handle, FORCE_FREE); + ehea_error("no busmap available"); + ret = -EIO; + goto out; + } + + for (top = 0; top < EHEA_MAP_ENTRIES; top++) { + if (!ehea_bmap->top[top]) + continue; + + hret = ehea_reg_mr_dir_sections(top, pt, adapter, mr); + if((hret != H_PAGE_REGISTERED) && (hret != H_SUCCESS)) + break; + } if (hret != H_SUCCESS) { ehea_h_free_resource(adapter->handle, mr->handle, FORCE_FREE); diff --git a/drivers/net/fs_enet/mii-fec.c b/drivers/net/fs_enet/mii-fec.c index ba75efc9f5b50bdaf647a70015a2d08b3987ec9d..f0014cfbb275ab9206cfe2f55765be08f4a88e84 100644 --- a/drivers/net/fs_enet/mii-fec.c +++ b/drivers/net/fs_enet/mii-fec.c @@ -194,7 +194,7 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev, ret = of_address_to_resource(ofdev->node, 0, &res); if (ret) - return ret; + goto out_res; snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", res.start); @@ -236,6 +236,7 @@ out_free_irqs: kfree(new_bus->irq); out_unmap_regs: iounmap(fec->fecp); +out_res: out_fec: kfree(fec); out_mii: diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 587afe7be689d174f6f36f0967fd0cfd40abc611..25bdd0832df5752f4f0de2a23b8df710d0ee83ce 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -138,6 +138,7 @@ static int gfar_poll(struct napi_struct *napi, int budget); static void gfar_netpoll(struct net_device *dev); #endif int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit); +static int gfar_clean_tx_ring(struct net_device *dev); static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int length); static void gfar_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp); @@ -634,6 +635,8 @@ static void free_skb_resources(struct gfar_private *priv) dev_kfree_skb_any(priv->tx_skbuff[i]); priv->tx_skbuff[i] = NULL; } + + txbdp++; } kfree(priv->tx_skbuff); @@ -1141,7 +1144,7 @@ static int gfar_close(struct net_device *dev) } /* Changes the mac address if the controller is not running. */ -int gfar_set_mac_address(struct net_device *dev) +static int gfar_set_mac_address(struct net_device *dev) { gfar_set_mac_for_addr(dev, 0, dev->dev_addr); @@ -1260,7 +1263,7 @@ static void gfar_timeout(struct net_device *dev) } /* Interrupt Handler for Transmit complete */ -int gfar_clean_tx_ring(struct net_device *dev) +static int gfar_clean_tx_ring(struct net_device *dev) { struct txbd8 *bdp; struct gfar_private *priv = netdev_priv(dev); diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h index fd487be3993eabc2409816a747de46132fc223bb..27f37c81e52c537552b7925067fcd42a39445b7b 100644 --- a/drivers/net/gianfar.h +++ b/drivers/net/gianfar.h @@ -782,5 +782,8 @@ extern void gfar_halt(struct net_device *dev); extern void gfar_phy_test(struct mii_bus *bus, struct phy_device *phydev, int enable, u32 regnum, u32 read); void gfar_init_sysfs(struct net_device *dev); +int gfar_local_mdio_write(struct gfar_mii __iomem *regs, int mii_id, + int regnum, u16 value); +int gfar_local_mdio_read(struct gfar_mii __iomem *regs, int mii_id, int regnum); #endif /* __GIANFAR_H */ diff --git a/drivers/net/gianfar_sysfs.c b/drivers/net/gianfar_sysfs.c index 230878b9419053ee65621528d7710e3f74677f94..5116f68e01b9a4618423f47d555d68771da01d3e 100644 --- a/drivers/net/gianfar_sysfs.c +++ b/drivers/net/gianfar_sysfs.c @@ -103,10 +103,10 @@ static ssize_t gfar_set_rx_stash_size(struct device *dev, spin_lock_irqsave(&priv->rxlock, flags); if (length > priv->rx_buffer_size) - return count; + goto out; if (length == priv->rx_stash_size) - return count; + goto out; priv->rx_stash_size = length; @@ -125,6 +125,7 @@ static ssize_t gfar_set_rx_stash_size(struct device *dev, gfar_write(&priv->regs->attr, temp); +out: spin_unlock_irqrestore(&priv->rxlock, flags); return count; @@ -154,10 +155,10 @@ static ssize_t gfar_set_rx_stash_index(struct device *dev, spin_lock_irqsave(&priv->rxlock, flags); if (index > priv->rx_stash_size) - return count; + goto out; if (index == priv->rx_stash_index) - return count; + goto out; priv->rx_stash_index = index; @@ -166,6 +167,7 @@ static ssize_t gfar_set_rx_stash_index(struct device *dev, temp |= ATTRELI_EI(index); gfar_write(&priv->regs->attreli, flags); +out: spin_unlock_irqrestore(&priv->rxlock, flags); return count; diff --git a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c index a873d2b315ca33e21cfc1c3ced4e3c48f6cce273..a7714da7c283c84d48082b34540fbb05f86f85d2 100644 --- a/drivers/net/irda/nsc-ircc.c +++ b/drivers/net/irda/nsc-ircc.c @@ -100,7 +100,9 @@ static int nsc_ircc_probe_39x(nsc_chip_t *chip, chipio_t *info); static int nsc_ircc_init_108(nsc_chip_t *chip, chipio_t *info); static int nsc_ircc_init_338(nsc_chip_t *chip, chipio_t *info); static int nsc_ircc_init_39x(nsc_chip_t *chip, chipio_t *info); +#ifdef CONFIG_PNP static int nsc_ircc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *id); +#endif /* These are the known NSC chips */ static nsc_chip_t chips[] = { @@ -156,9 +158,11 @@ static const struct pnp_device_id nsc_ircc_pnp_table[] = { MODULE_DEVICE_TABLE(pnp, nsc_ircc_pnp_table); static struct pnp_driver nsc_ircc_pnp_driver = { +#ifdef CONFIG_PNP .name = "nsc-ircc", .id_table = nsc_ircc_pnp_table, .probe = nsc_ircc_pnp_probe, +#endif }; /* Some prototypes */ @@ -916,6 +920,7 @@ static int nsc_ircc_probe_39x(nsc_chip_t *chip, chipio_t *info) return 0; } +#ifdef CONFIG_PNP /* PNP probing */ static int nsc_ircc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *id) { @@ -952,6 +957,7 @@ static int nsc_ircc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *i return 0; } +#endif /* * Function nsc_ircc_setup (info) diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c index 1f26da761e9f0067ca49450f31d48cad23cf6317..cfe0194fef71c1ab0ea9226a4f1337e567b5d7ca 100644 --- a/drivers/net/irda/smsc-ircc2.c +++ b/drivers/net/irda/smsc-ircc2.c @@ -376,6 +376,7 @@ MODULE_DEVICE_TABLE(pnp, smsc_ircc_pnp_table); static int pnp_driver_registered; +#ifdef CONFIG_PNP static int __init smsc_ircc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) { @@ -402,7 +403,9 @@ static struct pnp_driver smsc_ircc_pnp_driver = { .id_table = smsc_ircc_pnp_table, .probe = smsc_ircc_pnp_probe, }; - +#else /* CONFIG_PNP */ +static struct pnp_driver smsc_ircc_pnp_driver; +#endif /******************************************************************************* * diff --git a/drivers/net/mac89x0.c b/drivers/net/mac89x0.c index 2a66e5b7cebcbc0217b9bef6aad9b434f9d62242..4ce8afd481c3f13bd75caa570c5597c28b2a68cb 100644 --- a/drivers/net/mac89x0.c +++ b/drivers/net/mac89x0.c @@ -183,6 +183,9 @@ struct net_device * __init mac89x0_probe(int unit) int err = -ENODEV; DECLARE_MAC_BUF(mac); + if (!MACH_IS_MAC) + return ERR_PTR(-ENODEV); + dev = alloc_etherdev(sizeof(struct net_local)); if (!dev) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/macmace.c b/drivers/net/macmace.c index 18770527df995920047ceaad093b023cfd9c1d4d..51ad3765e0750c2857555c437ed259631a5394b7 100644 --- a/drivers/net/macmace.c +++ b/drivers/net/macmace.c @@ -781,6 +781,9 @@ static int __init mac_mace_init_module(void) { int err; + if (!MACH_IS_MAC) + return -ENODEV; + if ((err = platform_driver_register(&mac_mace_driver))) { printk(KERN_ERR "Driver registration failed\n"); return err; diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 2056cfc624dc6da62d2777c016920e86d01b5876..c36a03ae9bfbdc5d43c44913d68f82aeae6772f9 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -450,7 +450,7 @@ static void macvlan_dellink(struct net_device *dev) unregister_netdevice(dev); if (list_empty(&port->vlans)) - macvlan_port_destroy(dev); + macvlan_port_destroy(port->dev); } static struct rtnl_link_ops macvlan_link_ops __read_mostly = { diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 381b36e5f64c2fe11f559d182b5abab91f0de388..b7915cdcc6a504efc2ee422f3e29a77d37d72532 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -91,6 +91,11 @@ */ #define PHY_ADDR_REG 0x0000 #define SMI_REG 0x0004 +#define WINDOW_BASE(i) (0x0200 + ((i) << 3)) +#define WINDOW_SIZE(i) (0x0204 + ((i) << 3)) +#define WINDOW_REMAP_HIGH(i) (0x0280 + ((i) << 2)) +#define WINDOW_BAR_ENABLE 0x0290 +#define WINDOW_PROTECT(i) (0x0294 + ((i) << 4)) /* * Per-port registers. @@ -507,9 +512,23 @@ struct mv643xx_mib_counters { u32 late_collision; }; +struct mv643xx_shared_private { + void __iomem *eth_base; + + /* used to protect SMI_REG, which is shared across ports */ + spinlock_t phy_lock; + + u32 win_protect; + + unsigned int t_clk; +}; + struct mv643xx_private { + struct mv643xx_shared_private *shared; int port_num; /* User Ethernet port number */ + struct mv643xx_shared_private *shared_smi; + u32 rx_sram_addr; /* Base address of rx sram area */ u32 rx_sram_size; /* Size of rx sram area */ u32 tx_sram_addr; /* Base address of tx sram area */ @@ -614,19 +633,14 @@ static const struct ethtool_ops mv643xx_ethtool_ops; static char mv643xx_driver_name[] = "mv643xx_eth"; static char mv643xx_driver_version[] = "1.0"; -static void __iomem *mv643xx_eth_base; - -/* used to protect SMI_REG, which is shared across ports */ -static DEFINE_SPINLOCK(mv643xx_eth_phy_lock); - static inline u32 rdl(struct mv643xx_private *mp, int offset) { - return readl(mv643xx_eth_base + offset); + return readl(mp->shared->eth_base + offset); } static inline void wrl(struct mv643xx_private *mp, int offset, u32 data) { - writel(data, mv643xx_eth_base + offset); + writel(data, mp->shared->eth_base + offset); } /* @@ -1119,7 +1133,6 @@ static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id) * * INPUT: * struct mv643xx_private *mp Ethernet port - * unsigned int t_clk t_clk of the MV-643xx chip in HZ units * unsigned int delay Delay in usec * * OUTPUT: @@ -1130,10 +1143,10 @@ static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id) * */ static unsigned int eth_port_set_rx_coal(struct mv643xx_private *mp, - unsigned int t_clk, unsigned int delay) + unsigned int delay) { unsigned int port_num = mp->port_num; - unsigned int coal = ((t_clk / 1000000) * delay) / 64; + unsigned int coal = ((mp->shared->t_clk / 1000000) * delay) / 64; /* Set RX Coalescing mechanism */ wrl(mp, SDMA_CONFIG_REG(port_num), @@ -1158,7 +1171,6 @@ static unsigned int eth_port_set_rx_coal(struct mv643xx_private *mp, * * INPUT: * struct mv643xx_private *mp Ethernet port - * unsigned int t_clk t_clk of the MV-643xx chip in HZ units * unsigned int delay Delay in uSeconds * * OUTPUT: @@ -1169,9 +1181,9 @@ static unsigned int eth_port_set_rx_coal(struct mv643xx_private *mp, * */ static unsigned int eth_port_set_tx_coal(struct mv643xx_private *mp, - unsigned int t_clk, unsigned int delay) + unsigned int delay) { - unsigned int coal = ((t_clk / 1000000) * delay) / 64; + unsigned int coal = ((mp->shared->t_clk / 1000000) * delay) / 64; /* Set TX Coalescing mechanism */ wrl(mp, TX_FIFO_URGENT_THRESHOLD_REG(mp->port_num), coal << 4); @@ -1413,11 +1425,11 @@ static int mv643xx_eth_open(struct net_device *dev) #ifdef MV643XX_COAL mp->rx_int_coal = - eth_port_set_rx_coal(mp, 133000000, MV643XX_RX_COAL); + eth_port_set_rx_coal(mp, MV643XX_RX_COAL); #endif mp->tx_int_coal = - eth_port_set_tx_coal(mp, 133000000, MV643XX_TX_COAL); + eth_port_set_tx_coal(mp, MV643XX_TX_COAL); /* Unmask phy and link status changes interrupts */ wrl(mp, INTERRUPT_EXTEND_MASK_REG(port_num), ETH_INT_UNMASK_ALL_EXT); @@ -1827,6 +1839,11 @@ static int mv643xx_eth_probe(struct platform_device *pdev) return -ENODEV; } + if (pd->shared == NULL) { + printk(KERN_ERR "No mv643xx_eth_platform_data->shared\n"); + return -ENODEV; + } + dev = alloc_etherdev(sizeof(struct mv643xx_private)); if (!dev) return -ENOMEM; @@ -1877,8 +1894,16 @@ static int mv643xx_eth_probe(struct platform_device *pdev) spin_lock_init(&mp->lock); + mp->shared = platform_get_drvdata(pd->shared); port_num = mp->port_num = pd->port_number; + if (mp->shared->win_protect) + wrl(mp, WINDOW_PROTECT(port_num), mp->shared->win_protect); + + mp->shared_smi = mp->shared; + if (pd->shared_smi != NULL) + mp->shared_smi = platform_get_drvdata(pd->shared_smi); + /* set default config values */ eth_port_uc_addr_get(mp, dev->dev_addr); mp->rx_ring_size = PORT_DEFAULT_RECEIVE_QUEUE_SIZE; @@ -1983,30 +2008,91 @@ static int mv643xx_eth_remove(struct platform_device *pdev) return 0; } +static void mv643xx_eth_conf_mbus_windows(struct mv643xx_shared_private *msp, + struct mbus_dram_target_info *dram) +{ + void __iomem *base = msp->eth_base; + u32 win_enable; + u32 win_protect; + int i; + + for (i = 0; i < 6; i++) { + writel(0, base + WINDOW_BASE(i)); + writel(0, base + WINDOW_SIZE(i)); + if (i < 4) + writel(0, base + WINDOW_REMAP_HIGH(i)); + } + + win_enable = 0x3f; + win_protect = 0; + + for (i = 0; i < dram->num_cs; i++) { + struct mbus_dram_window *cs = dram->cs + i; + + writel((cs->base & 0xffff0000) | + (cs->mbus_attr << 8) | + dram->mbus_dram_target_id, base + WINDOW_BASE(i)); + writel((cs->size - 1) & 0xffff0000, base + WINDOW_SIZE(i)); + + win_enable &= ~(1 << i); + win_protect |= 3 << (2 * i); + } + + writel(win_enable, base + WINDOW_BAR_ENABLE); + msp->win_protect = win_protect; +} + static int mv643xx_eth_shared_probe(struct platform_device *pdev) { static int mv643xx_version_printed = 0; + struct mv643xx_eth_shared_platform_data *pd = pdev->dev.platform_data; + struct mv643xx_shared_private *msp; struct resource *res; + int ret; if (!mv643xx_version_printed++) printk(KERN_NOTICE "MV-643xx 10/100/1000 Ethernet Driver\n"); + ret = -EINVAL; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) - return -ENODEV; + goto out; - mv643xx_eth_base = ioremap(res->start, res->end - res->start + 1); - if (mv643xx_eth_base == NULL) - return -ENOMEM; + ret = -ENOMEM; + msp = kmalloc(sizeof(*msp), GFP_KERNEL); + if (msp == NULL) + goto out; + memset(msp, 0, sizeof(*msp)); + + msp->eth_base = ioremap(res->start, res->end - res->start + 1); + if (msp->eth_base == NULL) + goto out_free; + + spin_lock_init(&msp->phy_lock); + msp->t_clk = (pd != NULL && pd->t_clk != 0) ? pd->t_clk : 133000000; + + platform_set_drvdata(pdev, msp); + + /* + * (Re-)program MBUS remapping windows if we are asked to. + */ + if (pd != NULL && pd->dram != NULL) + mv643xx_eth_conf_mbus_windows(msp, pd->dram); return 0; +out_free: + kfree(msp); +out: + return ret; } static int mv643xx_eth_shared_remove(struct platform_device *pdev) { - iounmap(mv643xx_eth_base); - mv643xx_eth_base = NULL; + struct mv643xx_shared_private *msp = platform_get_drvdata(pdev); + + iounmap(msp->eth_base); + kfree(msp); return 0; } @@ -2906,15 +2992,16 @@ static void eth_port_reset(struct mv643xx_private *mp) static void eth_port_read_smi_reg(struct mv643xx_private *mp, unsigned int phy_reg, unsigned int *value) { + void __iomem *smi_reg = mp->shared_smi->eth_base + SMI_REG; int phy_addr = ethernet_phy_get(mp); unsigned long flags; int i; /* the SMI register is a shared resource */ - spin_lock_irqsave(&mv643xx_eth_phy_lock, flags); + spin_lock_irqsave(&mp->shared_smi->phy_lock, flags); /* wait for the SMI register to become available */ - for (i = 0; rdl(mp, SMI_REG) & ETH_SMI_BUSY; i++) { + for (i = 0; readl(smi_reg) & ETH_SMI_BUSY; i++) { if (i == PHY_WAIT_ITERATIONS) { printk("%s: PHY busy timeout\n", mp->dev->name); goto out; @@ -2922,11 +3009,11 @@ static void eth_port_read_smi_reg(struct mv643xx_private *mp, udelay(PHY_WAIT_MICRO_SECONDS); } - wrl(mp, SMI_REG, - (phy_addr << 16) | (phy_reg << 21) | ETH_SMI_OPCODE_READ); + writel((phy_addr << 16) | (phy_reg << 21) | ETH_SMI_OPCODE_READ, + smi_reg); /* now wait for the data to be valid */ - for (i = 0; !(rdl(mp, SMI_REG) & ETH_SMI_READ_VALID); i++) { + for (i = 0; !(readl(smi_reg) & ETH_SMI_READ_VALID); i++) { if (i == PHY_WAIT_ITERATIONS) { printk("%s: PHY read timeout\n", mp->dev->name); goto out; @@ -2934,9 +3021,9 @@ static void eth_port_read_smi_reg(struct mv643xx_private *mp, udelay(PHY_WAIT_MICRO_SECONDS); } - *value = rdl(mp, SMI_REG) & 0xffff; + *value = readl(smi_reg) & 0xffff; out: - spin_unlock_irqrestore(&mv643xx_eth_phy_lock, flags); + spin_unlock_irqrestore(&mp->shared_smi->phy_lock, flags); } /* @@ -2962,17 +3049,16 @@ out: static void eth_port_write_smi_reg(struct mv643xx_private *mp, unsigned int phy_reg, unsigned int value) { - int phy_addr; - int i; + void __iomem *smi_reg = mp->shared_smi->eth_base + SMI_REG; + int phy_addr = ethernet_phy_get(mp); unsigned long flags; - - phy_addr = ethernet_phy_get(mp); + int i; /* the SMI register is a shared resource */ - spin_lock_irqsave(&mv643xx_eth_phy_lock, flags); + spin_lock_irqsave(&mp->shared_smi->phy_lock, flags); /* wait for the SMI register to become available */ - for (i = 0; rdl(mp, SMI_REG) & ETH_SMI_BUSY; i++) { + for (i = 0; readl(smi_reg) & ETH_SMI_BUSY; i++) { if (i == PHY_WAIT_ITERATIONS) { printk("%s: PHY busy timeout\n", mp->dev->name); goto out; @@ -2980,10 +3066,10 @@ static void eth_port_write_smi_reg(struct mv643xx_private *mp, udelay(PHY_WAIT_MICRO_SECONDS); } - wrl(mp, SMI_REG, (phy_addr << 16) | (phy_reg << 21) | - ETH_SMI_OPCODE_WRITE | (value & 0xffff)); + writel((phy_addr << 16) | (phy_reg << 21) | + ETH_SMI_OPCODE_WRITE | (value & 0xffff), smi_reg); out: - spin_unlock_irqrestore(&mv643xx_eth_phy_lock, flags); + spin_unlock_irqrestore(&mp->shared_smi->phy_lock, flags); } /* diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index ef63c8d2bd7e4ae550a2f2add91b9327b1e6a40a..c91b12ea26ad7119581fb046587eb49a555063fa 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -144,11 +144,13 @@ struct myri10ge_tx_buf { char *req_bytes; struct myri10ge_tx_buffer_state *info; int mask; /* number of transmit slots -1 */ - int boundary; /* boundary transmits cannot cross */ int req ____cacheline_aligned; /* transmit slots submitted */ int pkt_start; /* packets started */ + int stop_queue; + int linearized; int done ____cacheline_aligned; /* transmit slots completed */ int pkt_done; /* packets completed */ + int wake_queue; }; struct myri10ge_rx_done { @@ -160,29 +162,50 @@ struct myri10ge_rx_done { struct net_lro_desc lro_desc[MYRI10GE_MAX_LRO_DESCRIPTORS]; }; -struct myri10ge_priv { - int running; /* running? */ - int csum_flag; /* rx_csums? */ +struct myri10ge_slice_netstats { + unsigned long rx_packets; + unsigned long tx_packets; + unsigned long rx_bytes; + unsigned long tx_bytes; + unsigned long rx_dropped; + unsigned long tx_dropped; +}; + +struct myri10ge_slice_state { struct myri10ge_tx_buf tx; /* transmit ring */ struct myri10ge_rx_buf rx_small; struct myri10ge_rx_buf rx_big; struct myri10ge_rx_done rx_done; + struct net_device *dev; + struct napi_struct napi; + struct myri10ge_priv *mgp; + struct myri10ge_slice_netstats stats; + __be32 __iomem *irq_claim; + struct mcp_irq_data *fw_stats; + dma_addr_t fw_stats_bus; + int watchdog_tx_done; + int watchdog_tx_req; +}; + +struct myri10ge_priv { + struct myri10ge_slice_state ss; + int tx_boundary; /* boundary transmits cannot cross */ + int running; /* running? */ + int csum_flag; /* rx_csums? */ int small_bytes; int big_bytes; + int max_intr_slots; struct net_device *dev; - struct napi_struct napi; struct net_device_stats stats; + spinlock_t stats_lock; u8 __iomem *sram; int sram_size; unsigned long board_span; unsigned long iomem_base; - __be32 __iomem *irq_claim; __be32 __iomem *irq_deassert; char *mac_addr_string; struct mcp_cmd_response *cmd; dma_addr_t cmd_bus; - struct mcp_irq_data *fw_stats; - dma_addr_t fw_stats_bus; struct pci_dev *pdev; int msi_enabled; u32 link_state; @@ -191,20 +214,16 @@ struct myri10ge_priv { __be32 __iomem *intr_coal_delay_ptr; int mtrr; int wc_enabled; - int wake_queue; - int stop_queue; int down_cnt; wait_queue_head_t down_wq; struct work_struct watchdog_work; struct timer_list watchdog_timer; - int watchdog_tx_done; - int watchdog_tx_req; - int watchdog_pause; int watchdog_resets; - int tx_linearized; + int watchdog_pause; int pause; char *fw_name; char eeprom_strings[MYRI10GE_EEPROM_STRINGS_SIZE]; + char *product_code_string; char fw_version[128]; int fw_ver_major; int fw_ver_minor; @@ -228,58 +247,54 @@ static char *myri10ge_fw_aligned = "myri10ge_eth_z8e.dat"; static char *myri10ge_fw_name = NULL; module_param(myri10ge_fw_name, charp, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(myri10ge_fw_name, "Firmware image name\n"); +MODULE_PARM_DESC(myri10ge_fw_name, "Firmware image name"); static int myri10ge_ecrc_enable = 1; module_param(myri10ge_ecrc_enable, int, S_IRUGO); -MODULE_PARM_DESC(myri10ge_ecrc_enable, "Enable Extended CRC on PCI-E\n"); - -static int myri10ge_max_intr_slots = 1024; -module_param(myri10ge_max_intr_slots, int, S_IRUGO); -MODULE_PARM_DESC(myri10ge_max_intr_slots, "Interrupt queue slots\n"); +MODULE_PARM_DESC(myri10ge_ecrc_enable, "Enable Extended CRC on PCI-E"); static int myri10ge_small_bytes = -1; /* -1 == auto */ module_param(myri10ge_small_bytes, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(myri10ge_small_bytes, "Threshold of small packets\n"); +MODULE_PARM_DESC(myri10ge_small_bytes, "Threshold of small packets"); static int myri10ge_msi = 1; /* enable msi by default */ module_param(myri10ge_msi, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(myri10ge_msi, "Enable Message Signalled Interrupts\n"); +MODULE_PARM_DESC(myri10ge_msi, "Enable Message Signalled Interrupts"); static int myri10ge_intr_coal_delay = 75; module_param(myri10ge_intr_coal_delay, int, S_IRUGO); -MODULE_PARM_DESC(myri10ge_intr_coal_delay, "Interrupt coalescing delay\n"); +MODULE_PARM_DESC(myri10ge_intr_coal_delay, "Interrupt coalescing delay"); static int myri10ge_flow_control = 1; module_param(myri10ge_flow_control, int, S_IRUGO); -MODULE_PARM_DESC(myri10ge_flow_control, "Pause parameter\n"); +MODULE_PARM_DESC(myri10ge_flow_control, "Pause parameter"); static int myri10ge_deassert_wait = 1; module_param(myri10ge_deassert_wait, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(myri10ge_deassert_wait, - "Wait when deasserting legacy interrupts\n"); + "Wait when deasserting legacy interrupts"); static int myri10ge_force_firmware = 0; module_param(myri10ge_force_firmware, int, S_IRUGO); MODULE_PARM_DESC(myri10ge_force_firmware, - "Force firmware to assume aligned completions\n"); + "Force firmware to assume aligned completions"); static int myri10ge_initial_mtu = MYRI10GE_MAX_ETHER_MTU - ETH_HLEN; module_param(myri10ge_initial_mtu, int, S_IRUGO); -MODULE_PARM_DESC(myri10ge_initial_mtu, "Initial MTU\n"); +MODULE_PARM_DESC(myri10ge_initial_mtu, "Initial MTU"); static int myri10ge_napi_weight = 64; module_param(myri10ge_napi_weight, int, S_IRUGO); -MODULE_PARM_DESC(myri10ge_napi_weight, "Set NAPI weight\n"); +MODULE_PARM_DESC(myri10ge_napi_weight, "Set NAPI weight"); static int myri10ge_watchdog_timeout = 1; module_param(myri10ge_watchdog_timeout, int, S_IRUGO); -MODULE_PARM_DESC(myri10ge_watchdog_timeout, "Set watchdog timeout\n"); +MODULE_PARM_DESC(myri10ge_watchdog_timeout, "Set watchdog timeout"); static int myri10ge_max_irq_loops = 1048576; module_param(myri10ge_max_irq_loops, int, S_IRUGO); MODULE_PARM_DESC(myri10ge_max_irq_loops, - "Set stuck legacy IRQ detection threshold\n"); + "Set stuck legacy IRQ detection threshold"); #define MYRI10GE_MSG_DEFAULT NETIF_MSG_LINK @@ -289,21 +304,22 @@ MODULE_PARM_DESC(myri10ge_debug, "Debug level (0=none,...,16=all)"); static int myri10ge_lro = 1; module_param(myri10ge_lro, int, S_IRUGO); -MODULE_PARM_DESC(myri10ge_lro, "Enable large receive offload\n"); +MODULE_PARM_DESC(myri10ge_lro, "Enable large receive offload"); static int myri10ge_lro_max_pkts = MYRI10GE_LRO_MAX_PKTS; module_param(myri10ge_lro_max_pkts, int, S_IRUGO); -MODULE_PARM_DESC(myri10ge_lro, "Number of LRO packets to be aggregated\n"); +MODULE_PARM_DESC(myri10ge_lro_max_pkts, + "Number of LRO packets to be aggregated"); static int myri10ge_fill_thresh = 256; module_param(myri10ge_fill_thresh, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(myri10ge_fill_thresh, "Number of empty rx slots allowed\n"); +MODULE_PARM_DESC(myri10ge_fill_thresh, "Number of empty rx slots allowed"); static int myri10ge_reset_recover = 1; static int myri10ge_wcfifo = 0; module_param(myri10ge_wcfifo, int, S_IRUGO); -MODULE_PARM_DESC(myri10ge_wcfifo, "Enable WC Fifo when WC is enabled\n"); +MODULE_PARM_DESC(myri10ge_wcfifo, "Enable WC Fifo when WC is enabled"); #define MYRI10GE_FW_OFFSET 1024*1024 #define MYRI10GE_HIGHPART_TO_U32(X) \ @@ -359,8 +375,10 @@ myri10ge_send_cmd(struct myri10ge_priv *mgp, u32 cmd, for (sleep_total = 0; sleep_total < 1000 && response->result == htonl(MYRI10GE_NO_RESPONSE_RESULT); - sleep_total += 10) + sleep_total += 10) { udelay(10); + mb(); + } } else { /* use msleep for most command */ for (sleep_total = 0; @@ -420,6 +438,10 @@ static int myri10ge_read_mac_addr(struct myri10ge_priv *mgp) ptr += 1; } } + if (memcmp(ptr, "PC=", 3) == 0) { + ptr += 3; + mgp->product_code_string = ptr; + } if (memcmp((const void *)ptr, "SN=", 3) == 0) { ptr += 3; mgp->serial_number = simple_strtoul(ptr, &ptr, 10); @@ -442,7 +464,7 @@ abort: static void myri10ge_dummy_rdma(struct myri10ge_priv *mgp, int enable) { char __iomem *submit; - __be32 buf[16]; + __be32 buf[16] __attribute__ ((__aligned__(8))); u32 dma_low, dma_high; int i; @@ -609,13 +631,38 @@ static int myri10ge_adopt_running_firmware(struct myri10ge_priv *mgp) return status; } +int myri10ge_get_firmware_capabilities(struct myri10ge_priv *mgp) +{ + struct myri10ge_cmd cmd; + int status; + + /* probe for IPv6 TSO support */ + mgp->features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_TSO; + status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_MAX_TSO6_HDR_SIZE, + &cmd, 0); + if (status == 0) { + mgp->max_tso6 = cmd.data0; + mgp->features |= NETIF_F_TSO6; + } + + status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_RX_RING_SIZE, &cmd, 0); + if (status != 0) { + dev_err(&mgp->pdev->dev, + "failed MXGEFW_CMD_GET_RX_RING_SIZE\n"); + return -ENXIO; + } + + mgp->max_intr_slots = 2 * (cmd.data0 / sizeof(struct mcp_dma_addr)); + + return 0; +} + static int myri10ge_load_firmware(struct myri10ge_priv *mgp) { char __iomem *submit; - __be32 buf[16]; + __be32 buf[16] __attribute__ ((__aligned__(8))); u32 dma_low, dma_high, size; int status, i; - struct myri10ge_cmd cmd; size = 0; status = myri10ge_load_hotplug_firmware(mgp, &size); @@ -635,7 +682,7 @@ static int myri10ge_load_firmware(struct myri10ge_priv *mgp) } dev_info(&mgp->pdev->dev, "Successfully adopted running firmware\n"); - if (mgp->tx.boundary == 4096) { + if (mgp->tx_boundary == 4096) { dev_warn(&mgp->pdev->dev, "Using firmware currently running on NIC" ". For optimal\n"); @@ -646,7 +693,9 @@ static int myri10ge_load_firmware(struct myri10ge_priv *mgp) } mgp->fw_name = "adopted"; - mgp->tx.boundary = 2048; + mgp->tx_boundary = 2048; + myri10ge_dummy_rdma(mgp, 1); + status = myri10ge_get_firmware_capabilities(mgp); return status; } @@ -681,26 +730,18 @@ static int myri10ge_load_firmware(struct myri10ge_priv *mgp) msleep(1); mb(); i = 0; - while (mgp->cmd->data != MYRI10GE_NO_CONFIRM_DATA && i < 20) { - msleep(1); + while (mgp->cmd->data != MYRI10GE_NO_CONFIRM_DATA && i < 9) { + msleep(1 << i); i++; } if (mgp->cmd->data != MYRI10GE_NO_CONFIRM_DATA) { dev_err(&mgp->pdev->dev, "handoff failed\n"); return -ENXIO; } - dev_info(&mgp->pdev->dev, "handoff confirmed\n"); myri10ge_dummy_rdma(mgp, 1); + status = myri10ge_get_firmware_capabilities(mgp); - /* probe for IPv6 TSO support */ - mgp->features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_TSO; - status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_MAX_TSO6_HDR_SIZE, - &cmd, 0); - if (status == 0) { - mgp->max_tso6 = cmd.data0; - mgp->features |= NETIF_F_TSO6; - } - return 0; + return status; } static int myri10ge_update_mac_address(struct myri10ge_priv *mgp, u8 * addr) @@ -772,7 +813,7 @@ static int myri10ge_dma_test(struct myri10ge_priv *mgp, int test_type) * transfers took to complete. */ - len = mgp->tx.boundary; + len = mgp->tx_boundary; cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus); cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus); @@ -834,17 +875,17 @@ static int myri10ge_reset(struct myri10ge_priv *mgp) /* Now exchange information about interrupts */ - bytes = myri10ge_max_intr_slots * sizeof(*mgp->rx_done.entry); - memset(mgp->rx_done.entry, 0, bytes); + bytes = mgp->max_intr_slots * sizeof(*mgp->ss.rx_done.entry); + memset(mgp->ss.rx_done.entry, 0, bytes); cmd.data0 = (u32) bytes; status = myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_INTRQ_SIZE, &cmd, 0); - cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->rx_done.bus); - cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->rx_done.bus); + cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->ss.rx_done.bus); + cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->ss.rx_done.bus); status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_INTRQ_DMA, &cmd, 0); status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_IRQ_ACK_OFFSET, &cmd, 0); - mgp->irq_claim = (__iomem __be32 *) (mgp->sram + cmd.data0); + mgp->ss.irq_claim = (__iomem __be32 *) (mgp->sram + cmd.data0); status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_IRQ_DEASSERT_OFFSET, &cmd, 0); mgp->irq_deassert = (__iomem __be32 *) (mgp->sram + cmd.data0); @@ -858,17 +899,17 @@ static int myri10ge_reset(struct myri10ge_priv *mgp) } put_be32(htonl(mgp->intr_coal_delay), mgp->intr_coal_delay_ptr); - memset(mgp->rx_done.entry, 0, bytes); + memset(mgp->ss.rx_done.entry, 0, bytes); /* reset mcp/driver shared state back to 0 */ - mgp->tx.req = 0; - mgp->tx.done = 0; - mgp->tx.pkt_start = 0; - mgp->tx.pkt_done = 0; - mgp->rx_big.cnt = 0; - mgp->rx_small.cnt = 0; - mgp->rx_done.idx = 0; - mgp->rx_done.cnt = 0; + mgp->ss.tx.req = 0; + mgp->ss.tx.done = 0; + mgp->ss.tx.pkt_start = 0; + mgp->ss.tx.pkt_done = 0; + mgp->ss.rx_big.cnt = 0; + mgp->ss.rx_small.cnt = 0; + mgp->ss.rx_done.idx = 0; + mgp->ss.rx_done.cnt = 0; mgp->link_changes = 0; status = myri10ge_update_mac_address(mgp, mgp->dev->dev_addr); myri10ge_change_pause(mgp, mgp->pause); @@ -1020,9 +1061,10 @@ myri10ge_unmap_rx_page(struct pci_dev *pdev, * page into an skb */ static inline int -myri10ge_rx_done(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx, +myri10ge_rx_done(struct myri10ge_slice_state *ss, struct myri10ge_rx_buf *rx, int bytes, int len, __wsum csum) { + struct myri10ge_priv *mgp = ss->mgp; struct sk_buff *skb; struct skb_frag_struct rx_frags[MYRI10GE_MAX_FRAGS_PER_FRAME]; int i, idx, hlen, remainder; @@ -1052,11 +1094,10 @@ myri10ge_rx_done(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx, rx_frags[0].page_offset += MXGEFW_PAD; rx_frags[0].size -= MXGEFW_PAD; len -= MXGEFW_PAD; - lro_receive_frags(&mgp->rx_done.lro_mgr, rx_frags, + lro_receive_frags(&ss->rx_done.lro_mgr, rx_frags, len, len, - /* opaque, will come back in get_frag_header */ - (void *)(__force unsigned long)csum, - csum); + /* opaque, will come back in get_frag_header */ + (void *)(__force unsigned long)csum, csum); return 1; } @@ -1096,10 +1137,11 @@ myri10ge_rx_done(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx, return 1; } -static inline void myri10ge_tx_done(struct myri10ge_priv *mgp, int mcp_index) +static inline void +myri10ge_tx_done(struct myri10ge_slice_state *ss, int mcp_index) { - struct pci_dev *pdev = mgp->pdev; - struct myri10ge_tx_buf *tx = &mgp->tx; + struct pci_dev *pdev = ss->mgp->pdev; + struct myri10ge_tx_buf *tx = &ss->tx; struct sk_buff *skb; int idx, len; @@ -1117,8 +1159,8 @@ static inline void myri10ge_tx_done(struct myri10ge_priv *mgp, int mcp_index) len = pci_unmap_len(&tx->info[idx], len); pci_unmap_len_set(&tx->info[idx], len, 0); if (skb) { - mgp->stats.tx_bytes += skb->len; - mgp->stats.tx_packets++; + ss->stats.tx_bytes += skb->len; + ss->stats.tx_packets++; dev_kfree_skb_irq(skb); if (len) pci_unmap_single(pdev, @@ -1134,16 +1176,18 @@ static inline void myri10ge_tx_done(struct myri10ge_priv *mgp, int mcp_index) } } /* start the queue if we've stopped it */ - if (netif_queue_stopped(mgp->dev) + if (netif_queue_stopped(ss->dev) && tx->req - tx->done < (tx->mask >> 1)) { - mgp->wake_queue++; - netif_wake_queue(mgp->dev); + tx->wake_queue++; + netif_wake_queue(ss->dev); } } -static inline int myri10ge_clean_rx_done(struct myri10ge_priv *mgp, int budget) +static inline int +myri10ge_clean_rx_done(struct myri10ge_slice_state *ss, int budget) { - struct myri10ge_rx_done *rx_done = &mgp->rx_done; + struct myri10ge_rx_done *rx_done = &ss->rx_done; + struct myri10ge_priv *mgp = ss->mgp; unsigned long rx_bytes = 0; unsigned long rx_packets = 0; unsigned long rx_ok; @@ -1159,40 +1203,40 @@ static inline int myri10ge_clean_rx_done(struct myri10ge_priv *mgp, int budget) rx_done->entry[idx].length = 0; checksum = csum_unfold(rx_done->entry[idx].checksum); if (length <= mgp->small_bytes) - rx_ok = myri10ge_rx_done(mgp, &mgp->rx_small, + rx_ok = myri10ge_rx_done(ss, &ss->rx_small, mgp->small_bytes, length, checksum); else - rx_ok = myri10ge_rx_done(mgp, &mgp->rx_big, + rx_ok = myri10ge_rx_done(ss, &ss->rx_big, mgp->big_bytes, length, checksum); rx_packets += rx_ok; rx_bytes += rx_ok * (unsigned long)length; cnt++; - idx = cnt & (myri10ge_max_intr_slots - 1); + idx = cnt & (mgp->max_intr_slots - 1); work_done++; } rx_done->idx = idx; rx_done->cnt = cnt; - mgp->stats.rx_packets += rx_packets; - mgp->stats.rx_bytes += rx_bytes; + ss->stats.rx_packets += rx_packets; + ss->stats.rx_bytes += rx_bytes; if (myri10ge_lro) lro_flush_all(&rx_done->lro_mgr); /* restock receive rings if needed */ - if (mgp->rx_small.fill_cnt - mgp->rx_small.cnt < myri10ge_fill_thresh) - myri10ge_alloc_rx_pages(mgp, &mgp->rx_small, + if (ss->rx_small.fill_cnt - ss->rx_small.cnt < myri10ge_fill_thresh) + myri10ge_alloc_rx_pages(mgp, &ss->rx_small, mgp->small_bytes + MXGEFW_PAD, 0); - if (mgp->rx_big.fill_cnt - mgp->rx_big.cnt < myri10ge_fill_thresh) - myri10ge_alloc_rx_pages(mgp, &mgp->rx_big, mgp->big_bytes, 0); + if (ss->rx_big.fill_cnt - ss->rx_big.cnt < myri10ge_fill_thresh) + myri10ge_alloc_rx_pages(mgp, &ss->rx_big, mgp->big_bytes, 0); return work_done; } static inline void myri10ge_check_statblock(struct myri10ge_priv *mgp) { - struct mcp_irq_data *stats = mgp->fw_stats; + struct mcp_irq_data *stats = mgp->ss.fw_stats; if (unlikely(stats->stats_updated)) { unsigned link_up = ntohl(stats->link_up); @@ -1219,9 +1263,9 @@ static inline void myri10ge_check_statblock(struct myri10ge_priv *mgp) } } if (mgp->rdma_tags_available != - ntohl(mgp->fw_stats->rdma_tags_available)) { + ntohl(stats->rdma_tags_available)) { mgp->rdma_tags_available = - ntohl(mgp->fw_stats->rdma_tags_available); + ntohl(stats->rdma_tags_available); printk(KERN_WARNING "myri10ge: %s: RDMA timed out! " "%d tags left\n", mgp->dev->name, mgp->rdma_tags_available); @@ -1234,26 +1278,27 @@ static inline void myri10ge_check_statblock(struct myri10ge_priv *mgp) static int myri10ge_poll(struct napi_struct *napi, int budget) { - struct myri10ge_priv *mgp = - container_of(napi, struct myri10ge_priv, napi); - struct net_device *netdev = mgp->dev; + struct myri10ge_slice_state *ss = + container_of(napi, struct myri10ge_slice_state, napi); + struct net_device *netdev = ss->mgp->dev; int work_done; /* process as many rx events as NAPI will allow */ - work_done = myri10ge_clean_rx_done(mgp, budget); + work_done = myri10ge_clean_rx_done(ss, budget); if (work_done < budget) { netif_rx_complete(netdev, napi); - put_be32(htonl(3), mgp->irq_claim); + put_be32(htonl(3), ss->irq_claim); } return work_done; } static irqreturn_t myri10ge_intr(int irq, void *arg) { - struct myri10ge_priv *mgp = arg; - struct mcp_irq_data *stats = mgp->fw_stats; - struct myri10ge_tx_buf *tx = &mgp->tx; + struct myri10ge_slice_state *ss = arg; + struct myri10ge_priv *mgp = ss->mgp; + struct mcp_irq_data *stats = ss->fw_stats; + struct myri10ge_tx_buf *tx = &ss->tx; u32 send_done_count; int i; @@ -1264,7 +1309,7 @@ static irqreturn_t myri10ge_intr(int irq, void *arg) /* low bit indicates receives are present, so schedule * napi poll handler */ if (stats->valid & 1) - netif_rx_schedule(mgp->dev, &mgp->napi); + netif_rx_schedule(ss->dev, &ss->napi); if (!mgp->msi_enabled) { put_be32(0, mgp->irq_deassert); @@ -1281,7 +1326,7 @@ static irqreturn_t myri10ge_intr(int irq, void *arg) /* check for transmit completes and receives */ send_done_count = ntohl(stats->send_done_count); if (send_done_count != tx->pkt_done) - myri10ge_tx_done(mgp, (int)send_done_count); + myri10ge_tx_done(ss, (int)send_done_count); if (unlikely(i > myri10ge_max_irq_loops)) { printk(KERN_WARNING "myri10ge: %s: irq stuck?\n", mgp->dev->name); @@ -1296,16 +1341,46 @@ static irqreturn_t myri10ge_intr(int irq, void *arg) myri10ge_check_statblock(mgp); - put_be32(htonl(3), mgp->irq_claim + 1); + put_be32(htonl(3), ss->irq_claim + 1); return (IRQ_HANDLED); } static int myri10ge_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd) { + struct myri10ge_priv *mgp = netdev_priv(netdev); + char *ptr; + int i; + cmd->autoneg = AUTONEG_DISABLE; cmd->speed = SPEED_10000; cmd->duplex = DUPLEX_FULL; + + /* + * parse the product code to deterimine the interface type + * (CX4, XFP, Quad Ribbon Fiber) by looking at the character + * after the 3rd dash in the driver's cached copy of the + * EEPROM's product code string. + */ + ptr = mgp->product_code_string; + if (ptr == NULL) { + printk(KERN_ERR "myri10ge: %s: Missing product code\n", + netdev->name); + return 0; + } + for (i = 0; i < 3; i++, ptr++) { + ptr = strchr(ptr, '-'); + if (ptr == NULL) { + printk(KERN_ERR "myri10ge: %s: Invalid product " + "code %s\n", netdev->name, + mgp->product_code_string); + return 0; + } + } + if (*ptr == 'R' || *ptr == 'Q') { + /* We've found either an XFP or quad ribbon fiber */ + cmd->port = PORT_FIBRE; + } return 0; } @@ -1324,6 +1399,7 @@ static int myri10ge_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *coal) { struct myri10ge_priv *mgp = netdev_priv(netdev); + coal->rx_coalesce_usecs = mgp->intr_coal_delay; return 0; } @@ -1370,10 +1446,10 @@ myri10ge_get_ringparam(struct net_device *netdev, { struct myri10ge_priv *mgp = netdev_priv(netdev); - ring->rx_mini_max_pending = mgp->rx_small.mask + 1; - ring->rx_max_pending = mgp->rx_big.mask + 1; + ring->rx_mini_max_pending = mgp->ss.rx_small.mask + 1; + ring->rx_max_pending = mgp->ss.rx_big.mask + 1; ring->rx_jumbo_max_pending = 0; - ring->tx_max_pending = mgp->rx_small.mask + 1; + ring->tx_max_pending = mgp->ss.rx_small.mask + 1; ring->rx_mini_pending = ring->rx_mini_max_pending; ring->rx_pending = ring->rx_max_pending; ring->rx_jumbo_pending = ring->rx_jumbo_max_pending; @@ -1383,6 +1459,7 @@ myri10ge_get_ringparam(struct net_device *netdev, static u32 myri10ge_get_rx_csum(struct net_device *netdev) { struct myri10ge_priv *mgp = netdev_priv(netdev); + if (mgp->csum_flag) return 1; else @@ -1392,6 +1469,7 @@ static u32 myri10ge_get_rx_csum(struct net_device *netdev) static int myri10ge_set_rx_csum(struct net_device *netdev, u32 csum_enabled) { struct myri10ge_priv *mgp = netdev_priv(netdev); + if (csum_enabled) mgp->csum_flag = MXGEFW_FLAGS_CKSUM; else @@ -1411,7 +1489,7 @@ static int myri10ge_set_tso(struct net_device *netdev, u32 tso_enabled) return 0; } -static const char myri10ge_gstrings_stats[][ETH_GSTRING_LEN] = { +static const char myri10ge_gstrings_main_stats[][ETH_GSTRING_LEN] = { "rx_packets", "tx_packets", "rx_bytes", "tx_bytes", "rx_errors", "tx_errors", "rx_dropped", "tx_dropped", "multicast", "collisions", "rx_length_errors", "rx_over_errors", "rx_crc_errors", @@ -1421,28 +1499,39 @@ static const char myri10ge_gstrings_stats[][ETH_GSTRING_LEN] = { /* device-specific stats */ "tx_boundary", "WC", "irq", "MSI", "read_dma_bw_MBs", "write_dma_bw_MBs", "read_write_dma_bw_MBs", - "serial_number", "tx_pkt_start", "tx_pkt_done", - "tx_req", "tx_done", "rx_small_cnt", "rx_big_cnt", - "wake_queue", "stop_queue", "watchdog_resets", "tx_linearized", + "serial_number", "watchdog_resets", "link_changes", "link_up", "dropped_link_overflow", "dropped_link_error_or_filtered", "dropped_pause", "dropped_bad_phy", "dropped_bad_crc32", "dropped_unicast_filtered", "dropped_multicast_filtered", "dropped_runt", "dropped_overrun", "dropped_no_small_buffer", - "dropped_no_big_buffer", "LRO aggregated", "LRO flushed", + "dropped_no_big_buffer" +}; + +static const char myri10ge_gstrings_slice_stats[][ETH_GSTRING_LEN] = { + "----------- slice ---------", + "tx_pkt_start", "tx_pkt_done", "tx_req", "tx_done", + "rx_small_cnt", "rx_big_cnt", + "wake_queue", "stop_queue", "tx_linearized", "LRO aggregated", + "LRO flushed", "LRO avg aggr", "LRO no_desc" }; #define MYRI10GE_NET_STATS_LEN 21 -#define MYRI10GE_STATS_LEN ARRAY_SIZE(myri10ge_gstrings_stats) +#define MYRI10GE_MAIN_STATS_LEN ARRAY_SIZE(myri10ge_gstrings_main_stats) +#define MYRI10GE_SLICE_STATS_LEN ARRAY_SIZE(myri10ge_gstrings_slice_stats) static void myri10ge_get_strings(struct net_device *netdev, u32 stringset, u8 * data) { switch (stringset) { case ETH_SS_STATS: - memcpy(data, *myri10ge_gstrings_stats, - sizeof(myri10ge_gstrings_stats)); + memcpy(data, *myri10ge_gstrings_main_stats, + sizeof(myri10ge_gstrings_main_stats)); + data += sizeof(myri10ge_gstrings_main_stats); + memcpy(data, *myri10ge_gstrings_slice_stats, + sizeof(myri10ge_gstrings_slice_stats)); + data += sizeof(myri10ge_gstrings_slice_stats); break; } } @@ -1451,7 +1540,7 @@ static int myri10ge_get_sset_count(struct net_device *netdev, int sset) { switch (sset) { case ETH_SS_STATS: - return MYRI10GE_STATS_LEN; + return MYRI10GE_MAIN_STATS_LEN + MYRI10GE_SLICE_STATS_LEN; default: return -EOPNOTSUPP; } @@ -1462,12 +1551,13 @@ myri10ge_get_ethtool_stats(struct net_device *netdev, struct ethtool_stats *stats, u64 * data) { struct myri10ge_priv *mgp = netdev_priv(netdev); + struct myri10ge_slice_state *ss; int i; for (i = 0; i < MYRI10GE_NET_STATS_LEN; i++) data[i] = ((unsigned long *)&mgp->stats)[i]; - data[i++] = (unsigned int)mgp->tx.boundary; + data[i++] = (unsigned int)mgp->tx_boundary; data[i++] = (unsigned int)mgp->wc_enabled; data[i++] = (unsigned int)mgp->pdev->irq; data[i++] = (unsigned int)mgp->msi_enabled; @@ -1475,40 +1565,44 @@ myri10ge_get_ethtool_stats(struct net_device *netdev, data[i++] = (unsigned int)mgp->write_dma; data[i++] = (unsigned int)mgp->read_write_dma; data[i++] = (unsigned int)mgp->serial_number; - data[i++] = (unsigned int)mgp->tx.pkt_start; - data[i++] = (unsigned int)mgp->tx.pkt_done; - data[i++] = (unsigned int)mgp->tx.req; - data[i++] = (unsigned int)mgp->tx.done; - data[i++] = (unsigned int)mgp->rx_small.cnt; - data[i++] = (unsigned int)mgp->rx_big.cnt; - data[i++] = (unsigned int)mgp->wake_queue; - data[i++] = (unsigned int)mgp->stop_queue; data[i++] = (unsigned int)mgp->watchdog_resets; - data[i++] = (unsigned int)mgp->tx_linearized; data[i++] = (unsigned int)mgp->link_changes; - data[i++] = (unsigned int)ntohl(mgp->fw_stats->link_up); - data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_link_overflow); - data[i++] = - (unsigned int)ntohl(mgp->fw_stats->dropped_link_error_or_filtered); - data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_pause); - data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_bad_phy); - data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_bad_crc32); + + /* firmware stats are useful only in the first slice */ + ss = &mgp->ss; + data[i++] = (unsigned int)ntohl(ss->fw_stats->link_up); + data[i++] = (unsigned int)ntohl(ss->fw_stats->dropped_link_overflow); data[i++] = - (unsigned int)ntohl(mgp->fw_stats->dropped_unicast_filtered); + (unsigned int)ntohl(ss->fw_stats->dropped_link_error_or_filtered); + data[i++] = (unsigned int)ntohl(ss->fw_stats->dropped_pause); + data[i++] = (unsigned int)ntohl(ss->fw_stats->dropped_bad_phy); + data[i++] = (unsigned int)ntohl(ss->fw_stats->dropped_bad_crc32); + data[i++] = (unsigned int)ntohl(ss->fw_stats->dropped_unicast_filtered); data[i++] = - (unsigned int)ntohl(mgp->fw_stats->dropped_multicast_filtered); - data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_runt); - data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_overrun); - data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_no_small_buffer); - data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_no_big_buffer); - data[i++] = mgp->rx_done.lro_mgr.stats.aggregated; - data[i++] = mgp->rx_done.lro_mgr.stats.flushed; - if (mgp->rx_done.lro_mgr.stats.flushed) - data[i++] = mgp->rx_done.lro_mgr.stats.aggregated / - mgp->rx_done.lro_mgr.stats.flushed; + (unsigned int)ntohl(ss->fw_stats->dropped_multicast_filtered); + data[i++] = (unsigned int)ntohl(ss->fw_stats->dropped_runt); + data[i++] = (unsigned int)ntohl(ss->fw_stats->dropped_overrun); + data[i++] = (unsigned int)ntohl(ss->fw_stats->dropped_no_small_buffer); + data[i++] = (unsigned int)ntohl(ss->fw_stats->dropped_no_big_buffer); + + data[i++] = 0; + data[i++] = (unsigned int)ss->tx.pkt_start; + data[i++] = (unsigned int)ss->tx.pkt_done; + data[i++] = (unsigned int)ss->tx.req; + data[i++] = (unsigned int)ss->tx.done; + data[i++] = (unsigned int)ss->rx_small.cnt; + data[i++] = (unsigned int)ss->rx_big.cnt; + data[i++] = (unsigned int)ss->tx.wake_queue; + data[i++] = (unsigned int)ss->tx.stop_queue; + data[i++] = (unsigned int)ss->tx.linearized; + data[i++] = ss->rx_done.lro_mgr.stats.aggregated; + data[i++] = ss->rx_done.lro_mgr.stats.flushed; + if (ss->rx_done.lro_mgr.stats.flushed) + data[i++] = ss->rx_done.lro_mgr.stats.aggregated / + ss->rx_done.lro_mgr.stats.flushed; else data[i++] = 0; - data[i++] = mgp->rx_done.lro_mgr.stats.no_desc; + data[i++] = ss->rx_done.lro_mgr.stats.no_desc; } static void myri10ge_set_msglevel(struct net_device *netdev, u32 value) @@ -1544,19 +1638,17 @@ static const struct ethtool_ops myri10ge_ethtool_ops = { .get_msglevel = myri10ge_get_msglevel }; -static int myri10ge_allocate_rings(struct net_device *dev) +static int myri10ge_allocate_rings(struct myri10ge_slice_state *ss) { - struct myri10ge_priv *mgp; + struct myri10ge_priv *mgp = ss->mgp; struct myri10ge_cmd cmd; + struct net_device *dev = mgp->dev; int tx_ring_size, rx_ring_size; int tx_ring_entries, rx_ring_entries; int i, status; size_t bytes; - mgp = netdev_priv(dev); - /* get ring sizes */ - status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_SEND_RING_SIZE, &cmd, 0); tx_ring_size = cmd.data0; status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_RX_RING_SIZE, &cmd, 0); @@ -1566,144 +1658,142 @@ static int myri10ge_allocate_rings(struct net_device *dev) tx_ring_entries = tx_ring_size / sizeof(struct mcp_kreq_ether_send); rx_ring_entries = rx_ring_size / sizeof(struct mcp_dma_addr); - mgp->tx.mask = tx_ring_entries - 1; - mgp->rx_small.mask = mgp->rx_big.mask = rx_ring_entries - 1; + ss->tx.mask = tx_ring_entries - 1; + ss->rx_small.mask = ss->rx_big.mask = rx_ring_entries - 1; status = -ENOMEM; /* allocate the host shadow rings */ bytes = 8 + (MYRI10GE_MAX_SEND_DESC_TSO + 4) - * sizeof(*mgp->tx.req_list); - mgp->tx.req_bytes = kzalloc(bytes, GFP_KERNEL); - if (mgp->tx.req_bytes == NULL) + * sizeof(*ss->tx.req_list); + ss->tx.req_bytes = kzalloc(bytes, GFP_KERNEL); + if (ss->tx.req_bytes == NULL) goto abort_with_nothing; /* ensure req_list entries are aligned to 8 bytes */ - mgp->tx.req_list = (struct mcp_kreq_ether_send *) - ALIGN((unsigned long)mgp->tx.req_bytes, 8); + ss->tx.req_list = (struct mcp_kreq_ether_send *) + ALIGN((unsigned long)ss->tx.req_bytes, 8); - bytes = rx_ring_entries * sizeof(*mgp->rx_small.shadow); - mgp->rx_small.shadow = kzalloc(bytes, GFP_KERNEL); - if (mgp->rx_small.shadow == NULL) + bytes = rx_ring_entries * sizeof(*ss->rx_small.shadow); + ss->rx_small.shadow = kzalloc(bytes, GFP_KERNEL); + if (ss->rx_small.shadow == NULL) goto abort_with_tx_req_bytes; - bytes = rx_ring_entries * sizeof(*mgp->rx_big.shadow); - mgp->rx_big.shadow = kzalloc(bytes, GFP_KERNEL); - if (mgp->rx_big.shadow == NULL) + bytes = rx_ring_entries * sizeof(*ss->rx_big.shadow); + ss->rx_big.shadow = kzalloc(bytes, GFP_KERNEL); + if (ss->rx_big.shadow == NULL) goto abort_with_rx_small_shadow; /* allocate the host info rings */ - bytes = tx_ring_entries * sizeof(*mgp->tx.info); - mgp->tx.info = kzalloc(bytes, GFP_KERNEL); - if (mgp->tx.info == NULL) + bytes = tx_ring_entries * sizeof(*ss->tx.info); + ss->tx.info = kzalloc(bytes, GFP_KERNEL); + if (ss->tx.info == NULL) goto abort_with_rx_big_shadow; - bytes = rx_ring_entries * sizeof(*mgp->rx_small.info); - mgp->rx_small.info = kzalloc(bytes, GFP_KERNEL); - if (mgp->rx_small.info == NULL) + bytes = rx_ring_entries * sizeof(*ss->rx_small.info); + ss->rx_small.info = kzalloc(bytes, GFP_KERNEL); + if (ss->rx_small.info == NULL) goto abort_with_tx_info; - bytes = rx_ring_entries * sizeof(*mgp->rx_big.info); - mgp->rx_big.info = kzalloc(bytes, GFP_KERNEL); - if (mgp->rx_big.info == NULL) + bytes = rx_ring_entries * sizeof(*ss->rx_big.info); + ss->rx_big.info = kzalloc(bytes, GFP_KERNEL); + if (ss->rx_big.info == NULL) goto abort_with_rx_small_info; /* Fill the receive rings */ - mgp->rx_big.cnt = 0; - mgp->rx_small.cnt = 0; - mgp->rx_big.fill_cnt = 0; - mgp->rx_small.fill_cnt = 0; - mgp->rx_small.page_offset = MYRI10GE_ALLOC_SIZE; - mgp->rx_big.page_offset = MYRI10GE_ALLOC_SIZE; - mgp->rx_small.watchdog_needed = 0; - mgp->rx_big.watchdog_needed = 0; - myri10ge_alloc_rx_pages(mgp, &mgp->rx_small, + ss->rx_big.cnt = 0; + ss->rx_small.cnt = 0; + ss->rx_big.fill_cnt = 0; + ss->rx_small.fill_cnt = 0; + ss->rx_small.page_offset = MYRI10GE_ALLOC_SIZE; + ss->rx_big.page_offset = MYRI10GE_ALLOC_SIZE; + ss->rx_small.watchdog_needed = 0; + ss->rx_big.watchdog_needed = 0; + myri10ge_alloc_rx_pages(mgp, &ss->rx_small, mgp->small_bytes + MXGEFW_PAD, 0); - if (mgp->rx_small.fill_cnt < mgp->rx_small.mask + 1) { + if (ss->rx_small.fill_cnt < ss->rx_small.mask + 1) { printk(KERN_ERR "myri10ge: %s: alloced only %d small bufs\n", - dev->name, mgp->rx_small.fill_cnt); + dev->name, ss->rx_small.fill_cnt); goto abort_with_rx_small_ring; } - myri10ge_alloc_rx_pages(mgp, &mgp->rx_big, mgp->big_bytes, 0); - if (mgp->rx_big.fill_cnt < mgp->rx_big.mask + 1) { + myri10ge_alloc_rx_pages(mgp, &ss->rx_big, mgp->big_bytes, 0); + if (ss->rx_big.fill_cnt < ss->rx_big.mask + 1) { printk(KERN_ERR "myri10ge: %s: alloced only %d big bufs\n", - dev->name, mgp->rx_big.fill_cnt); + dev->name, ss->rx_big.fill_cnt); goto abort_with_rx_big_ring; } return 0; abort_with_rx_big_ring: - for (i = mgp->rx_big.cnt; i < mgp->rx_big.fill_cnt; i++) { - int idx = i & mgp->rx_big.mask; - myri10ge_unmap_rx_page(mgp->pdev, &mgp->rx_big.info[idx], + for (i = ss->rx_big.cnt; i < ss->rx_big.fill_cnt; i++) { + int idx = i & ss->rx_big.mask; + myri10ge_unmap_rx_page(mgp->pdev, &ss->rx_big.info[idx], mgp->big_bytes); - put_page(mgp->rx_big.info[idx].page); + put_page(ss->rx_big.info[idx].page); } abort_with_rx_small_ring: - for (i = mgp->rx_small.cnt; i < mgp->rx_small.fill_cnt; i++) { - int idx = i & mgp->rx_small.mask; - myri10ge_unmap_rx_page(mgp->pdev, &mgp->rx_small.info[idx], + for (i = ss->rx_small.cnt; i < ss->rx_small.fill_cnt; i++) { + int idx = i & ss->rx_small.mask; + myri10ge_unmap_rx_page(mgp->pdev, &ss->rx_small.info[idx], mgp->small_bytes + MXGEFW_PAD); - put_page(mgp->rx_small.info[idx].page); + put_page(ss->rx_small.info[idx].page); } - kfree(mgp->rx_big.info); + kfree(ss->rx_big.info); abort_with_rx_small_info: - kfree(mgp->rx_small.info); + kfree(ss->rx_small.info); abort_with_tx_info: - kfree(mgp->tx.info); + kfree(ss->tx.info); abort_with_rx_big_shadow: - kfree(mgp->rx_big.shadow); + kfree(ss->rx_big.shadow); abort_with_rx_small_shadow: - kfree(mgp->rx_small.shadow); + kfree(ss->rx_small.shadow); abort_with_tx_req_bytes: - kfree(mgp->tx.req_bytes); - mgp->tx.req_bytes = NULL; - mgp->tx.req_list = NULL; + kfree(ss->tx.req_bytes); + ss->tx.req_bytes = NULL; + ss->tx.req_list = NULL; abort_with_nothing: return status; } -static void myri10ge_free_rings(struct net_device *dev) +static void myri10ge_free_rings(struct myri10ge_slice_state *ss) { - struct myri10ge_priv *mgp; + struct myri10ge_priv *mgp = ss->mgp; struct sk_buff *skb; struct myri10ge_tx_buf *tx; int i, len, idx; - mgp = netdev_priv(dev); - - for (i = mgp->rx_big.cnt; i < mgp->rx_big.fill_cnt; i++) { - idx = i & mgp->rx_big.mask; - if (i == mgp->rx_big.fill_cnt - 1) - mgp->rx_big.info[idx].page_offset = MYRI10GE_ALLOC_SIZE; - myri10ge_unmap_rx_page(mgp->pdev, &mgp->rx_big.info[idx], + for (i = ss->rx_big.cnt; i < ss->rx_big.fill_cnt; i++) { + idx = i & ss->rx_big.mask; + if (i == ss->rx_big.fill_cnt - 1) + ss->rx_big.info[idx].page_offset = MYRI10GE_ALLOC_SIZE; + myri10ge_unmap_rx_page(mgp->pdev, &ss->rx_big.info[idx], mgp->big_bytes); - put_page(mgp->rx_big.info[idx].page); + put_page(ss->rx_big.info[idx].page); } - for (i = mgp->rx_small.cnt; i < mgp->rx_small.fill_cnt; i++) { - idx = i & mgp->rx_small.mask; - if (i == mgp->rx_small.fill_cnt - 1) - mgp->rx_small.info[idx].page_offset = + for (i = ss->rx_small.cnt; i < ss->rx_small.fill_cnt; i++) { + idx = i & ss->rx_small.mask; + if (i == ss->rx_small.fill_cnt - 1) + ss->rx_small.info[idx].page_offset = MYRI10GE_ALLOC_SIZE; - myri10ge_unmap_rx_page(mgp->pdev, &mgp->rx_small.info[idx], + myri10ge_unmap_rx_page(mgp->pdev, &ss->rx_small.info[idx], mgp->small_bytes + MXGEFW_PAD); - put_page(mgp->rx_small.info[idx].page); + put_page(ss->rx_small.info[idx].page); } - tx = &mgp->tx; + tx = &ss->tx; while (tx->done != tx->req) { idx = tx->done & tx->mask; skb = tx->info[idx].skb; @@ -1714,7 +1804,7 @@ static void myri10ge_free_rings(struct net_device *dev) len = pci_unmap_len(&tx->info[idx], len); pci_unmap_len_set(&tx->info[idx], len, 0); if (skb) { - mgp->stats.tx_dropped++; + ss->stats.tx_dropped++; dev_kfree_skb_any(skb); if (len) pci_unmap_single(mgp->pdev, @@ -1729,19 +1819,19 @@ static void myri10ge_free_rings(struct net_device *dev) PCI_DMA_TODEVICE); } } - kfree(mgp->rx_big.info); + kfree(ss->rx_big.info); - kfree(mgp->rx_small.info); + kfree(ss->rx_small.info); - kfree(mgp->tx.info); + kfree(ss->tx.info); - kfree(mgp->rx_big.shadow); + kfree(ss->rx_big.shadow); - kfree(mgp->rx_small.shadow); + kfree(ss->rx_small.shadow); - kfree(mgp->tx.req_bytes); - mgp->tx.req_bytes = NULL; - mgp->tx.req_list = NULL; + kfree(ss->tx.req_bytes); + ss->tx.req_bytes = NULL; + ss->tx.req_list = NULL; } static int myri10ge_request_irq(struct myri10ge_priv *mgp) @@ -1840,13 +1930,11 @@ myri10ge_get_frag_header(struct skb_frag_struct *frag, void **mac_hdr, static int myri10ge_open(struct net_device *dev) { - struct myri10ge_priv *mgp; + struct myri10ge_priv *mgp = netdev_priv(dev); struct myri10ge_cmd cmd; struct net_lro_mgr *lro_mgr; int status, big_pow2; - mgp = netdev_priv(dev); - if (mgp->running != MYRI10GE_ETH_STOPPED) return -EBUSY; @@ -1883,16 +1971,16 @@ static int myri10ge_open(struct net_device *dev) /* get the lanai pointers to the send and receive rings */ status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_SEND_OFFSET, &cmd, 0); - mgp->tx.lanai = + mgp->ss.tx.lanai = (struct mcp_kreq_ether_send __iomem *)(mgp->sram + cmd.data0); status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_SMALL_RX_OFFSET, &cmd, 0); - mgp->rx_small.lanai = + mgp->ss.rx_small.lanai = (struct mcp_kreq_ether_recv __iomem *)(mgp->sram + cmd.data0); status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_BIG_RX_OFFSET, &cmd, 0); - mgp->rx_big.lanai = + mgp->ss.rx_big.lanai = (struct mcp_kreq_ether_recv __iomem *)(mgp->sram + cmd.data0); if (status != 0) { @@ -1904,15 +1992,15 @@ static int myri10ge_open(struct net_device *dev) } if (myri10ge_wcfifo && mgp->wc_enabled) { - mgp->tx.wc_fifo = (u8 __iomem *) mgp->sram + MXGEFW_ETH_SEND_4; - mgp->rx_small.wc_fifo = + mgp->ss.tx.wc_fifo = (u8 __iomem *) mgp->sram + MXGEFW_ETH_SEND_4; + mgp->ss.rx_small.wc_fifo = (u8 __iomem *) mgp->sram + MXGEFW_ETH_RECV_SMALL; - mgp->rx_big.wc_fifo = + mgp->ss.rx_big.wc_fifo = (u8 __iomem *) mgp->sram + MXGEFW_ETH_RECV_BIG; } else { - mgp->tx.wc_fifo = NULL; - mgp->rx_small.wc_fifo = NULL; - mgp->rx_big.wc_fifo = NULL; + mgp->ss.tx.wc_fifo = NULL; + mgp->ss.rx_small.wc_fifo = NULL; + mgp->ss.rx_big.wc_fifo = NULL; } /* Firmware needs the big buff size as a power of 2. Lie and @@ -1929,7 +2017,7 @@ static int myri10ge_open(struct net_device *dev) mgp->big_bytes = big_pow2; } - status = myri10ge_allocate_rings(dev); + status = myri10ge_allocate_rings(&mgp->ss); if (status != 0) goto abort_with_irq; @@ -1948,12 +2036,12 @@ static int myri10ge_open(struct net_device *dev) goto abort_with_rings; } - cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->fw_stats_bus); - cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->fw_stats_bus); + cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->ss.fw_stats_bus); + cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->ss.fw_stats_bus); cmd.data2 = sizeof(struct mcp_irq_data); status = myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_STATS_DMA_V2, &cmd, 0); if (status == -ENOSYS) { - dma_addr_t bus = mgp->fw_stats_bus; + dma_addr_t bus = mgp->ss.fw_stats_bus; bus += offsetof(struct mcp_irq_data, send_done_count); cmd.data0 = MYRI10GE_LOWPART_TO_U32(bus); cmd.data1 = MYRI10GE_HIGHPART_TO_U32(bus); @@ -1974,20 +2062,20 @@ static int myri10ge_open(struct net_device *dev) mgp->link_state = ~0U; mgp->rdma_tags_available = 15; - lro_mgr = &mgp->rx_done.lro_mgr; + lro_mgr = &mgp->ss.rx_done.lro_mgr; lro_mgr->dev = dev; lro_mgr->features = LRO_F_NAPI; lro_mgr->ip_summed = CHECKSUM_COMPLETE; lro_mgr->ip_summed_aggr = CHECKSUM_UNNECESSARY; lro_mgr->max_desc = MYRI10GE_MAX_LRO_DESCRIPTORS; - lro_mgr->lro_arr = mgp->rx_done.lro_desc; + lro_mgr->lro_arr = mgp->ss.rx_done.lro_desc; lro_mgr->get_frag_header = myri10ge_get_frag_header; lro_mgr->max_aggr = myri10ge_lro_max_pkts; lro_mgr->frag_align_pad = 2; if (lro_mgr->max_aggr > MAX_SKB_FRAGS) lro_mgr->max_aggr = MAX_SKB_FRAGS; - napi_enable(&mgp->napi); /* must happen prior to any irq */ + napi_enable(&mgp->ss.napi); /* must happen prior to any irq */ status = myri10ge_send_cmd(mgp, MXGEFW_CMD_ETHERNET_UP, &cmd, 0); if (status) { @@ -1996,8 +2084,8 @@ static int myri10ge_open(struct net_device *dev) goto abort_with_rings; } - mgp->wake_queue = 0; - mgp->stop_queue = 0; + mgp->ss.tx.wake_queue = 0; + mgp->ss.tx.stop_queue = 0; mgp->running = MYRI10GE_ETH_RUNNING; mgp->watchdog_timer.expires = jiffies + myri10ge_watchdog_timeout * HZ; add_timer(&mgp->watchdog_timer); @@ -2005,7 +2093,7 @@ static int myri10ge_open(struct net_device *dev) return 0; abort_with_rings: - myri10ge_free_rings(dev); + myri10ge_free_rings(&mgp->ss); abort_with_irq: myri10ge_free_irq(mgp); @@ -2017,21 +2105,19 @@ abort_with_nothing: static int myri10ge_close(struct net_device *dev) { - struct myri10ge_priv *mgp; + struct myri10ge_priv *mgp = netdev_priv(dev); struct myri10ge_cmd cmd; int status, old_down_cnt; - mgp = netdev_priv(dev); - if (mgp->running != MYRI10GE_ETH_RUNNING) return 0; - if (mgp->tx.req_bytes == NULL) + if (mgp->ss.tx.req_bytes == NULL) return 0; del_timer_sync(&mgp->watchdog_timer); mgp->running = MYRI10GE_ETH_STOPPING; - napi_disable(&mgp->napi); + napi_disable(&mgp->ss.napi); netif_carrier_off(dev); netif_stop_queue(dev); old_down_cnt = mgp->down_cnt; @@ -2047,7 +2133,7 @@ static int myri10ge_close(struct net_device *dev) netif_tx_disable(dev); myri10ge_free_irq(mgp); - myri10ge_free_rings(dev); + myri10ge_free_rings(&mgp->ss); mgp->running = MYRI10GE_ETH_STOPPED; return 0; @@ -2143,7 +2229,7 @@ myri10ge_submit_req_wc(struct myri10ge_tx_buf *tx, /* * Transmit a packet. We need to split the packet so that a single - * segment does not cross myri10ge->tx.boundary, so this makes segment + * segment does not cross myri10ge->tx_boundary, so this makes segment * counting tricky. So rather than try to count segments up front, we * just give up if there are too few segments to hold a reasonably * fragmented packet currently available. If we run @@ -2154,8 +2240,9 @@ myri10ge_submit_req_wc(struct myri10ge_tx_buf *tx, static int myri10ge_xmit(struct sk_buff *skb, struct net_device *dev) { struct myri10ge_priv *mgp = netdev_priv(dev); + struct myri10ge_slice_state *ss; struct mcp_kreq_ether_send *req; - struct myri10ge_tx_buf *tx = &mgp->tx; + struct myri10ge_tx_buf *tx; struct skb_frag_struct *frag; dma_addr_t bus; u32 low; @@ -2166,6 +2253,9 @@ static int myri10ge_xmit(struct sk_buff *skb, struct net_device *dev) int cum_len, seglen, boundary, rdma_count; u8 flags, odd_flag; + /* always transmit through slot 0 */ + ss = &mgp->ss; + tx = &ss->tx; again: req = tx->req_list; avail = tx->mask - 1 - (tx->req - tx->done); @@ -2180,7 +2270,7 @@ again: if ((unlikely(avail < max_segments))) { /* we are out of transmit resources */ - mgp->stop_queue++; + tx->stop_queue++; netif_stop_queue(dev); return 1; } @@ -2242,7 +2332,7 @@ again: if (skb_padto(skb, ETH_ZLEN)) { /* The packet is gone, so we must * return 0 */ - mgp->stats.tx_dropped += 1; + ss->stats.tx_dropped += 1; return 0; } /* adjust the len to account for the zero pad @@ -2284,7 +2374,7 @@ again: while (1) { /* Break the SKB or Fragment up into pieces which - * do not cross mgp->tx.boundary */ + * do not cross mgp->tx_boundary */ low = MYRI10GE_LOWPART_TO_U32(bus); high_swapped = htonl(MYRI10GE_HIGHPART_TO_U32(bus)); while (len) { @@ -2294,7 +2384,8 @@ again: if (unlikely(count == max_segments)) goto abort_linearize; - boundary = (low + tx->boundary) & ~(tx->boundary - 1); + boundary = + (low + mgp->tx_boundary) & ~(mgp->tx_boundary - 1); seglen = boundary - low; if (seglen > len) seglen = len; @@ -2378,7 +2469,7 @@ again: myri10ge_submit_req_wc(tx, tx->req_list, count); tx->pkt_start++; if ((avail - count) < MXGEFW_MAX_SEND_DESC) { - mgp->stop_queue++; + tx->stop_queue++; netif_stop_queue(dev); } dev->trans_start = jiffies; @@ -2420,12 +2511,12 @@ abort_linearize: if (skb_linearize(skb)) goto drop; - mgp->tx_linearized++; + tx->linearized++; goto again; drop: dev_kfree_skb_any(skb); - mgp->stats.tx_dropped += 1; + ss->stats.tx_dropped += 1; return 0; } @@ -2433,7 +2524,7 @@ drop: static int myri10ge_sw_tso(struct sk_buff *skb, struct net_device *dev) { struct sk_buff *segs, *curr; - struct myri10ge_priv *mgp = dev->priv; + struct myri10ge_priv *mgp = netdev_priv(dev); int status; segs = skb_gso_segment(skb, dev->features & ~NETIF_F_TSO6); @@ -2473,14 +2564,13 @@ static struct net_device_stats *myri10ge_get_stats(struct net_device *dev) static void myri10ge_set_multicast_list(struct net_device *dev) { + struct myri10ge_priv *mgp = netdev_priv(dev); struct myri10ge_cmd cmd; - struct myri10ge_priv *mgp; struct dev_mc_list *mc_list; __be32 data[2] = { 0, 0 }; int err; DECLARE_MAC_BUF(mac); - mgp = netdev_priv(dev); /* can be called from atomic contexts, * pass 1 to force atomicity in myri10ge_send_cmd() */ myri10ge_change_promisc(mgp, dev->flags & IFF_PROMISC, 1); @@ -2616,13 +2706,14 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp) ext_type = (val & PCI_EXP_FLAGS_TYPE) >> 4; if (ext_type != PCI_EXP_TYPE_ROOT_PORT) { if (myri10ge_ecrc_enable > 1) { - struct pci_dev *old_bridge = bridge; + struct pci_dev *prev_bridge, *old_bridge = bridge; /* Walk the hierarchy up to the root port * where ECRC has to be enabled */ do { + prev_bridge = bridge; bridge = bridge->bus->self; - if (!bridge) { + if (!bridge || prev_bridge == bridge) { dev_err(dev, "Failed to find root port" " to force ECRC\n"); @@ -2681,9 +2772,9 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp) * already been enabled, then it must use a firmware image which works * around unaligned completion packets (myri10ge_ethp_z8e.dat), and it * should also ensure that it never gives the device a Read-DMA which is - * larger than 2KB by setting the tx.boundary to 2KB. If ECRC is + * larger than 2KB by setting the tx_boundary to 2KB. If ECRC is * enabled, then the driver should use the aligned (myri10ge_eth_z8e.dat) - * firmware image, and set tx.boundary to 4KB. + * firmware image, and set tx_boundary to 4KB. */ static void myri10ge_firmware_probe(struct myri10ge_priv *mgp) @@ -2692,7 +2783,7 @@ static void myri10ge_firmware_probe(struct myri10ge_priv *mgp) struct device *dev = &pdev->dev; int status; - mgp->tx.boundary = 4096; + mgp->tx_boundary = 4096; /* * Verify the max read request size was set to 4KB * before trying the test with 4KB. @@ -2704,7 +2795,7 @@ static void myri10ge_firmware_probe(struct myri10ge_priv *mgp) } if (status != 4096) { dev_warn(dev, "Max Read Request size != 4096 (%d)\n", status); - mgp->tx.boundary = 2048; + mgp->tx_boundary = 2048; } /* * load the optimized firmware (which assumes aligned PCIe @@ -2737,7 +2828,7 @@ static void myri10ge_firmware_probe(struct myri10ge_priv *mgp) "Please install up to date fw\n"); abort: /* fall back to using the unaligned firmware */ - mgp->tx.boundary = 2048; + mgp->tx_boundary = 2048; mgp->fw_name = myri10ge_fw_unaligned; } @@ -2758,7 +2849,7 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp) if (link_width < 8) { dev_info(&mgp->pdev->dev, "PCIE x%d Link\n", link_width); - mgp->tx.boundary = 4096; + mgp->tx_boundary = 4096; mgp->fw_name = myri10ge_fw_aligned; } else { myri10ge_firmware_probe(mgp); @@ -2767,12 +2858,12 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp) if (myri10ge_force_firmware == 1) { dev_info(&mgp->pdev->dev, "Assuming aligned completions (forced)\n"); - mgp->tx.boundary = 4096; + mgp->tx_boundary = 4096; mgp->fw_name = myri10ge_fw_aligned; } else { dev_info(&mgp->pdev->dev, "Assuming unaligned completions (forced)\n"); - mgp->tx.boundary = 2048; + mgp->tx_boundary = 2048; mgp->fw_name = myri10ge_fw_unaligned; } } @@ -2889,6 +2980,7 @@ static void myri10ge_watchdog(struct work_struct *work) { struct myri10ge_priv *mgp = container_of(work, struct myri10ge_priv, watchdog_work); + struct myri10ge_tx_buf *tx; u32 reboot; int status; u16 cmd, vendor; @@ -2938,15 +3030,16 @@ static void myri10ge_watchdog(struct work_struct *work) printk(KERN_ERR "myri10ge: %s: device timeout, resetting\n", mgp->dev->name); + tx = &mgp->ss.tx; printk(KERN_INFO "myri10ge: %s: %d %d %d %d %d\n", - mgp->dev->name, mgp->tx.req, mgp->tx.done, - mgp->tx.pkt_start, mgp->tx.pkt_done, - (int)ntohl(mgp->fw_stats->send_done_count)); + mgp->dev->name, tx->req, tx->done, + tx->pkt_start, tx->pkt_done, + (int)ntohl(mgp->ss.fw_stats->send_done_count)); msleep(2000); printk(KERN_INFO "myri10ge: %s: %d %d %d %d %d\n", - mgp->dev->name, mgp->tx.req, mgp->tx.done, - mgp->tx.pkt_start, mgp->tx.pkt_done, - (int)ntohl(mgp->fw_stats->send_done_count)); + mgp->dev->name, tx->req, tx->done, + tx->pkt_start, tx->pkt_done, + (int)ntohl(mgp->ss.fw_stats->send_done_count)); } rtnl_lock(); myri10ge_close(mgp->dev); @@ -2969,28 +3062,31 @@ static void myri10ge_watchdog(struct work_struct *work) static void myri10ge_watchdog_timer(unsigned long arg) { struct myri10ge_priv *mgp; + struct myri10ge_slice_state *ss; u32 rx_pause_cnt; mgp = (struct myri10ge_priv *)arg; - if (mgp->rx_small.watchdog_needed) { - myri10ge_alloc_rx_pages(mgp, &mgp->rx_small, + rx_pause_cnt = ntohl(mgp->ss.fw_stats->dropped_pause); + + ss = &mgp->ss; + if (ss->rx_small.watchdog_needed) { + myri10ge_alloc_rx_pages(mgp, &ss->rx_small, mgp->small_bytes + MXGEFW_PAD, 1); - if (mgp->rx_small.fill_cnt - mgp->rx_small.cnt >= + if (ss->rx_small.fill_cnt - ss->rx_small.cnt >= myri10ge_fill_thresh) - mgp->rx_small.watchdog_needed = 0; + ss->rx_small.watchdog_needed = 0; } - if (mgp->rx_big.watchdog_needed) { - myri10ge_alloc_rx_pages(mgp, &mgp->rx_big, mgp->big_bytes, 1); - if (mgp->rx_big.fill_cnt - mgp->rx_big.cnt >= + if (ss->rx_big.watchdog_needed) { + myri10ge_alloc_rx_pages(mgp, &ss->rx_big, mgp->big_bytes, 1); + if (ss->rx_big.fill_cnt - ss->rx_big.cnt >= myri10ge_fill_thresh) - mgp->rx_big.watchdog_needed = 0; + ss->rx_big.watchdog_needed = 0; } - rx_pause_cnt = ntohl(mgp->fw_stats->dropped_pause); - if (mgp->tx.req != mgp->tx.done && - mgp->tx.done == mgp->watchdog_tx_done && - mgp->watchdog_tx_req != mgp->watchdog_tx_done) { + if (ss->tx.req != ss->tx.done && + ss->tx.done == ss->watchdog_tx_done && + ss->watchdog_tx_req != ss->watchdog_tx_done) { /* nic seems like it might be stuck.. */ if (rx_pause_cnt != mgp->watchdog_pause) { if (net_ratelimit()) @@ -3005,8 +3101,8 @@ static void myri10ge_watchdog_timer(unsigned long arg) /* rearm timer */ mod_timer(&mgp->watchdog_timer, jiffies + myri10ge_watchdog_timeout * HZ); - mgp->watchdog_tx_done = mgp->tx.done; - mgp->watchdog_tx_req = mgp->tx.req; + ss->watchdog_tx_done = ss->tx.done; + ss->watchdog_tx_req = ss->tx.req; mgp->watchdog_pause = rx_pause_cnt; } @@ -3030,7 +3126,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) mgp = netdev_priv(netdev); mgp->dev = netdev; - netif_napi_add(netdev, &mgp->napi, myri10ge_poll, myri10ge_napi_weight); + netif_napi_add(netdev, &mgp->ss.napi, myri10ge_poll, myri10ge_napi_weight); mgp->pdev = pdev; mgp->csum_flag = MXGEFW_FLAGS_CKSUM; mgp->pause = myri10ge_flow_control; @@ -3076,9 +3172,9 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (mgp->cmd == NULL) goto abort_with_netdev; - mgp->fw_stats = dma_alloc_coherent(&pdev->dev, sizeof(*mgp->fw_stats), - &mgp->fw_stats_bus, GFP_KERNEL); - if (mgp->fw_stats == NULL) + mgp->ss.fw_stats = dma_alloc_coherent(&pdev->dev, sizeof(*mgp->ss.fw_stats), + &mgp->ss.fw_stats_bus, GFP_KERNEL); + if (mgp->ss.fw_stats == NULL) goto abort_with_cmd; mgp->board_span = pci_resource_len(pdev, 0); @@ -3118,12 +3214,12 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) netdev->dev_addr[i] = mgp->mac_addr[i]; /* allocate rx done ring */ - bytes = myri10ge_max_intr_slots * sizeof(*mgp->rx_done.entry); - mgp->rx_done.entry = dma_alloc_coherent(&pdev->dev, bytes, - &mgp->rx_done.bus, GFP_KERNEL); - if (mgp->rx_done.entry == NULL) + bytes = mgp->max_intr_slots * sizeof(*mgp->ss.rx_done.entry); + mgp->ss.rx_done.entry = dma_alloc_coherent(&pdev->dev, bytes, + &mgp->ss.rx_done.bus, GFP_KERNEL); + if (mgp->ss.rx_done.entry == NULL) goto abort_with_ioremap; - memset(mgp->rx_done.entry, 0, bytes); + memset(mgp->ss.rx_done.entry, 0, bytes); myri10ge_select_firmware(mgp); @@ -3183,7 +3279,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } dev_info(dev, "%s IRQ %d, tx bndry %d, fw %s, WC %s\n", (mgp->msi_enabled ? "MSI" : "xPIC"), - netdev->irq, mgp->tx.boundary, mgp->fw_name, + netdev->irq, mgp->tx_boundary, mgp->fw_name, (mgp->wc_enabled ? "Enabled" : "Disabled")); return 0; @@ -3195,9 +3291,9 @@ abort_with_firmware: myri10ge_dummy_rdma(mgp, 0); abort_with_rx_done: - bytes = myri10ge_max_intr_slots * sizeof(*mgp->rx_done.entry); + bytes = mgp->max_intr_slots * sizeof(*mgp->ss.rx_done.entry); dma_free_coherent(&pdev->dev, bytes, - mgp->rx_done.entry, mgp->rx_done.bus); + mgp->ss.rx_done.entry, mgp->ss.rx_done.bus); abort_with_ioremap: iounmap(mgp->sram); @@ -3207,8 +3303,8 @@ abort_with_wc: if (mgp->mtrr >= 0) mtrr_del(mgp->mtrr, mgp->iomem_base, mgp->board_span); #endif - dma_free_coherent(&pdev->dev, sizeof(*mgp->fw_stats), - mgp->fw_stats, mgp->fw_stats_bus); + dma_free_coherent(&pdev->dev, sizeof(*mgp->ss.fw_stats), + mgp->ss.fw_stats, mgp->ss.fw_stats_bus); abort_with_cmd: dma_free_coherent(&pdev->dev, sizeof(*mgp->cmd), @@ -3246,9 +3342,9 @@ static void myri10ge_remove(struct pci_dev *pdev) /* avoid a memory leak */ pci_restore_state(pdev); - bytes = myri10ge_max_intr_slots * sizeof(*mgp->rx_done.entry); + bytes = mgp->max_intr_slots * sizeof(*mgp->ss.rx_done.entry); dma_free_coherent(&pdev->dev, bytes, - mgp->rx_done.entry, mgp->rx_done.bus); + mgp->ss.rx_done.entry, mgp->ss.rx_done.bus); iounmap(mgp->sram); @@ -3256,8 +3352,8 @@ static void myri10ge_remove(struct pci_dev *pdev) if (mgp->mtrr >= 0) mtrr_del(mgp->mtrr, mgp->iomem_base, mgp->board_span); #endif - dma_free_coherent(&pdev->dev, sizeof(*mgp->fw_stats), - mgp->fw_stats, mgp->fw_stats_bus); + dma_free_coherent(&pdev->dev, sizeof(*mgp->ss.fw_stats), + mgp->ss.fw_stats, mgp->ss.fw_stats_bus); dma_free_coherent(&pdev->dev, sizeof(*mgp->cmd), mgp->cmd, mgp->cmd_bus); diff --git a/drivers/net/myri10ge/myri10ge_mcp.h b/drivers/net/myri10ge/myri10ge_mcp.h index 58e57178c563f6129b4faf80d50e14408a0fe265..fdbeeee073727240a4df96f60b7837f8efc8f0d1 100644 --- a/drivers/net/myri10ge/myri10ge_mcp.h +++ b/drivers/net/myri10ge/myri10ge_mcp.h @@ -10,7 +10,7 @@ struct mcp_dma_addr { __be32 low; }; -/* 4 Bytes. 8 Bytes for NDIS drivers. */ +/* 4 Bytes */ struct mcp_slot { __sum16 checksum; __be16 length; @@ -144,6 +144,7 @@ enum myri10ge_mcp_cmd_type { * a power of 2 number of entries. */ MXGEFW_CMD_SET_INTRQ_SIZE, /* in bytes */ +#define MXGEFW_CMD_SET_INTRQ_SIZE_FLAG_NO_STRICT_SIZE_CHECK (1 << 31) /* command to bring ethernet interface up. Above parameters * (plus mtu & mac address) must have been exchanged prior @@ -221,10 +222,14 @@ enum myri10ge_mcp_cmd_type { MXGEFW_CMD_GET_MAX_RSS_QUEUES, MXGEFW_CMD_ENABLE_RSS_QUEUES, /* data0 = number of slices n (0, 1, ..., n-1) to enable - * data1 = interrupt mode. 0=share one INTx/MSI, 1=use one MSI-X per queue. + * data1 = interrupt mode. + * 0=share one INTx/MSI, 1=use one MSI-X per queue. * If all queues share one interrupt, the driver must have set * RSS_SHARED_INTERRUPT_DMA before enabling queues. */ +#define MXGEFW_SLICE_INTR_MODE_SHARED 0 +#define MXGEFW_SLICE_INTR_MODE_ONE_PER_SLICE 1 + MXGEFW_CMD_GET_RSS_SHARED_INTERRUPT_MASK_OFFSET, MXGEFW_CMD_SET_RSS_SHARED_INTERRUPT_DMA, /* data0, data1 = bus address lsw, msw */ @@ -241,10 +246,14 @@ enum myri10ge_mcp_cmd_type { * 0: disable rss. nic does not distribute receive packets. * 1: enable rss. nic distributes receive packets among queues. * data1 = hash type - * 1: IPV4 - * 2: TCP_IPV4 - * 3: IPV4 | TCP_IPV4 + * 1: IPV4 (required by RSS) + * 2: TCP_IPV4 (required by RSS) + * 3: IPV4 | TCP_IPV4 (required by RSS) + * 4: source port */ +#define MXGEFW_RSS_HASH_TYPE_IPV4 0x1 +#define MXGEFW_RSS_HASH_TYPE_TCP_IPV4 0x2 +#define MXGEFW_RSS_HASH_TYPE_SRC_PORT 0x4 MXGEFW_CMD_GET_MAX_TSO6_HDR_SIZE, /* Return data = the max. size of the entire headers of a IPv6 TSO packet. @@ -260,6 +269,8 @@ enum myri10ge_mcp_cmd_type { * 0: Linux/FreeBSD style (NIC default) * 1: NDIS/NetBSD style */ +#define MXGEFW_TSO_MODE_LINUX 0 +#define MXGEFW_TSO_MODE_NDIS 1 MXGEFW_CMD_MDIO_READ, /* data0 = dev_addr (PMA/PMD or PCS ...), data1 = register/addr */ @@ -286,6 +297,38 @@ enum myri10ge_mcp_cmd_type { /* Return data = NIC memory offset of mcp_vpump_public_global */ MXGEFW_CMD_RESET_VPUMP, /* Resets the VPUMP state */ + + MXGEFW_CMD_SET_RSS_MCP_SLOT_TYPE, + /* data0 = mcp_slot type to use. + * 0 = the default 4B mcp_slot + * 1 = 8B mcp_slot_8 + */ +#define MXGEFW_RSS_MCP_SLOT_TYPE_MIN 0 +#define MXGEFW_RSS_MCP_SLOT_TYPE_WITH_HASH 1 + + MXGEFW_CMD_SET_THROTTLE_FACTOR, + /* set the throttle factor for ethp_z8e + * data0 = throttle_factor + * throttle_factor = 256 * pcie-raw-speed / tx_speed + * tx_speed = 256 * pcie-raw-speed / throttle_factor + * + * For PCI-E x8: pcie-raw-speed == 16Gb/s + * For PCI-E x4: pcie-raw-speed == 8Gb/s + * + * ex1: throttle_factor == 0x1a0 (416), tx_speed == 1.23GB/s == 9.846 Gb/s + * ex2: throttle_factor == 0x200 (512), tx_speed == 1.0GB/s == 8 Gb/s + * + * with tx_boundary == 2048, max-throttle-factor == 8191 => min-speed == 500Mb/s + * with tx_boundary == 4096, max-throttle-factor == 4095 => min-speed == 1Gb/s + */ + + MXGEFW_CMD_VPUMP_UP, + /* Allocates VPump Connection, Send Request and Zero copy buffer address tables */ + MXGEFW_CMD_GET_VPUMP_CLK, + /* Get the lanai clock */ + + MXGEFW_CMD_GET_DCA_OFFSET, + /* offset of dca control for WDMAs */ }; enum myri10ge_mcp_cmd_status { @@ -302,7 +345,8 @@ enum myri10ge_mcp_cmd_status { MXGEFW_CMD_ERROR_UNALIGNED, MXGEFW_CMD_ERROR_NO_MDIO, MXGEFW_CMD_ERROR_XFP_FAILURE, - MXGEFW_CMD_ERROR_XFP_ABSENT + MXGEFW_CMD_ERROR_XFP_ABSENT, + MXGEFW_CMD_ERROR_BAD_PCIE_LINK }; #define MXGEFW_OLD_IRQ_DATA_LEN 40 diff --git a/drivers/net/myri10ge/myri10ge_mcp_gen_header.h b/drivers/net/myri10ge/myri10ge_mcp_gen_header.h index 16a810dd6d515d4ed7a6f61ceb7b443131c34b9e..07d65c2cbb24dade697c881e307d5f849c4bacc2 100644 --- a/drivers/net/myri10ge/myri10ge_mcp_gen_header.h +++ b/drivers/net/myri10ge/myri10ge_mcp_gen_header.h @@ -1,30 +1,6 @@ #ifndef __MYRI10GE_MCP_GEN_HEADER_H__ #define __MYRI10GE_MCP_GEN_HEADER_H__ -/* this file define a standard header used as a first entry point to - * exchange information between firmware/driver and driver. The - * header structure can be anywhere in the mcp. It will usually be in - * the .data section, because some fields needs to be initialized at - * compile time. - * The 32bit word at offset MX_HEADER_PTR_OFFSET in the mcp must - * contains the location of the header. - * - * Typically a MCP will start with the following: - * .text - * .space 52 ! to help catch MEMORY_INT errors - * bt start ! jump to real code - * nop - * .long _gen_mcp_header - * - * The source will have a definition like: - * - * mcp_gen_header_t gen_mcp_header = { - * .header_length = sizeof(mcp_gen_header_t), - * .mcp_type = MCP_TYPE_XXX, - * .version = "something $Id: mcp_gen_header.h,v 1.2 2006/05/13 10:04:35 bgoglin Exp $", - * .mcp_globals = (unsigned)&Globals - * }; - */ #define MCP_HEADER_PTR_OFFSET 0x3c @@ -32,13 +8,14 @@ #define MCP_TYPE_PCIE 0x70636965 /* "PCIE" pcie-only MCP */ #define MCP_TYPE_ETH 0x45544820 /* "ETH " */ #define MCP_TYPE_MCP0 0x4d435030 /* "MCP0" */ +#define MCP_TYPE_DFLT 0x20202020 /* " " */ struct mcp_gen_header { /* the first 4 fields are filled at compile time */ unsigned header_length; __be32 mcp_type; char version[128]; - unsigned mcp_globals; /* pointer to mcp-type specific structure */ + unsigned mcp_private; /* pointer to mcp-type specific structure */ /* filled by the MCP at run-time */ unsigned sram_size; @@ -53,6 +30,18 @@ struct mcp_gen_header { * * Never remove any field. Keep everything naturally align. */ + + /* Specifies if the running mcp is mcp0, 1, or 2. */ + unsigned char mcp_index; + unsigned char disable_rabbit; + unsigned char unaligned_tlp; + unsigned char pad1; + unsigned counters_addr; + unsigned copy_block_info; /* for small mcps loaded with "lload -d" */ + unsigned short handoff_id_major; /* must be equal */ + unsigned short handoff_id_caps; /* bitfield: new mcp must have superset */ + unsigned msix_table_addr; /* start address of msix table in firmware */ + /* 8 */ }; #endif /* __MYRI10GE_MCP_GEN_HEADER_H__ */ diff --git a/drivers/net/niu.c b/drivers/net/niu.c index 4009c4ce96b4fd609425e8fe3b95d30f38d705a7..918f802fe089d060247bb21e72b8a651fa0ef333 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -1,6 +1,6 @@ /* niu.c: Neptune ethernet driver. * - * Copyright (C) 2007 David S. Miller (davem@davemloft.net) + * Copyright (C) 2007, 2008 David S. Miller (davem@davemloft.net) */ #include @@ -33,8 +33,8 @@ #define DRV_MODULE_NAME "niu" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "0.8" -#define DRV_MODULE_RELDATE "April 24, 2008" +#define DRV_MODULE_VERSION "0.9" +#define DRV_MODULE_RELDATE "May 4, 2008" static char version[] __devinitdata = DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; @@ -865,7 +865,6 @@ static int link_status_1g_serdes(struct niu *np, int *link_up_p) return 0; } - static int link_status_10g_serdes(struct niu *np, int *link_up_p) { unsigned long flags; @@ -900,7 +899,6 @@ static int link_status_10g_serdes(struct niu *np, int *link_up_p) return 0; } - static int link_status_1g_rgmii(struct niu *np, int *link_up_p) { struct niu_link_config *lp = &np->link_config; @@ -957,7 +955,6 @@ out: return err; } - static int bcm8704_reset(struct niu *np) { int err, limit; @@ -1357,8 +1354,6 @@ static int mii_reset(struct niu *np) return 0; } - - static int xcvr_init_1g_rgmii(struct niu *np) { int err; @@ -1419,7 +1414,6 @@ static int xcvr_init_1g_rgmii(struct niu *np) return 0; } - static int mii_init_common(struct niu *np) { struct niu_link_config *lp = &np->link_config; @@ -7008,31 +7002,20 @@ static int __devinit niu_phy_type_prop_decode(struct niu *np, return 0; } -/* niu board models have a trailing dash version incremented - * with HW rev change. Need to ingnore the dash version while - * checking for match - * - * for example, for the 10G card the current vpd.board_model - * is 501-5283-04, of which -04 is the dash version and have - * to be ignored - */ -static int niu_board_model_match(struct niu *np, const char *model) -{ - return !strncmp(np->vpd.board_model, model, strlen(model)); -} - static int niu_pci_vpd_get_nports(struct niu *np) { int ports = 0; - if ((niu_board_model_match(np, NIU_QGC_LP_BM_STR)) || - (niu_board_model_match(np, NIU_QGC_PEM_BM_STR)) || - (niu_board_model_match(np, NIU_ALONSO_BM_STR))) { + if ((!strcmp(np->vpd.model, NIU_QGC_LP_MDL_STR)) || + (!strcmp(np->vpd.model, NIU_QGC_PEM_MDL_STR)) || + (!strcmp(np->vpd.model, NIU_MARAMBA_MDL_STR)) || + (!strcmp(np->vpd.model, NIU_KIMI_MDL_STR)) || + (!strcmp(np->vpd.model, NIU_ALONSO_MDL_STR))) { ports = 4; - } else if ((niu_board_model_match(np, NIU_2XGF_LP_BM_STR)) || - (niu_board_model_match(np, NIU_2XGF_PEM_BM_STR)) || - (niu_board_model_match(np, NIU_FOXXY_BM_STR)) || - (niu_board_model_match(np, NIU_2XGF_MRVL_BM_STR))) { + } else if ((!strcmp(np->vpd.model, NIU_2XGF_LP_MDL_STR)) || + (!strcmp(np->vpd.model, NIU_2XGF_PEM_MDL_STR)) || + (!strcmp(np->vpd.model, NIU_FOXXY_MDL_STR)) || + (!strcmp(np->vpd.model, NIU_2XGF_MRVL_MDL_STR))) { ports = 2; } @@ -7053,8 +7036,8 @@ static void __devinit niu_pci_vpd_validate(struct niu *np) return; } - if (!strcmp(np->vpd.model, "SUNW,CP3220") || - !strcmp(np->vpd.model, "SUNW,CP3260")) { + if (!strcmp(np->vpd.model, NIU_ALONSO_MDL_STR) || + !strcmp(np->vpd.model, NIU_KIMI_MDL_STR)) { np->flags |= NIU_FLAGS_10G; np->flags &= ~NIU_FLAGS_FIBER; np->flags |= NIU_FLAGS_XCVR_SERDES; @@ -7065,7 +7048,7 @@ static void __devinit niu_pci_vpd_validate(struct niu *np) } if (np->flags & NIU_FLAGS_10G) np->mac_xcvr = MAC_XCVR_XPCS; - } else if (niu_board_model_match(np, NIU_FOXXY_BM_STR)) { + } else if (!strcmp(np->vpd.model, NIU_FOXXY_MDL_STR)) { np->flags |= (NIU_FLAGS_10G | NIU_FLAGS_FIBER | NIU_FLAGS_HOTPLUG_PHY); } else if (niu_phy_type_prop_decode(np, np->vpd.phy_type)) { @@ -7264,8 +7247,11 @@ static int __devinit niu_get_and_validate_port(struct niu *np) parent->num_ports = nr64(ESPC_NUM_PORTS_MACS) & ESPC_NUM_PORTS_MACS_VAL; + /* All of the current probing methods fail on + * Maramba on-board parts. + */ if (!parent->num_ports) - return -ENODEV; + parent->num_ports = 4; } } } @@ -7538,8 +7524,8 @@ static int __devinit walk_phys(struct niu *np, struct niu_parent *parent) u32 val; int err; - if (!strcmp(np->vpd.model, "SUNW,CP3220") || - !strcmp(np->vpd.model, "SUNW,CP3260")) { + if (!strcmp(np->vpd.model, NIU_ALONSO_MDL_STR) || + !strcmp(np->vpd.model, NIU_KIMI_MDL_STR)) { num_10g = 0; num_1g = 2; parent->plat_type = PLAT_TYPE_ATCA_CP3220; @@ -7548,7 +7534,7 @@ static int __devinit walk_phys(struct niu *np, struct niu_parent *parent) phy_encode(PORT_TYPE_1G, 1) | phy_encode(PORT_TYPE_1G, 2) | phy_encode(PORT_TYPE_1G, 3)); - } else if (niu_board_model_match(np, NIU_FOXXY_BM_STR)) { + } else if (!strcmp(np->vpd.model, NIU_FOXXY_MDL_STR)) { num_10g = 2; num_1g = 0; parent->num_ports = 2; @@ -7943,6 +7929,7 @@ static int __devinit niu_get_of_props(struct niu *np) struct device_node *dp; const char *phy_type; const u8 *mac_addr; + const char *model; int prop_len; if (np->parent->plat_type == PLAT_TYPE_NIU) @@ -7997,6 +7984,11 @@ static int __devinit niu_get_of_props(struct niu *np) memcpy(dev->dev_addr, dev->perm_addr, dev->addr_len); + model = of_get_property(dp, "model", &prop_len); + + if (model) + strcpy(np->vpd.model, model); + return 0; #else return -EINVAL; diff --git a/drivers/net/niu.h b/drivers/net/niu.h index 97ffbe137bcbaa20fbea8ae4eeedf54c9b9ac7a8..12fd570b9423905bb410da6f7c23b7490d834216 100644 --- a/drivers/net/niu.h +++ b/drivers/net/niu.h @@ -2946,6 +2946,15 @@ struct rx_ring_info { #define NIU_ALONSO_BM_STR "373-0202" #define NIU_FOXXY_BM_STR "501-7961" #define NIU_2XGF_MRVL_BM_STR "SK-6E82" +#define NIU_QGC_LP_MDL_STR "SUNW,pcie-qgc" +#define NIU_2XGF_LP_MDL_STR "SUNW,pcie-2xgf" +#define NIU_QGC_PEM_MDL_STR "SUNW,pcie-qgc-pem" +#define NIU_2XGF_PEM_MDL_STR "SUNW,pcie-2xgf-pem" +#define NIU_ALONSO_MDL_STR "SUNW,CP3220" +#define NIU_KIMI_MDL_STR "SUNW,CP3260" +#define NIU_MARAMBA_MDL_STR "SUNW,pcie-neptune" +#define NIU_FOXXY_MDL_STR "SUNW,pcie-rfem" +#define NIU_2XGF_MRVL_MDL_STR "SysKonnect,pcie-2xgf" #define NIU_VPD_MIN_MAJOR 3 #define NIU_VPD_MIN_MINOR 4 diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index 4eb322e5273dab2df2102db0c55eec8fff6e815f..a1c454dbc164b2c75d07f3b05ca9ad527c860cfd 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c @@ -22,12 +22,8 @@ *************************************************************************/ #define DRV_NAME "pcnet32" -#ifdef CONFIG_PCNET32_NAPI -#define DRV_VERSION "1.34-NAPI" -#else -#define DRV_VERSION "1.34" -#endif -#define DRV_RELDATE "14.Aug.2007" +#define DRV_VERSION "1.35" +#define DRV_RELDATE "21.Apr.2008" #define PFX DRV_NAME ": " static const char *const version = @@ -445,30 +441,24 @@ static struct pcnet32_access pcnet32_dwio = { static void pcnet32_netif_stop(struct net_device *dev) { -#ifdef CONFIG_PCNET32_NAPI struct pcnet32_private *lp = netdev_priv(dev); -#endif + dev->trans_start = jiffies; -#ifdef CONFIG_PCNET32_NAPI napi_disable(&lp->napi); -#endif netif_tx_disable(dev); } static void pcnet32_netif_start(struct net_device *dev) { -#ifdef CONFIG_PCNET32_NAPI struct pcnet32_private *lp = netdev_priv(dev); ulong ioaddr = dev->base_addr; u16 val; -#endif + netif_wake_queue(dev); -#ifdef CONFIG_PCNET32_NAPI val = lp->a.read_csr(ioaddr, CSR3); val &= 0x00ff; lp->a.write_csr(ioaddr, CSR3, val); napi_enable(&lp->napi); -#endif } /* @@ -911,11 +901,7 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1) rc = 1; /* default to fail */ if (netif_running(dev)) -#ifdef CONFIG_PCNET32_NAPI pcnet32_netif_stop(dev); -#else - pcnet32_close(dev); -#endif spin_lock_irqsave(&lp->lock, flags); lp->a.write_csr(ioaddr, CSR0, CSR0_STOP); /* stop the chip */ @@ -1046,7 +1032,6 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1) x = a->read_bcr(ioaddr, 32); /* reset internal loopback */ a->write_bcr(ioaddr, 32, (x & ~0x0002)); -#ifdef CONFIG_PCNET32_NAPI if (netif_running(dev)) { pcnet32_netif_start(dev); pcnet32_restart(dev, CSR0_NORMAL); @@ -1055,16 +1040,6 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1) lp->a.write_bcr(ioaddr, 20, 4); /* return to 16bit mode */ } spin_unlock_irqrestore(&lp->lock, flags); -#else - if (netif_running(dev)) { - spin_unlock_irqrestore(&lp->lock, flags); - pcnet32_open(dev); - } else { - pcnet32_purge_rx_ring(dev); - lp->a.write_bcr(ioaddr, 20, 4); /* return to 16bit mode */ - spin_unlock_irqrestore(&lp->lock, flags); - } -#endif return (rc); } /* end pcnet32_loopback_test */ @@ -1270,11 +1245,7 @@ static void pcnet32_rx_entry(struct net_device *dev, } dev->stats.rx_bytes += skb->len; skb->protocol = eth_type_trans(skb, dev); -#ifdef CONFIG_PCNET32_NAPI netif_receive_skb(skb); -#else - netif_rx(skb); -#endif dev->last_rx = jiffies; dev->stats.rx_packets++; return; @@ -1403,7 +1374,6 @@ static int pcnet32_tx(struct net_device *dev) return must_restart; } -#ifdef CONFIG_PCNET32_NAPI static int pcnet32_poll(struct napi_struct *napi, int budget) { struct pcnet32_private *lp = container_of(napi, struct pcnet32_private, napi); @@ -1442,7 +1412,6 @@ static int pcnet32_poll(struct napi_struct *napi, int budget) } return work_done; } -#endif #define PCNET32_REGS_PER_PHY 32 #define PCNET32_MAX_PHYS 32 @@ -1864,9 +1833,7 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev) /* napi.weight is used in both the napi and non-napi cases */ lp->napi.weight = lp->rx_ring_size / 2; -#ifdef CONFIG_PCNET32_NAPI netif_napi_add(dev, &lp->napi, pcnet32_poll, lp->rx_ring_size / 2); -#endif if (fdx && !(lp->options & PCNET32_PORT_ASEL) && ((cards_found >= MAX_UNITS) || full_duplex[cards_found])) @@ -2297,9 +2264,7 @@ static int pcnet32_open(struct net_device *dev) goto err_free_ring; } -#ifdef CONFIG_PCNET32_NAPI napi_enable(&lp->napi); -#endif /* Re-initialize the PCNET32, and start it when done. */ lp->a.write_csr(ioaddr, 1, (lp->init_dma_addr & 0xffff)); @@ -2623,7 +2588,6 @@ pcnet32_interrupt(int irq, void *dev_id) dev->name, csr0); /* unlike for the lance, there is no restart needed */ } -#ifdef CONFIG_PCNET32_NAPI if (netif_rx_schedule_prep(dev, &lp->napi)) { u16 val; /* set interrupt masks */ @@ -2634,24 +2598,9 @@ pcnet32_interrupt(int irq, void *dev_id) __netif_rx_schedule(dev, &lp->napi); break; } -#else - pcnet32_rx(dev, lp->napi.weight); - if (pcnet32_tx(dev)) { - /* reset the chip to clear the error condition, then restart */ - lp->a.reset(ioaddr); - lp->a.write_csr(ioaddr, CSR4, 0x0915); /* auto tx pad */ - pcnet32_restart(dev, CSR0_START); - netif_wake_queue(dev); - } -#endif csr0 = lp->a.read_csr(ioaddr, CSR0); } -#ifndef CONFIG_PCNET32_NAPI - /* Set interrupt enable. */ - lp->a.write_csr(ioaddr, CSR0, CSR0_INTEN); -#endif - if (netif_msg_intr(lp)) printk(KERN_DEBUG "%s: exiting interrupt, csr0=%#4.4x.\n", dev->name, lp->a.read_csr(ioaddr, CSR0)); @@ -2670,9 +2619,7 @@ static int pcnet32_close(struct net_device *dev) del_timer_sync(&lp->watchdog_timer); netif_stop_queue(dev); -#ifdef CONFIG_PCNET32_NAPI napi_disable(&lp->napi); -#endif spin_lock_irqsave(&lp->lock, flags); diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 3c18bb594957a3e2e0320274ff88897189d8b594..45cc2914d3475d1f12db6749890158087f7ab6ca 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -547,7 +547,7 @@ static void phy_force_reduction(struct phy_device *phydev) * Must not be called from interrupt context, or while the * phydev->lock is held. */ -void phy_error(struct phy_device *phydev) +static void phy_error(struct phy_device *phydev) { mutex_lock(&phydev->lock); phydev->state = PHY_HALTED; diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index d3207c0da89561eb345b1d0873eb19b5a3695438..1f4ca2b54a73370213d1ce162c5c048e00bfc732 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -2458,6 +2458,7 @@ ppp_create_interface(int unit, int *retp) out3: atomic_dec(&ppp_unit_count); + unregister_netdev(dev); out2: mutex_unlock(&all_ppp_mutex); free_netdev(dev); diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c index 244d7830c92aac88486981f7ec52b3d3b141631f..79359919335b466d5408e82e33c6d4eae452097e 100644 --- a/drivers/net/pppol2tp.c +++ b/drivers/net/pppol2tp.c @@ -1621,9 +1621,16 @@ out_no_ppp: end: release_sock(sk); - if (error != 0) - PRINTK(session ? session->debug : -1, PPPOL2TP_MSG_CONTROL, KERN_WARNING, - "%s: connect failed: %d\n", session->name, error); + if (error != 0) { + if (session) + PRINTK(session->debug, + PPPOL2TP_MSG_CONTROL, KERN_WARNING, + "%s: connect failed: %d\n", + session->name, error); + else + PRINTK(-1, PPPOL2TP_MSG_CONTROL, KERN_WARNING, + "connect failed: %d\n", error); + } return error; } diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c index 0d32123085e98a92f06f0e7e8b20f1f04f0048b9..1dae1f2ed813e6dc2ebdf818d9e9ef6084422dfc 100644 --- a/drivers/net/ps3_gelic_wireless.c +++ b/drivers/net/ps3_gelic_wireless.c @@ -2474,6 +2474,8 @@ static void gelic_wl_free(struct gelic_wl_info *wl) pr_debug("%s: <-\n", __func__); + free_page((unsigned long)wl->buf); + pr_debug("%s: destroy queues\n", __func__); destroy_workqueue(wl->eurus_cmd_queue); destroy_workqueue(wl->event_queue); diff --git a/drivers/net/sfc/Makefile b/drivers/net/sfc/Makefile index 0f023447eafd769ba4df26679ab3baa98a35dada..1d2daeec7ac11f5a0ba77376667be986fe5a5f95 100644 --- a/drivers/net/sfc/Makefile +++ b/drivers/net/sfc/Makefile @@ -1,5 +1,5 @@ sfc-y += efx.o falcon.o tx.o rx.o falcon_xmac.o \ - i2c-direct.o ethtool.o xfp_phy.o mdio_10g.o \ - tenxpress.o boards.o sfe4001.o + i2c-direct.o selftest.o ethtool.o xfp_phy.o \ + mdio_10g.o tenxpress.o boards.o sfe4001.o obj-$(CONFIG_SFC) += sfc.o diff --git a/drivers/net/sfc/boards.h b/drivers/net/sfc/boards.h index f56341d428e136bc67b6f665ad444f77055aacfe..695764dc2e644a23e6c1f7071662e747348eacac 100644 --- a/drivers/net/sfc/boards.h +++ b/drivers/net/sfc/boards.h @@ -22,5 +22,7 @@ enum efx_board_type { extern int efx_set_board_info(struct efx_nic *efx, u16 revision_info); extern int sfe4001_poweron(struct efx_nic *efx); extern void sfe4001_poweroff(struct efx_nic *efx); +/* Are we putting the PHY into flash config mode */ +extern unsigned int sfe4001_phy_flash_cfg; #endif diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 59edcf793c19253c4be6d5bceeae730327d87c78..418f2e53a95b6709df9a4ce2d3328902c22ba3d4 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -1873,6 +1873,7 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type, tx_queue->queue = i; tx_queue->buffer = NULL; tx_queue->channel = &efx->channel[0]; /* for safety */ + tx_queue->tso_headers_free = NULL; } for (i = 0; i < EFX_MAX_RX_QUEUES; i++) { rx_queue = &efx->rx_queue[i]; @@ -2071,7 +2072,8 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev, net_dev = alloc_etherdev(sizeof(*efx)); if (!net_dev) return -ENOMEM; - net_dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_HIGHDMA; + net_dev->features |= (NETIF_F_IP_CSUM | NETIF_F_SG | + NETIF_F_HIGHDMA | NETIF_F_TSO); if (lro) net_dev->features |= NETIF_F_LRO; efx = net_dev->priv; diff --git a/drivers/net/sfc/enum.h b/drivers/net/sfc/enum.h index 43663a4619da26b77b55a655c3159a046754330c..c53290d08e2b7ae0c56f9ec21705ada1f799611f 100644 --- a/drivers/net/sfc/enum.h +++ b/drivers/net/sfc/enum.h @@ -10,6 +10,55 @@ #ifndef EFX_ENUM_H #define EFX_ENUM_H +/** + * enum efx_loopback_mode - loopback modes + * @LOOPBACK_NONE: no loopback + * @LOOPBACK_XGMII: loopback within MAC at XGMII level + * @LOOPBACK_XGXS: loopback within MAC at XGXS level + * @LOOPBACK_XAUI: loopback within MAC at XAUI level + * @LOOPBACK_PHYXS: loopback within PHY at PHYXS level + * @LOOPBACK_PCS: loopback within PHY at PCS level + * @LOOPBACK_PMAPMD: loopback within PHY at PMAPMD level + * @LOOPBACK_NETWORK: reflecting loopback (even further than furthest!) + */ +/* Please keep in order and up-to-date w.r.t the following two #defines */ +enum efx_loopback_mode { + LOOPBACK_NONE = 0, + LOOPBACK_MAC = 1, + LOOPBACK_XGMII = 2, + LOOPBACK_XGXS = 3, + LOOPBACK_XAUI = 4, + LOOPBACK_PHY = 5, + LOOPBACK_PHYXS = 6, + LOOPBACK_PCS = 7, + LOOPBACK_PMAPMD = 8, + LOOPBACK_NETWORK = 9, + LOOPBACK_MAX +}; + +#define LOOPBACK_TEST_MAX LOOPBACK_PMAPMD + +extern const char *efx_loopback_mode_names[]; +#define LOOPBACK_MODE_NAME(mode) \ + STRING_TABLE_LOOKUP(mode, efx_loopback_mode) +#define LOOPBACK_MODE(efx) \ + LOOPBACK_MODE_NAME(efx->loopback_mode) + +/* These loopbacks occur within the controller */ +#define LOOPBACKS_10G_INTERNAL ((1 << LOOPBACK_XGMII)| \ + (1 << LOOPBACK_XGXS) | \ + (1 << LOOPBACK_XAUI)) + +#define LOOPBACK_MASK(_efx) \ + (1 << (_efx)->loopback_mode) + +#define LOOPBACK_INTERNAL(_efx) \ + ((LOOPBACKS_10G_INTERNAL & LOOPBACK_MASK(_efx)) ? 1 : 0) + +#define LOOPBACK_OUT_OF(_from, _to, _mask) \ + (((LOOPBACK_MASK(_from) & (_mask)) && \ + ((LOOPBACK_MASK(_to) & (_mask)) == 0)) ? 1 : 0) + /*****************************************************************************/ /** diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index ad541badbd98bd94392111ec9c81c23c96d80839..e2c75d10161093614d104603e498b68c6d6987ce 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c @@ -12,12 +12,26 @@ #include #include #include "net_driver.h" +#include "selftest.h" #include "efx.h" #include "ethtool.h" #include "falcon.h" #include "gmii.h" #include "mac.h" +const char *efx_loopback_mode_names[] = { + [LOOPBACK_NONE] = "NONE", + [LOOPBACK_MAC] = "MAC", + [LOOPBACK_XGMII] = "XGMII", + [LOOPBACK_XGXS] = "XGXS", + [LOOPBACK_XAUI] = "XAUI", + [LOOPBACK_PHY] = "PHY", + [LOOPBACK_PHYXS] = "PHY(XS)", + [LOOPBACK_PCS] = "PHY(PCS)", + [LOOPBACK_PMAPMD] = "PHY(PMAPMD)", + [LOOPBACK_NETWORK] = "NETWORK", +}; + static int efx_ethtool_set_tx_csum(struct net_device *net_dev, u32 enable); struct ethtool_string { @@ -217,23 +231,179 @@ static void efx_ethtool_get_drvinfo(struct net_device *net_dev, strlcpy(info->bus_info, pci_name(efx->pci_dev), sizeof(info->bus_info)); } +/** + * efx_fill_test - fill in an individual self-test entry + * @test_index: Index of the test + * @strings: Ethtool strings, or %NULL + * @data: Ethtool test results, or %NULL + * @test: Pointer to test result (used only if data != %NULL) + * @unit_format: Unit name format (e.g. "channel\%d") + * @unit_id: Unit id (e.g. 0 for "channel0") + * @test_format: Test name format (e.g. "loopback.\%s.tx.sent") + * @test_id: Test id (e.g. "PHY" for "loopback.PHY.tx_sent") + * + * Fill in an individual self-test entry. + */ +static void efx_fill_test(unsigned int test_index, + struct ethtool_string *strings, u64 *data, + int *test, const char *unit_format, int unit_id, + const char *test_format, const char *test_id) +{ + struct ethtool_string unit_str, test_str; + + /* Fill data value, if applicable */ + if (data) + data[test_index] = *test; + + /* Fill string, if applicable */ + if (strings) { + snprintf(unit_str.name, sizeof(unit_str.name), + unit_format, unit_id); + snprintf(test_str.name, sizeof(test_str.name), + test_format, test_id); + snprintf(strings[test_index].name, + sizeof(strings[test_index].name), + "%-9s%-17s", unit_str.name, test_str.name); + } +} + +#define EFX_PORT_NAME "port%d", 0 +#define EFX_CHANNEL_NAME(_channel) "channel%d", _channel->channel +#define EFX_TX_QUEUE_NAME(_tx_queue) "txq%d", _tx_queue->queue +#define EFX_RX_QUEUE_NAME(_rx_queue) "rxq%d", _rx_queue->queue +#define EFX_LOOPBACK_NAME(_mode, _counter) \ + "loopback.%s." _counter, LOOPBACK_MODE_NAME(mode) + +/** + * efx_fill_loopback_test - fill in a block of loopback self-test entries + * @efx: Efx NIC + * @lb_tests: Efx loopback self-test results structure + * @mode: Loopback test mode + * @test_index: Starting index of the test + * @strings: Ethtool strings, or %NULL + * @data: Ethtool test results, or %NULL + */ +static int efx_fill_loopback_test(struct efx_nic *efx, + struct efx_loopback_self_tests *lb_tests, + enum efx_loopback_mode mode, + unsigned int test_index, + struct ethtool_string *strings, u64 *data) +{ + struct efx_tx_queue *tx_queue; + + efx_for_each_tx_queue(tx_queue, efx) { + efx_fill_test(test_index++, strings, data, + &lb_tests->tx_sent[tx_queue->queue], + EFX_TX_QUEUE_NAME(tx_queue), + EFX_LOOPBACK_NAME(mode, "tx_sent")); + efx_fill_test(test_index++, strings, data, + &lb_tests->tx_done[tx_queue->queue], + EFX_TX_QUEUE_NAME(tx_queue), + EFX_LOOPBACK_NAME(mode, "tx_done")); + } + efx_fill_test(test_index++, strings, data, + &lb_tests->rx_good, + EFX_PORT_NAME, + EFX_LOOPBACK_NAME(mode, "rx_good")); + efx_fill_test(test_index++, strings, data, + &lb_tests->rx_bad, + EFX_PORT_NAME, + EFX_LOOPBACK_NAME(mode, "rx_bad")); + + return test_index; +} + +/** + * efx_ethtool_fill_self_tests - get self-test details + * @efx: Efx NIC + * @tests: Efx self-test results structure, or %NULL + * @strings: Ethtool strings, or %NULL + * @data: Ethtool test results, or %NULL + */ +static int efx_ethtool_fill_self_tests(struct efx_nic *efx, + struct efx_self_tests *tests, + struct ethtool_string *strings, + u64 *data) +{ + struct efx_channel *channel; + unsigned int n = 0; + enum efx_loopback_mode mode; + + /* Interrupt */ + efx_fill_test(n++, strings, data, &tests->interrupt, + "core", 0, "interrupt", NULL); + + /* Event queues */ + efx_for_each_channel(channel, efx) { + efx_fill_test(n++, strings, data, + &tests->eventq_dma[channel->channel], + EFX_CHANNEL_NAME(channel), + "eventq.dma", NULL); + efx_fill_test(n++, strings, data, + &tests->eventq_int[channel->channel], + EFX_CHANNEL_NAME(channel), + "eventq.int", NULL); + efx_fill_test(n++, strings, data, + &tests->eventq_poll[channel->channel], + EFX_CHANNEL_NAME(channel), + "eventq.poll", NULL); + } + + /* PHY presence */ + efx_fill_test(n++, strings, data, &tests->phy_ok, + EFX_PORT_NAME, "phy_ok", NULL); + + /* Loopback tests */ + efx_fill_test(n++, strings, data, &tests->loopback_speed, + EFX_PORT_NAME, "loopback.speed", NULL); + efx_fill_test(n++, strings, data, &tests->loopback_full_duplex, + EFX_PORT_NAME, "loopback.full_duplex", NULL); + for (mode = LOOPBACK_NONE; mode < LOOPBACK_TEST_MAX; mode++) { + if (!(efx->loopback_modes & (1 << mode))) + continue; + n = efx_fill_loopback_test(efx, + &tests->loopback[mode], mode, n, + strings, data); + } + + return n; +} + static int efx_ethtool_get_stats_count(struct net_device *net_dev) { return EFX_ETHTOOL_NUM_STATS; } +static int efx_ethtool_self_test_count(struct net_device *net_dev) +{ + struct efx_nic *efx = net_dev->priv; + + return efx_ethtool_fill_self_tests(efx, NULL, NULL, NULL); +} + static void efx_ethtool_get_strings(struct net_device *net_dev, u32 string_set, u8 *strings) { + struct efx_nic *efx = net_dev->priv; struct ethtool_string *ethtool_strings = (struct ethtool_string *)strings; int i; - if (string_set == ETH_SS_STATS) + switch (string_set) { + case ETH_SS_STATS: for (i = 0; i < EFX_ETHTOOL_NUM_STATS; i++) strncpy(ethtool_strings[i].name, efx_ethtool_stats[i].name, sizeof(ethtool_strings[i].name)); + break; + case ETH_SS_TEST: + efx_ethtool_fill_self_tests(efx, NULL, + ethtool_strings, NULL); + break; + default: + /* No other string sets */ + break; + } } static void efx_ethtool_get_stats(struct net_device *net_dev, @@ -272,6 +442,22 @@ static void efx_ethtool_get_stats(struct net_device *net_dev, } } +static int efx_ethtool_set_tso(struct net_device *net_dev, u32 enable) +{ + int rc; + + /* Our TSO requires TX checksumming, so force TX checksumming + * on when TSO is enabled. + */ + if (enable) { + rc = efx_ethtool_set_tx_csum(net_dev, 1); + if (rc) + return rc; + } + + return ethtool_op_set_tso(net_dev, enable); +} + static int efx_ethtool_set_tx_csum(struct net_device *net_dev, u32 enable) { struct efx_nic *efx = net_dev->priv; @@ -283,6 +469,15 @@ static int efx_ethtool_set_tx_csum(struct net_device *net_dev, u32 enable) efx_flush_queues(efx); + /* Our TSO requires TX checksumming, so disable TSO when + * checksumming is disabled + */ + if (!enable) { + rc = efx_ethtool_set_tso(net_dev, 0); + if (rc) + return rc; + } + return 0; } @@ -305,6 +500,64 @@ static u32 efx_ethtool_get_rx_csum(struct net_device *net_dev) return efx->rx_checksum_enabled; } +static void efx_ethtool_self_test(struct net_device *net_dev, + struct ethtool_test *test, u64 *data) +{ + struct efx_nic *efx = net_dev->priv; + struct efx_self_tests efx_tests; + int offline, already_up; + int rc; + + ASSERT_RTNL(); + if (efx->state != STATE_RUNNING) { + rc = -EIO; + goto fail1; + } + + /* We need rx buffers and interrupts. */ + already_up = (efx->net_dev->flags & IFF_UP); + if (!already_up) { + rc = dev_open(efx->net_dev); + if (rc) { + EFX_ERR(efx, "failed opening device.\n"); + goto fail2; + } + } + + memset(&efx_tests, 0, sizeof(efx_tests)); + offline = (test->flags & ETH_TEST_FL_OFFLINE); + + /* Perform online self tests first */ + rc = efx_online_test(efx, &efx_tests); + if (rc) + goto out; + + /* Perform offline tests only if online tests passed */ + if (offline) { + /* Stop the kernel from sending packets during the test. */ + efx_stop_queue(efx); + rc = efx_flush_queues(efx); + if (!rc) + rc = efx_offline_test(efx, &efx_tests, + efx->loopback_modes); + efx_wake_queue(efx); + } + + out: + if (!already_up) + dev_close(efx->net_dev); + + EFX_LOG(efx, "%s all %sline self-tests\n", + rc == 0 ? "passed" : "failed", offline ? "off" : "on"); + + fail2: + fail1: + /* Fill ethtool results structures */ + efx_ethtool_fill_self_tests(efx, &efx_tests, NULL, data); + if (rc) + test->flags |= ETH_TEST_FL_FAILED; +} + /* Restart autonegotiation */ static int efx_ethtool_nway_reset(struct net_device *net_dev) { @@ -451,8 +704,12 @@ struct ethtool_ops efx_ethtool_ops = { .set_tx_csum = efx_ethtool_set_tx_csum, .get_sg = ethtool_op_get_sg, .set_sg = ethtool_op_set_sg, + .get_tso = ethtool_op_get_tso, + .set_tso = efx_ethtool_set_tso, .get_flags = ethtool_op_get_flags, .set_flags = ethtool_op_set_flags, + .self_test_count = efx_ethtool_self_test_count, + .self_test = efx_ethtool_self_test, .get_strings = efx_ethtool_get_strings, .phys_id = efx_ethtool_phys_id, .get_stats_count = efx_ethtool_get_stats_count, diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 46db549ce58059c4a8cf03ba67f4a579c024fe3d..b57cc68058c04d3d40270eaaeb983175aef63dc9 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -1129,6 +1129,7 @@ static void falcon_handle_driver_event(struct efx_channel *channel, case RX_RECOVERY_EV_DECODE: EFX_ERR(efx, "channel %d seen DRIVER RX_RESET event. " "Resetting.\n", channel->channel); + atomic_inc(&efx->rx_reset); efx_schedule_reset(efx, EFX_WORKAROUND_6555(efx) ? RESET_TYPE_RX_RECOVERY : @@ -1731,7 +1732,8 @@ void falcon_drain_tx_fifo(struct efx_nic *efx) efx_oword_t temp; int count; - if (FALCON_REV(efx) < FALCON_REV_B0) + if ((FALCON_REV(efx) < FALCON_REV_B0) || + (efx->loopback_mode != LOOPBACK_NONE)) return; falcon_read(efx, &temp, MAC0_CTRL_REG_KER); @@ -2091,6 +2093,8 @@ static int falcon_probe_phy(struct efx_nic *efx) efx->phy_type); return -1; } + + efx->loopback_modes = LOOPBACKS_10G_INTERNAL | efx->phy_op->loopbacks; return 0; } @@ -2468,14 +2472,12 @@ int falcon_probe_nic(struct efx_nic *efx) fail5: falcon_free_buffer(efx, &efx->irq_status); fail4: - /* fall-thru */ fail3: if (nic_data->pci_dev2) { pci_dev_put(nic_data->pci_dev2); nic_data->pci_dev2 = NULL; } fail2: - /* fall-thru */ fail1: kfree(efx->nic_data); return rc; diff --git a/drivers/net/sfc/falcon_hwdefs.h b/drivers/net/sfc/falcon_hwdefs.h index 0485a63eaff6e12bae1e6539a9386eb7db9bc411..06e2d68fc3d1f98b34899ed7c39ff557da671e9f 100644 --- a/drivers/net/sfc/falcon_hwdefs.h +++ b/drivers/net/sfc/falcon_hwdefs.h @@ -636,6 +636,14 @@ #define XX_HIDRVA_WIDTH 1 #define XX_LODRVA_LBN 8 #define XX_LODRVA_WIDTH 1 +#define XX_LPBKD_LBN 3 +#define XX_LPBKD_WIDTH 1 +#define XX_LPBKC_LBN 2 +#define XX_LPBKC_WIDTH 1 +#define XX_LPBKB_LBN 1 +#define XX_LPBKB_WIDTH 1 +#define XX_LPBKA_LBN 0 +#define XX_LPBKA_WIDTH 1 #define XX_TXDRV_CTL_REG_MAC 0x12 #define XX_DEQD_LBN 28 @@ -656,8 +664,14 @@ #define XX_DTXA_WIDTH 4 /* XAUI XGXS core status register */ -#define XX_FORCE_SIG_DECODE_FORCED 0xff #define XX_CORE_STAT_REG_MAC 0x16 +#define XX_FORCE_SIG_LBN 24 +#define XX_FORCE_SIG_WIDTH 8 +#define XX_FORCE_SIG_DECODE_FORCED 0xff +#define XX_XGXS_LB_EN_LBN 23 +#define XX_XGXS_LB_EN_WIDTH 1 +#define XX_XGMII_LB_EN_LBN 22 +#define XX_XGMII_LB_EN_WIDTH 1 #define XX_ALIGN_DONE_LBN 20 #define XX_ALIGN_DONE_WIDTH 1 #define XX_SYNC_STAT_LBN 16 diff --git a/drivers/net/sfc/falcon_xmac.c b/drivers/net/sfc/falcon_xmac.c index aa7521b24a5d04c592cecdef0d13a8449f890e67..a74b7931a3c43e462d7fdca00ecc8e98e46d64a5 100644 --- a/drivers/net/sfc/falcon_xmac.c +++ b/drivers/net/sfc/falcon_xmac.c @@ -32,7 +32,7 @@ (FALCON_XMAC_REGBANK + ((mac_reg) * FALCON_XMAC_REG_SIZE)) void falcon_xmac_writel(struct efx_nic *efx, - efx_dword_t *value, unsigned int mac_reg) + efx_dword_t *value, unsigned int mac_reg) { efx_oword_t temp; @@ -69,6 +69,10 @@ static int falcon_reset_xmac(struct efx_nic *efx) udelay(10); } + /* This often fails when DSP is disabled, ignore it */ + if (sfe4001_phy_flash_cfg != 0) + return 0; + EFX_ERR(efx, "timed out waiting for XMAC core reset\n"); return -ETIMEDOUT; } @@ -223,7 +227,7 @@ static int falcon_xgmii_status(struct efx_nic *efx) /* The ISR latches, so clear it and re-read */ falcon_xmac_readl(efx, ®, XM_MGT_INT_REG_MAC_B0); falcon_xmac_readl(efx, ®, XM_MGT_INT_REG_MAC_B0); - + if (EFX_DWORD_FIELD(reg, XM_LCLFLT) || EFX_DWORD_FIELD(reg, XM_RMTFLT)) { EFX_INFO(efx, "MGT_INT: "EFX_DWORD_FMT"\n", EFX_DWORD_VAL(reg)); @@ -237,7 +241,7 @@ static void falcon_mask_status_intr(struct efx_nic *efx, int enable) { efx_dword_t reg; - if (FALCON_REV(efx) < FALCON_REV_B0) + if ((FALCON_REV(efx) < FALCON_REV_B0) || LOOPBACK_INTERNAL(efx)) return; /* Flush the ISR */ @@ -284,6 +288,9 @@ int falcon_xaui_link_ok(struct efx_nic *efx) efx_dword_t reg; int align_done, sync_status, link_ok = 0; + if (LOOPBACK_INTERNAL(efx)) + return 1; + /* Read link status */ falcon_xmac_readl(efx, ®, XX_CORE_STAT_REG_MAC); @@ -374,6 +381,61 @@ static void falcon_reconfigure_xmac_core(struct efx_nic *efx) falcon_xmac_writel(efx, ®, XM_ADR_HI_REG_MAC); } +static void falcon_reconfigure_xgxs_core(struct efx_nic *efx) +{ + efx_dword_t reg; + int xgxs_loopback = (efx->loopback_mode == LOOPBACK_XGXS) ? 1 : 0; + int xaui_loopback = (efx->loopback_mode == LOOPBACK_XAUI) ? 1 : 0; + int xgmii_loopback = + (efx->loopback_mode == LOOPBACK_XGMII) ? 1 : 0; + + /* XGXS block is flaky and will need to be reset if moving + * into our out of XGMII, XGXS or XAUI loopbacks. */ + if (EFX_WORKAROUND_5147(efx)) { + int old_xgmii_loopback, old_xgxs_loopback, old_xaui_loopback; + int reset_xgxs; + + falcon_xmac_readl(efx, ®, XX_CORE_STAT_REG_MAC); + old_xgxs_loopback = EFX_DWORD_FIELD(reg, XX_XGXS_LB_EN); + old_xgmii_loopback = EFX_DWORD_FIELD(reg, XX_XGMII_LB_EN); + + falcon_xmac_readl(efx, ®, XX_SD_CTL_REG_MAC); + old_xaui_loopback = EFX_DWORD_FIELD(reg, XX_LPBKA); + + /* The PHY driver may have turned XAUI off */ + reset_xgxs = ((xgxs_loopback != old_xgxs_loopback) || + (xaui_loopback != old_xaui_loopback) || + (xgmii_loopback != old_xgmii_loopback)); + if (reset_xgxs) { + falcon_xmac_readl(efx, ®, XX_PWR_RST_REG_MAC); + EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSTX_EN, 1); + EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSRX_EN, 1); + falcon_xmac_writel(efx, ®, XX_PWR_RST_REG_MAC); + udelay(1); + EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSTX_EN, 0); + EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSRX_EN, 0); + falcon_xmac_writel(efx, ®, XX_PWR_RST_REG_MAC); + udelay(1); + } + } + + falcon_xmac_readl(efx, ®, XX_CORE_STAT_REG_MAC); + EFX_SET_DWORD_FIELD(reg, XX_FORCE_SIG, + (xgxs_loopback || xaui_loopback) ? + XX_FORCE_SIG_DECODE_FORCED : 0); + EFX_SET_DWORD_FIELD(reg, XX_XGXS_LB_EN, xgxs_loopback); + EFX_SET_DWORD_FIELD(reg, XX_XGMII_LB_EN, xgmii_loopback); + falcon_xmac_writel(efx, ®, XX_CORE_STAT_REG_MAC); + + falcon_xmac_readl(efx, ®, XX_SD_CTL_REG_MAC); + EFX_SET_DWORD_FIELD(reg, XX_LPBKD, xaui_loopback); + EFX_SET_DWORD_FIELD(reg, XX_LPBKC, xaui_loopback); + EFX_SET_DWORD_FIELD(reg, XX_LPBKB, xaui_loopback); + EFX_SET_DWORD_FIELD(reg, XX_LPBKA, xaui_loopback); + falcon_xmac_writel(efx, ®, XX_SD_CTL_REG_MAC); +} + + /* Try and bring the Falcon side of the Falcon-Phy XAUI link fails * to come back up. Bash it until it comes back up */ static int falcon_check_xaui_link_up(struct efx_nic *efx) @@ -382,7 +444,8 @@ static int falcon_check_xaui_link_up(struct efx_nic *efx) tries = EFX_WORKAROUND_5147(efx) ? 5 : 1; max_tries = tries; - if (efx->phy_type == PHY_TYPE_NONE) + if ((efx->loopback_mode == LOOPBACK_NETWORK) || + (efx->phy_type == PHY_TYPE_NONE)) return 0; while (tries) { @@ -408,8 +471,13 @@ void falcon_reconfigure_xmac(struct efx_nic *efx) falcon_mask_status_intr(efx, 0); falcon_deconfigure_mac_wrapper(efx); + + efx->tx_disabled = LOOPBACK_INTERNAL(efx); efx->phy_op->reconfigure(efx); + + falcon_reconfigure_xgxs_core(efx); falcon_reconfigure_xmac_core(efx); + falcon_reconfigure_mac_wrapper(efx); /* Ensure XAUI link is up */ @@ -491,13 +559,15 @@ void falcon_update_stats_xmac(struct efx_nic *efx) (mac_stats->rx_bytes - mac_stats->rx_good_bytes); } -#define EFX_XAUI_RETRAIN_MAX 8 - int falcon_check_xmac(struct efx_nic *efx) { unsigned xaui_link_ok; int rc; + if ((efx->loopback_mode == LOOPBACK_NETWORK) || + (efx->phy_type == PHY_TYPE_NONE)) + return 0; + falcon_mask_status_intr(efx, 0); xaui_link_ok = falcon_xaui_link_ok(efx); diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c index dc06bb0aa5752677b4115645aec5385985e5b5a5..c4f540e93b79f61b69465d7ac6c6508032362f1c 100644 --- a/drivers/net/sfc/mdio_10g.c +++ b/drivers/net/sfc/mdio_10g.c @@ -44,6 +44,9 @@ static int mdio_clause45_check_mmd(struct efx_nic *efx, int mmd, int status; int phy_id = efx->mii.phy_id; + if (LOOPBACK_INTERNAL(efx)) + return 0; + /* Read MMD STATUS2 to check it is responding. */ status = mdio_clause45_read(efx, phy_id, mmd, MDIO_MMDREG_STAT2); if (((status >> MDIO_MMDREG_STAT2_PRESENT_LBN) & @@ -164,6 +167,22 @@ int mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask) int mmd = 0; int good; + /* If the port is in loopback, then we should only consider a subset + * of mmd's */ + if (LOOPBACK_INTERNAL(efx)) + return 1; + else if (efx->loopback_mode == LOOPBACK_NETWORK) + return 0; + else if (efx->loopback_mode == LOOPBACK_PHYXS) + mmd_mask &= ~(MDIO_MMDREG_DEVS0_PHYXS | + MDIO_MMDREG_DEVS0_PCS | + MDIO_MMDREG_DEVS0_PMAPMD); + else if (efx->loopback_mode == LOOPBACK_PCS) + mmd_mask &= ~(MDIO_MMDREG_DEVS0_PCS | + MDIO_MMDREG_DEVS0_PMAPMD); + else if (efx->loopback_mode == LOOPBACK_PMAPMD) + mmd_mask &= ~MDIO_MMDREG_DEVS0_PMAPMD; + while (mmd_mask) { if (mmd_mask & 1) { /* Double reads because link state is latched, and a @@ -182,6 +201,65 @@ int mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask) return ok; } +void mdio_clause45_transmit_disable(struct efx_nic *efx) +{ + int phy_id = efx->mii.phy_id; + int ctrl1, ctrl2; + + ctrl1 = ctrl2 = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD, + MDIO_MMDREG_TXDIS); + if (efx->tx_disabled) + ctrl2 |= (1 << MDIO_MMDREG_TXDIS_GLOBAL_LBN); + else + ctrl1 &= ~(1 << MDIO_MMDREG_TXDIS_GLOBAL_LBN); + if (ctrl1 != ctrl2) + mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, + MDIO_MMDREG_TXDIS, ctrl2); +} + +void mdio_clause45_phy_reconfigure(struct efx_nic *efx) +{ + int phy_id = efx->mii.phy_id; + int ctrl1, ctrl2; + + /* Handle (with debouncing) PMA/PMD loopback */ + ctrl1 = ctrl2 = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD, + MDIO_MMDREG_CTRL1); + + if (efx->loopback_mode == LOOPBACK_PMAPMD) + ctrl2 |= (1 << MDIO_PMAPMD_CTRL1_LBACK_LBN); + else + ctrl2 &= ~(1 << MDIO_PMAPMD_CTRL1_LBACK_LBN); + + if (ctrl1 != ctrl2) + mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, + MDIO_MMDREG_CTRL1, ctrl2); + + /* Handle (with debouncing) PCS loopback */ + ctrl1 = ctrl2 = mdio_clause45_read(efx, phy_id, MDIO_MMD_PCS, + MDIO_MMDREG_CTRL1); + if (efx->loopback_mode == LOOPBACK_PCS) + ctrl2 |= (1 << MDIO_MMDREG_CTRL1_LBACK_LBN); + else + ctrl2 &= ~(1 << MDIO_MMDREG_CTRL1_LBACK_LBN); + + if (ctrl1 != ctrl2) + mdio_clause45_write(efx, phy_id, MDIO_MMD_PCS, + MDIO_MMDREG_CTRL1, ctrl2); + + /* Handle (with debouncing) PHYXS network loopback */ + ctrl1 = ctrl2 = mdio_clause45_read(efx, phy_id, MDIO_MMD_PHYXS, + MDIO_MMDREG_CTRL1); + if (efx->loopback_mode == LOOPBACK_NETWORK) + ctrl2 |= (1 << MDIO_MMDREG_CTRL1_LBACK_LBN); + else + ctrl2 &= ~(1 << MDIO_MMDREG_CTRL1_LBACK_LBN); + + if (ctrl1 != ctrl2) + mdio_clause45_write(efx, phy_id, MDIO_MMD_PHYXS, + MDIO_MMDREG_CTRL1, ctrl2); +} + /** * mdio_clause45_get_settings - Read (some of) the PHY settings over MDIO. * @efx: Efx NIC diff --git a/drivers/net/sfc/mdio_10g.h b/drivers/net/sfc/mdio_10g.h index 2214b6d820a7b8cbaac61bbcddf69b4693c804df..cb99f3f4491c5413c27435f188824d68fe11f988 100644 --- a/drivers/net/sfc/mdio_10g.h +++ b/drivers/net/sfc/mdio_10g.h @@ -44,11 +44,16 @@ #define MDIO_MMDREG_DEVS1 (6) #define MDIO_MMDREG_CTRL2 (7) #define MDIO_MMDREG_STAT2 (8) +#define MDIO_MMDREG_TXDIS (9) /* Bits in MMDREG_CTRL1 */ /* Reset */ #define MDIO_MMDREG_CTRL1_RESET_LBN (15) #define MDIO_MMDREG_CTRL1_RESET_WIDTH (1) +/* Loopback */ +/* Loopback bit for WIS, PCS, PHYSX and DTEXS */ +#define MDIO_MMDREG_CTRL1_LBACK_LBN (14) +#define MDIO_MMDREG_CTRL1_LBACK_WIDTH (1) /* Bits in MMDREG_STAT1 */ #define MDIO_MMDREG_STAT1_FAULT_LBN (7) @@ -56,6 +61,9 @@ /* Link state */ #define MDIO_MMDREG_STAT1_LINK_LBN (2) #define MDIO_MMDREG_STAT1_LINK_WIDTH (1) +/* Low power ability */ +#define MDIO_MMDREG_STAT1_LPABLE_LBN (1) +#define MDIO_MMDREG_STAT1_LPABLE_WIDTH (1) /* Bits in ID reg */ #define MDIO_ID_REV(_id32) (_id32 & 0xf) @@ -76,6 +84,14 @@ #define MDIO_MMDREG_STAT2_PRESENT_LBN (14) #define MDIO_MMDREG_STAT2_PRESENT_WIDTH (2) +/* Bits in MMDREG_TXDIS */ +#define MDIO_MMDREG_TXDIS_GLOBAL_LBN (0) +#define MDIO_MMDREG_TXDIS_GLOBAL_WIDTH (1) + +/* MMD-specific bits, ordered by MMD, then register */ +#define MDIO_PMAPMD_CTRL1_LBACK_LBN (0) +#define MDIO_PMAPMD_CTRL1_LBACK_WIDTH (1) + /* PMA type (4 bits) */ #define MDIO_PMAPMD_CTRL2_10G_CX4 (0x0) #define MDIO_PMAPMD_CTRL2_10G_EW (0x1) @@ -95,7 +111,7 @@ #define MDIO_PMAPMD_CTRL2_10_BT (0xf) #define MDIO_PMAPMD_CTRL2_TYPE_MASK (0xf) -/* /\* PHY XGXS lane state *\/ */ +/* PHY XGXS lane state */ #define MDIO_PHYXS_LANE_STATE (0x18) #define MDIO_PHYXS_LANE_ALIGNED_LBN (12) @@ -217,6 +233,12 @@ int mdio_clause45_check_mmds(struct efx_nic *efx, extern int mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask); +/* Generic transmit disable support though PMAPMD */ +extern void mdio_clause45_transmit_disable(struct efx_nic *efx); + +/* Generic part of reconfigure: set/clear loopback bits */ +extern void mdio_clause45_phy_reconfigure(struct efx_nic *efx); + /* Read (some of) the PHY settings over MDIO */ extern void mdio_clause45_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd); diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index c505482c25203d1fa8de92195c404cd4bce8683a..59f261b4171fd70a10618e09a62fd8fec20ea183 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -134,6 +134,8 @@ struct efx_special_buffer { * Set only on the final fragment of a packet; %NULL for all other * fragments. When this fragment completes, then we can free this * skb. + * @tsoh: The associated TSO header structure, or %NULL if this + * buffer is not a TSO header. * @dma_addr: DMA address of the fragment. * @len: Length of this fragment. * This field is zero when the queue slot is empty. @@ -144,6 +146,7 @@ struct efx_special_buffer { */ struct efx_tx_buffer { const struct sk_buff *skb; + struct efx_tso_header *tsoh; dma_addr_t dma_addr; unsigned short len; unsigned char continuation; @@ -187,6 +190,13 @@ struct efx_tx_buffer { * variable indicates that the queue is full. This is to * avoid cache-line ping-pong between the xmit path and the * completion path. + * @tso_headers_free: A list of TSO headers allocated for this TX queue + * that are not in use, and so available for new TSO sends. The list + * is protected by the TX queue lock. + * @tso_bursts: Number of times TSO xmit invoked by kernel + * @tso_long_headers: Number of packets with headers too long for standard + * blocks + * @tso_packets: Number of packets via the TSO xmit path */ struct efx_tx_queue { /* Members which don't change on the fast path */ @@ -206,6 +216,10 @@ struct efx_tx_queue { unsigned int insert_count ____cacheline_aligned_in_smp; unsigned int write_count; unsigned int old_read_count; + struct efx_tso_header *tso_headers_free; + unsigned int tso_bursts; + unsigned int tso_long_headers; + unsigned int tso_packets; }; /** @@ -434,6 +448,9 @@ struct efx_board { struct efx_blinker blinker; }; +#define STRING_TABLE_LOOKUP(val, member) \ + member ## _names[val] + enum efx_int_mode { /* Be careful if altering to correct macro below */ EFX_INT_MODE_MSIX = 0, @@ -506,6 +523,7 @@ enum efx_fc_type { * @check_hw: Check hardware * @reset_xaui: Reset XAUI side of PHY for (software sequenced reset) * @mmds: MMD presence mask + * @loopbacks: Supported loopback modes mask */ struct efx_phy_operations { int (*init) (struct efx_nic *efx); @@ -515,6 +533,7 @@ struct efx_phy_operations { int (*check_hw) (struct efx_nic *efx); void (*reset_xaui) (struct efx_nic *efx); int mmds; + unsigned loopbacks; }; /* @@ -653,7 +672,6 @@ union efx_multicast_hash { * @phy_op: PHY interface * @phy_data: PHY private data (including PHY-specific stats) * @mii: PHY interface - * @phy_powered: PHY power state * @tx_disabled: PHY transmitter turned off * @link_up: Link status * @link_options: Link options (MII/GMII format) @@ -662,6 +680,9 @@ union efx_multicast_hash { * @multicast_hash: Multicast hash table * @flow_control: Flow control flags - separate RX/TX so can't use link_options * @reconfigure_work: work item for dealing with PHY events + * @loopback_mode: Loopback status + * @loopback_modes: Supported loopback mode bitmask + * @loopback_selftest: Offline self-test private state * * The @priv field of the corresponding &struct net_device points to * this. @@ -721,6 +742,7 @@ struct efx_nic { struct efx_phy_operations *phy_op; void *phy_data; struct mii_if_info mii; + unsigned tx_disabled; int link_up; unsigned int link_options; @@ -732,6 +754,10 @@ struct efx_nic { struct work_struct reconfigure_work; atomic_t rx_reset; + enum efx_loopback_mode loopback_mode; + unsigned int loopback_modes; + + void *loopback_selftest; }; /** diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c index 551299b462ae9446ad3b44491b693f652513b589..670622373ddf027b1456ad17b69132331332396f 100644 --- a/drivers/net/sfc/rx.c +++ b/drivers/net/sfc/rx.c @@ -19,6 +19,7 @@ #include "rx.h" #include "efx.h" #include "falcon.h" +#include "selftest.h" #include "workarounds.h" /* Number of RX descriptors pushed at once. */ @@ -683,6 +684,15 @@ void __efx_rx_packet(struct efx_channel *channel, struct sk_buff *skb; int lro = efx->net_dev->features & NETIF_F_LRO; + /* If we're in loopback test, then pass the packet directly to the + * loopback layer, and free the rx_buf here + */ + if (unlikely(efx->loopback_selftest)) { + efx_loopback_rx_packet(efx, rx_buf->data, rx_buf->len); + efx_free_rx_buffer(efx, rx_buf); + goto done; + } + if (rx_buf->skb) { prefetch(skb_shinfo(rx_buf->skb)); @@ -736,7 +746,6 @@ void __efx_rx_packet(struct efx_channel *channel, /* Update allocation strategy method */ channel->rx_alloc_level += RX_ALLOC_FACTOR_SKB; - /* fall-thru */ done: efx->net_dev->last_rx = jiffies; } diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c new file mode 100644 index 0000000000000000000000000000000000000000..cbda15946e8f57585aa8cda81a39ed5e106c3b50 --- /dev/null +++ b/drivers/net/sfc/selftest.c @@ -0,0 +1,717 @@ +/**************************************************************************** + * Driver for Solarflare Solarstorm network controllers and boards + * Copyright 2005-2006 Fen Systems Ltd. + * Copyright 2006-2008 Solarflare Communications Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation, incorporated herein by reference. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "net_driver.h" +#include "ethtool.h" +#include "efx.h" +#include "falcon.h" +#include "selftest.h" +#include "boards.h" +#include "workarounds.h" +#include "mac.h" + +/* + * Loopback test packet structure + * + * The self-test should stress every RSS vector, and unfortunately + * Falcon only performs RSS on TCP/UDP packets. + */ +struct efx_loopback_payload { + struct ethhdr header; + struct iphdr ip; + struct udphdr udp; + __be16 iteration; + const char msg[64]; +} __attribute__ ((packed)); + +/* Loopback test source MAC address */ +static const unsigned char payload_source[ETH_ALEN] = { + 0x00, 0x0f, 0x53, 0x1b, 0x1b, 0x1b, +}; + +static const char *payload_msg = + "Hello world! This is an Efx loopback test in progress!"; + +/** + * efx_selftest_state - persistent state during a selftest + * @flush: Drop all packets in efx_loopback_rx_packet + * @packet_count: Number of packets being used in this test + * @skbs: An array of skbs transmitted + * @rx_good: RX good packet count + * @rx_bad: RX bad packet count + * @payload: Payload used in tests + */ +struct efx_selftest_state { + int flush; + int packet_count; + struct sk_buff **skbs; + atomic_t rx_good; + atomic_t rx_bad; + struct efx_loopback_payload payload; +}; + +/************************************************************************** + * + * Configurable values + * + **************************************************************************/ + +/* Level of loopback testing + * + * The maximum packet burst length is 16**(n-1), i.e. + * + * - Level 0 : no packets + * - Level 1 : 1 packet + * - Level 2 : 17 packets (1 * 1 packet, 1 * 16 packets) + * - Level 3 : 273 packets (1 * 1 packet, 1 * 16 packet, 1 * 256 packets) + * + */ +static unsigned int loopback_test_level = 3; + +/************************************************************************** + * + * Interrupt and event queue testing + * + **************************************************************************/ + +/* Test generation and receipt of interrupts */ +static int efx_test_interrupts(struct efx_nic *efx, + struct efx_self_tests *tests) +{ + struct efx_channel *channel; + + EFX_LOG(efx, "testing interrupts\n"); + tests->interrupt = -1; + + /* Reset interrupt flag */ + efx->last_irq_cpu = -1; + smp_wmb(); + + /* ACK each interrupting event queue. Receiving an interrupt due to + * traffic before a test event is raised is considered a pass */ + efx_for_each_channel_with_interrupt(channel, efx) { + if (channel->work_pending) + efx_process_channel_now(channel); + if (efx->last_irq_cpu >= 0) + goto success; + } + + falcon_generate_interrupt(efx); + + /* Wait for arrival of test interrupt. */ + EFX_LOG(efx, "waiting for test interrupt\n"); + schedule_timeout_uninterruptible(HZ / 10); + if (efx->last_irq_cpu >= 0) + goto success; + + EFX_ERR(efx, "timed out waiting for interrupt\n"); + return -ETIMEDOUT; + + success: + EFX_LOG(efx, "test interrupt (mode %d) seen on CPU%d\n", + efx->interrupt_mode, efx->last_irq_cpu); + tests->interrupt = 1; + return 0; +} + +/* Test generation and receipt of non-interrupting events */ +static int efx_test_eventq(struct efx_channel *channel, + struct efx_self_tests *tests) +{ + unsigned int magic; + + /* Channel specific code, limited to 20 bits */ + magic = (0x00010150 + channel->channel); + EFX_LOG(channel->efx, "channel %d testing event queue with code %x\n", + channel->channel, magic); + + tests->eventq_dma[channel->channel] = -1; + tests->eventq_int[channel->channel] = 1; /* fake pass */ + tests->eventq_poll[channel->channel] = 1; /* fake pass */ + + /* Reset flag and zero magic word */ + channel->efx->last_irq_cpu = -1; + channel->eventq_magic = 0; + smp_wmb(); + + falcon_generate_test_event(channel, magic); + udelay(1); + + efx_process_channel_now(channel); + if (channel->eventq_magic != magic) { + EFX_ERR(channel->efx, "channel %d failed to see test event\n", + channel->channel); + return -ETIMEDOUT; + } else { + tests->eventq_dma[channel->channel] = 1; + } + + return 0; +} + +/* Test generation and receipt of interrupting events */ +static int efx_test_eventq_irq(struct efx_channel *channel, + struct efx_self_tests *tests) +{ + unsigned int magic, count; + + /* Channel specific code, limited to 20 bits */ + magic = (0x00010150 + channel->channel); + EFX_LOG(channel->efx, "channel %d testing event queue with code %x\n", + channel->channel, magic); + + tests->eventq_dma[channel->channel] = -1; + tests->eventq_int[channel->channel] = -1; + tests->eventq_poll[channel->channel] = -1; + + /* Reset flag and zero magic word */ + channel->efx->last_irq_cpu = -1; + channel->eventq_magic = 0; + smp_wmb(); + + falcon_generate_test_event(channel, magic); + + /* Wait for arrival of interrupt */ + count = 0; + do { + schedule_timeout_uninterruptible(HZ / 100); + + if (channel->work_pending) + efx_process_channel_now(channel); + + if (channel->eventq_magic == magic) + goto eventq_ok; + } while (++count < 2); + + EFX_ERR(channel->efx, "channel %d timed out waiting for event queue\n", + channel->channel); + + /* See if interrupt arrived */ + if (channel->efx->last_irq_cpu >= 0) { + EFX_ERR(channel->efx, "channel %d saw interrupt on CPU%d " + "during event queue test\n", channel->channel, + raw_smp_processor_id()); + tests->eventq_int[channel->channel] = 1; + } + + /* Check to see if event was received even if interrupt wasn't */ + efx_process_channel_now(channel); + if (channel->eventq_magic == magic) { + EFX_ERR(channel->efx, "channel %d event was generated, but " + "failed to trigger an interrupt\n", channel->channel); + tests->eventq_dma[channel->channel] = 1; + } + + return -ETIMEDOUT; + eventq_ok: + EFX_LOG(channel->efx, "channel %d event queue passed\n", + channel->channel); + tests->eventq_dma[channel->channel] = 1; + tests->eventq_int[channel->channel] = 1; + tests->eventq_poll[channel->channel] = 1; + return 0; +} + +/************************************************************************** + * + * PHY testing + * + **************************************************************************/ + +/* Check PHY presence by reading the PHY ID registers */ +static int efx_test_phy(struct efx_nic *efx, + struct efx_self_tests *tests) +{ + u16 physid1, physid2; + struct mii_if_info *mii = &efx->mii; + struct net_device *net_dev = efx->net_dev; + + if (efx->phy_type == PHY_TYPE_NONE) + return 0; + + EFX_LOG(efx, "testing PHY presence\n"); + tests->phy_ok = -1; + + physid1 = mii->mdio_read(net_dev, mii->phy_id, MII_PHYSID1); + physid2 = mii->mdio_read(net_dev, mii->phy_id, MII_PHYSID2); + + if ((physid1 != 0x0000) && (physid1 != 0xffff) && + (physid2 != 0x0000) && (physid2 != 0xffff)) { + EFX_LOG(efx, "found MII PHY %d ID 0x%x:%x\n", + mii->phy_id, physid1, physid2); + tests->phy_ok = 1; + return 0; + } + + EFX_ERR(efx, "no MII PHY present with ID %d\n", mii->phy_id); + return -ENODEV; +} + +/************************************************************************** + * + * Loopback testing + * NB Only one loopback test can be executing concurrently. + * + **************************************************************************/ + +/* Loopback test RX callback + * This is called for each received packet during loopback testing. + */ +void efx_loopback_rx_packet(struct efx_nic *efx, + const char *buf_ptr, int pkt_len) +{ + struct efx_selftest_state *state = efx->loopback_selftest; + struct efx_loopback_payload *received; + struct efx_loopback_payload *payload; + + BUG_ON(!buf_ptr); + + /* If we are just flushing, then drop the packet */ + if ((state == NULL) || state->flush) + return; + + payload = &state->payload; + + received = (struct efx_loopback_payload *)(char *) buf_ptr; + received->ip.saddr = payload->ip.saddr; + received->ip.check = payload->ip.check; + + /* Check that header exists */ + if (pkt_len < sizeof(received->header)) { + EFX_ERR(efx, "saw runt RX packet (length %d) in %s loopback " + "test\n", pkt_len, LOOPBACK_MODE(efx)); + goto err; + } + + /* Check that the ethernet header exists */ + if (memcmp(&received->header, &payload->header, ETH_HLEN) != 0) { + EFX_ERR(efx, "saw non-loopback RX packet in %s loopback test\n", + LOOPBACK_MODE(efx)); + goto err; + } + + /* Check packet length */ + if (pkt_len != sizeof(*payload)) { + EFX_ERR(efx, "saw incorrect RX packet length %d (wanted %d) in " + "%s loopback test\n", pkt_len, (int)sizeof(*payload), + LOOPBACK_MODE(efx)); + goto err; + } + + /* Check that IP header matches */ + if (memcmp(&received->ip, &payload->ip, sizeof(payload->ip)) != 0) { + EFX_ERR(efx, "saw corrupted IP header in %s loopback test\n", + LOOPBACK_MODE(efx)); + goto err; + } + + /* Check that msg and padding matches */ + if (memcmp(&received->msg, &payload->msg, sizeof(received->msg)) != 0) { + EFX_ERR(efx, "saw corrupted RX packet in %s loopback test\n", + LOOPBACK_MODE(efx)); + goto err; + } + + /* Check that iteration matches */ + if (received->iteration != payload->iteration) { + EFX_ERR(efx, "saw RX packet from iteration %d (wanted %d) in " + "%s loopback test\n", ntohs(received->iteration), + ntohs(payload->iteration), LOOPBACK_MODE(efx)); + goto err; + } + + /* Increase correct RX count */ + EFX_TRACE(efx, "got loopback RX in %s loopback test\n", + LOOPBACK_MODE(efx)); + + atomic_inc(&state->rx_good); + return; + + err: +#ifdef EFX_ENABLE_DEBUG + if (atomic_read(&state->rx_bad) == 0) { + EFX_ERR(efx, "received packet:\n"); + print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 0x10, 1, + buf_ptr, pkt_len, 0); + EFX_ERR(efx, "expected packet:\n"); + print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 0x10, 1, + &state->payload, sizeof(state->payload), 0); + } +#endif + atomic_inc(&state->rx_bad); +} + +/* Initialise an efx_selftest_state for a new iteration */ +static void efx_iterate_state(struct efx_nic *efx) +{ + struct efx_selftest_state *state = efx->loopback_selftest; + struct net_device *net_dev = efx->net_dev; + struct efx_loopback_payload *payload = &state->payload; + + /* Initialise the layerII header */ + memcpy(&payload->header.h_dest, net_dev->dev_addr, ETH_ALEN); + memcpy(&payload->header.h_source, &payload_source, ETH_ALEN); + payload->header.h_proto = htons(ETH_P_IP); + + /* saddr set later and used as incrementing count */ + payload->ip.daddr = htonl(INADDR_LOOPBACK); + payload->ip.ihl = 5; + payload->ip.check = htons(0xdead); + payload->ip.tot_len = htons(sizeof(*payload) - sizeof(struct ethhdr)); + payload->ip.version = IPVERSION; + payload->ip.protocol = IPPROTO_UDP; + + /* Initialise udp header */ + payload->udp.source = 0; + payload->udp.len = htons(sizeof(*payload) - sizeof(struct ethhdr) - + sizeof(struct iphdr)); + payload->udp.check = 0; /* checksum ignored */ + + /* Fill out payload */ + payload->iteration = htons(ntohs(payload->iteration) + 1); + memcpy(&payload->msg, payload_msg, sizeof(payload_msg)); + + /* Fill out remaining state members */ + atomic_set(&state->rx_good, 0); + atomic_set(&state->rx_bad, 0); + smp_wmb(); +} + +static int efx_tx_loopback(struct efx_tx_queue *tx_queue) +{ + struct efx_nic *efx = tx_queue->efx; + struct efx_selftest_state *state = efx->loopback_selftest; + struct efx_loopback_payload *payload; + struct sk_buff *skb; + int i, rc; + + /* Transmit N copies of buffer */ + for (i = 0; i < state->packet_count; i++) { + /* Allocate an skb, holding an extra reference for + * transmit completion counting */ + skb = alloc_skb(sizeof(state->payload), GFP_KERNEL); + if (!skb) + return -ENOMEM; + state->skbs[i] = skb; + skb_get(skb); + + /* Copy the payload in, incrementing the source address to + * exercise the rss vectors */ + payload = ((struct efx_loopback_payload *) + skb_put(skb, sizeof(state->payload))); + memcpy(payload, &state->payload, sizeof(state->payload)); + payload->ip.saddr = htonl(INADDR_LOOPBACK | (i << 2)); + + /* Ensure everything we've written is visible to the + * interrupt handler. */ + smp_wmb(); + + if (NET_DEV_REGISTERED(efx)) + netif_tx_lock_bh(efx->net_dev); + rc = efx_xmit(efx, tx_queue, skb); + if (NET_DEV_REGISTERED(efx)) + netif_tx_unlock_bh(efx->net_dev); + + if (rc != NETDEV_TX_OK) { + EFX_ERR(efx, "TX queue %d could not transmit packet %d " + "of %d in %s loopback test\n", tx_queue->queue, + i + 1, state->packet_count, LOOPBACK_MODE(efx)); + + /* Defer cleaning up the other skbs for the caller */ + kfree_skb(skb); + return -EPIPE; + } + } + + return 0; +} + +static int efx_rx_loopback(struct efx_tx_queue *tx_queue, + struct efx_loopback_self_tests *lb_tests) +{ + struct efx_nic *efx = tx_queue->efx; + struct efx_selftest_state *state = efx->loopback_selftest; + struct sk_buff *skb; + int tx_done = 0, rx_good, rx_bad; + int i, rc = 0; + + if (NET_DEV_REGISTERED(efx)) + netif_tx_lock_bh(efx->net_dev); + + /* Count the number of tx completions, and decrement the refcnt. Any + * skbs not already completed will be free'd when the queue is flushed */ + for (i=0; i < state->packet_count; i++) { + skb = state->skbs[i]; + if (skb && !skb_shared(skb)) + ++tx_done; + dev_kfree_skb_any(skb); + } + + if (NET_DEV_REGISTERED(efx)) + netif_tx_unlock_bh(efx->net_dev); + + /* Check TX completion and received packet counts */ + rx_good = atomic_read(&state->rx_good); + rx_bad = atomic_read(&state->rx_bad); + if (tx_done != state->packet_count) { + /* Don't free the skbs; they will be picked up on TX + * overflow or channel teardown. + */ + EFX_ERR(efx, "TX queue %d saw only %d out of an expected %d " + "TX completion events in %s loopback test\n", + tx_queue->queue, tx_done, state->packet_count, + LOOPBACK_MODE(efx)); + rc = -ETIMEDOUT; + /* Allow to fall through so we see the RX errors as well */ + } + + /* We may always be up to a flush away from our desired packet total */ + if (rx_good != state->packet_count) { + EFX_LOG(efx, "TX queue %d saw only %d out of an expected %d " + "received packets in %s loopback test\n", + tx_queue->queue, rx_good, state->packet_count, + LOOPBACK_MODE(efx)); + rc = -ETIMEDOUT; + /* Fall through */ + } + + /* Update loopback test structure */ + lb_tests->tx_sent[tx_queue->queue] += state->packet_count; + lb_tests->tx_done[tx_queue->queue] += tx_done; + lb_tests->rx_good += rx_good; + lb_tests->rx_bad += rx_bad; + + return rc; +} + +static int +efx_test_loopback(struct efx_tx_queue *tx_queue, + struct efx_loopback_self_tests *lb_tests) +{ + struct efx_nic *efx = tx_queue->efx; + struct efx_selftest_state *state = efx->loopback_selftest; + struct efx_channel *channel; + int i, rc = 0; + + for (i = 0; i < loopback_test_level; i++) { + /* Determine how many packets to send */ + state->packet_count = (efx->type->txd_ring_mask + 1) / 3; + state->packet_count = min(1 << (i << 2), state->packet_count); + state->skbs = kzalloc(sizeof(state->skbs[0]) * + state->packet_count, GFP_KERNEL); + state->flush = 0; + + EFX_LOG(efx, "TX queue %d testing %s loopback with %d " + "packets\n", tx_queue->queue, LOOPBACK_MODE(efx), + state->packet_count); + + efx_iterate_state(efx); + rc = efx_tx_loopback(tx_queue); + + /* NAPI polling is not enabled, so process channels synchronously */ + schedule_timeout_uninterruptible(HZ / 50); + efx_for_each_channel_with_interrupt(channel, efx) { + if (channel->work_pending) + efx_process_channel_now(channel); + } + + rc |= efx_rx_loopback(tx_queue, lb_tests); + kfree(state->skbs); + + if (rc) { + /* Wait a while to ensure there are no packets + * floating around after a failure. */ + schedule_timeout_uninterruptible(HZ / 10); + return rc; + } + } + + EFX_LOG(efx, "TX queue %d passed %s loopback test with a burst length " + "of %d packets\n", tx_queue->queue, LOOPBACK_MODE(efx), + state->packet_count); + + return rc; +} + +static int efx_test_loopbacks(struct efx_nic *efx, + struct efx_self_tests *tests, + unsigned int loopback_modes) +{ + struct efx_selftest_state *state = efx->loopback_selftest; + struct ethtool_cmd ecmd, ecmd_loopback; + struct efx_tx_queue *tx_queue; + enum efx_loopback_mode old_mode, mode; + int count, rc = 0, link_up; + + rc = efx_ethtool_get_settings(efx->net_dev, &ecmd); + if (rc) { + EFX_ERR(efx, "could not get GMII settings\n"); + return rc; + } + old_mode = efx->loopback_mode; + + /* Disable autonegotiation for the purposes of loopback */ + memcpy(&ecmd_loopback, &ecmd, sizeof(ecmd_loopback)); + if (ecmd_loopback.autoneg == AUTONEG_ENABLE) { + ecmd_loopback.autoneg = AUTONEG_DISABLE; + ecmd_loopback.duplex = DUPLEX_FULL; + ecmd_loopback.speed = SPEED_10000; + } + + rc = efx_ethtool_set_settings(efx->net_dev, &ecmd_loopback); + if (rc) { + EFX_ERR(efx, "could not disable autonegotiation\n"); + goto out; + } + tests->loopback_speed = ecmd_loopback.speed; + tests->loopback_full_duplex = ecmd_loopback.duplex; + + /* Test all supported loopback modes */ + for (mode = LOOPBACK_NONE; mode < LOOPBACK_TEST_MAX; mode++) { + if (!(loopback_modes & (1 << mode))) + continue; + + /* Move the port into the specified loopback mode. */ + state->flush = 1; + efx->loopback_mode = mode; + efx_reconfigure_port(efx); + + /* Wait for the PHY to signal the link is up */ + count = 0; + do { + struct efx_channel *channel = &efx->channel[0]; + + falcon_check_xmac(efx); + schedule_timeout_uninterruptible(HZ / 10); + if (channel->work_pending) + efx_process_channel_now(channel); + /* Wait for PHY events to be processed */ + flush_workqueue(efx->workqueue); + rmb(); + + /* efx->link_up can be 1 even if the XAUI link is down, + * (bug5762). Usually, it's not worth bothering with the + * difference, but for selftests, we need that extra + * guarantee that the link is really, really, up. + */ + link_up = efx->link_up; + if (!falcon_xaui_link_ok(efx)) + link_up = 0; + + } while ((++count < 20) && !link_up); + + /* The link should now be up. If it isn't, there is no point + * in attempting a loopback test */ + if (!link_up) { + EFX_ERR(efx, "loopback %s never came up\n", + LOOPBACK_MODE(efx)); + rc = -EIO; + goto out; + } + + EFX_LOG(efx, "link came up in %s loopback in %d iterations\n", + LOOPBACK_MODE(efx), count); + + /* Test every TX queue */ + efx_for_each_tx_queue(tx_queue, efx) { + rc |= efx_test_loopback(tx_queue, + &tests->loopback[mode]); + if (rc) + goto out; + } + } + + out: + /* Take out of loopback and restore PHY settings */ + state->flush = 1; + efx->loopback_mode = old_mode; + efx_ethtool_set_settings(efx->net_dev, &ecmd); + + return rc; +} + +/************************************************************************** + * + * Entry points + * + *************************************************************************/ + +/* Online (i.e. non-disruptive) testing + * This checks interrupt generation, event delivery and PHY presence. */ +int efx_online_test(struct efx_nic *efx, struct efx_self_tests *tests) +{ + struct efx_channel *channel; + int rc = 0; + + EFX_LOG(efx, "performing online self-tests\n"); + + rc |= efx_test_interrupts(efx, tests); + efx_for_each_channel(channel, efx) { + if (channel->has_interrupt) + rc |= efx_test_eventq_irq(channel, tests); + else + rc |= efx_test_eventq(channel, tests); + } + rc |= efx_test_phy(efx, tests); + + if (rc) + EFX_ERR(efx, "failed online self-tests\n"); + + return rc; +} + +/* Offline (i.e. disruptive) testing + * This checks MAC and PHY loopback on the specified port. */ +int efx_offline_test(struct efx_nic *efx, + struct efx_self_tests *tests, unsigned int loopback_modes) +{ + struct efx_selftest_state *state; + int rc = 0; + + EFX_LOG(efx, "performing offline self-tests\n"); + + /* Create a selftest_state structure to hold state for the test */ + state = kzalloc(sizeof(*state), GFP_KERNEL); + if (state == NULL) { + rc = -ENOMEM; + goto out; + } + + /* Set the port loopback_selftest member. From this point on + * all received packets will be dropped. Mark the state as + * "flushing" so all inflight packets are dropped */ + BUG_ON(efx->loopback_selftest); + state->flush = 1; + efx->loopback_selftest = (void *)state; + + rc = efx_test_loopbacks(efx, tests, loopback_modes); + + efx->loopback_selftest = NULL; + wmb(); + kfree(state); + + out: + if (rc) + EFX_ERR(efx, "failed offline self-tests\n"); + + return rc; +} + diff --git a/drivers/net/sfc/selftest.h b/drivers/net/sfc/selftest.h new file mode 100644 index 0000000000000000000000000000000000000000..f6999c2b622d603eabcd77a3f5f8fc0350201489 --- /dev/null +++ b/drivers/net/sfc/selftest.h @@ -0,0 +1,50 @@ +/**************************************************************************** + * Driver for Solarflare Solarstorm network controllers and boards + * Copyright 2005-2006 Fen Systems Ltd. + * Copyright 2006-2008 Solarflare Communications Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation, incorporated herein by reference. + */ + +#ifndef EFX_SELFTEST_H +#define EFX_SELFTEST_H + +#include "net_driver.h" + +/* + * Self tests + */ + +struct efx_loopback_self_tests { + int tx_sent[EFX_MAX_TX_QUEUES]; + int tx_done[EFX_MAX_TX_QUEUES]; + int rx_good; + int rx_bad; +}; + +/* Efx self test results + * For fields which are not counters, 1 indicates success and -1 + * indicates failure. + */ +struct efx_self_tests { + int interrupt; + int eventq_dma[EFX_MAX_CHANNELS]; + int eventq_int[EFX_MAX_CHANNELS]; + int eventq_poll[EFX_MAX_CHANNELS]; + int phy_ok; + int loopback_speed; + int loopback_full_duplex; + struct efx_loopback_self_tests loopback[LOOPBACK_TEST_MAX]; +}; + +extern void efx_loopback_rx_packet(struct efx_nic *efx, + const char *buf_ptr, int pkt_len); +extern int efx_online_test(struct efx_nic *efx, + struct efx_self_tests *tests); +extern int efx_offline_test(struct efx_nic *efx, + struct efx_self_tests *tests, + unsigned int loopback_modes); + +#endif /* EFX_SELFTEST_H */ diff --git a/drivers/net/sfc/sfe4001.c b/drivers/net/sfc/sfe4001.c index 11fa9fb8f48b23e769257e09c55c4760152c621a..725d1a539c49fdb73f3d331f8a2508f0b8ceee4a 100644 --- a/drivers/net/sfc/sfe4001.c +++ b/drivers/net/sfc/sfe4001.c @@ -130,6 +130,15 @@ void sfe4001_poweroff(struct efx_nic *efx) (void) efx_i2c_read(i2c, MAX6647, RSL, &in, 1); } +/* The P0_EN_3V3X line on SFE4001 boards (from A2 onward) is connected + * to the FLASH_CFG_1 input on the DSP. We must keep it high at power- + * up to allow writing the flash (done through MDIO from userland). + */ +unsigned int sfe4001_phy_flash_cfg; +module_param_named(phy_flash_cfg, sfe4001_phy_flash_cfg, uint, 0444); +MODULE_PARM_DESC(phy_flash_cfg, + "Force PHY to enter flash configuration mode"); + /* This board uses an I2C expander to provider power to the PHY, which needs to * be turned on before the PHY can be used. * Context: Process context, rtnl lock held @@ -203,6 +212,8 @@ int sfe4001_poweron(struct efx_nic *efx) out = 0xff & ~((1 << P0_EN_1V2_LBN) | (1 << P0_EN_2V5_LBN) | (1 << P0_EN_3V3X_LBN) | (1 << P0_EN_5V_LBN) | (1 << P0_X_TRST_LBN)); + if (sfe4001_phy_flash_cfg) + out |= 1 << P0_EN_3V3X_LBN; rc = efx_i2c_write(i2c, PCA9539, P0_OUT, &out, 1); if (rc) @@ -226,6 +237,9 @@ int sfe4001_poweron(struct efx_nic *efx) if (in & (1 << P1_AFE_PWD_LBN)) goto done; + /* DSP doesn't look powered in flash config mode */ + if (sfe4001_phy_flash_cfg) + goto done; } while (++count < 20); EFX_INFO(efx, "timed out waiting for power\n"); diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c index a2e9f79e47b17a0571b5653d19a927aff877df90..b1cd6deec01f7b3dd78c79781b39fa823db1ae68 100644 --- a/drivers/net/sfc/tenxpress.c +++ b/drivers/net/sfc/tenxpress.c @@ -24,6 +24,11 @@ MDIO_MMDREG_DEVS0_PCS | \ MDIO_MMDREG_DEVS0_PHYXS) +#define TENXPRESS_LOOPBACKS ((1 << LOOPBACK_PHYXS) | \ + (1 << LOOPBACK_PCS) | \ + (1 << LOOPBACK_PMAPMD) | \ + (1 << LOOPBACK_NETWORK)) + /* We complain if we fail to see the link partner as 10G capable this many * times in a row (must be > 1 as sampling the autoneg. registers is racy) */ @@ -72,6 +77,10 @@ #define PMA_PMD_BIST_RXD_LBN (1) #define PMA_PMD_BIST_AFE_LBN (0) +/* Special Software reset register */ +#define PMA_PMD_EXT_CTRL_REG 49152 +#define PMA_PMD_EXT_SSR_LBN 15 + #define BIST_MAX_DELAY (1000) #define BIST_POLL_DELAY (10) @@ -86,6 +95,11 @@ #define PCS_TEST_SELECT_REG 0xd807 /* PRM 10.5.8 */ #define CLK312_EN_LBN 3 +/* PHYXS registers */ +#define PHYXS_TEST1 (49162) +#define LOOPBACK_NEAR_LBN (8) +#define LOOPBACK_NEAR_WIDTH (1) + /* Boot status register */ #define PCS_BOOT_STATUS_REG (0xd000) #define PCS_BOOT_FATAL_ERR_LBN (0) @@ -106,7 +120,9 @@ MODULE_PARM_DESC(crc_error_reset_threshold, struct tenxpress_phy_data { enum tenxpress_state state; + enum efx_loopback_mode loopback_mode; atomic_t bad_crc_count; + int tx_disabled; int bad_lp_tries; }; @@ -199,10 +215,12 @@ static int tenxpress_phy_init(struct efx_nic *efx) tenxpress_set_state(efx, TENXPRESS_STATUS_NORMAL); - rc = mdio_clause45_wait_reset_mmds(efx, - TENXPRESS_REQUIRED_DEVS); - if (rc < 0) - goto fail; + if (!sfe4001_phy_flash_cfg) { + rc = mdio_clause45_wait_reset_mmds(efx, + TENXPRESS_REQUIRED_DEVS); + if (rc < 0) + goto fail; + } rc = mdio_clause45_check_mmds(efx, TENXPRESS_REQUIRED_DEVS, 0); if (rc < 0) @@ -225,6 +243,35 @@ static int tenxpress_phy_init(struct efx_nic *efx) return rc; } +static int tenxpress_special_reset(struct efx_nic *efx) +{ + int rc, reg; + + EFX_TRACE(efx, "%s\n", __func__); + + /* Initiate reset */ + reg = mdio_clause45_read(efx, efx->mii.phy_id, + MDIO_MMD_PMAPMD, PMA_PMD_EXT_CTRL_REG); + reg |= (1 << PMA_PMD_EXT_SSR_LBN); + mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD, + PMA_PMD_EXT_CTRL_REG, reg); + + msleep(200); + + /* Wait for the blocks to come out of reset */ + rc = mdio_clause45_wait_reset_mmds(efx, + TENXPRESS_REQUIRED_DEVS); + if (rc < 0) + return rc; + + /* Try and reconfigure the device */ + rc = tenxpress_init(efx); + if (rc < 0) + return rc; + + return 0; +} + static void tenxpress_set_bad_lp(struct efx_nic *efx, int bad_lp) { struct tenxpress_phy_data *pd = efx->phy_data; @@ -299,11 +346,46 @@ static int tenxpress_link_ok(struct efx_nic *efx, int check_lp) return ok; } +static void tenxpress_phyxs_loopback(struct efx_nic *efx) +{ + int phy_id = efx->mii.phy_id; + int ctrl1, ctrl2; + + ctrl1 = ctrl2 = mdio_clause45_read(efx, phy_id, MDIO_MMD_PHYXS, + PHYXS_TEST1); + if (efx->loopback_mode == LOOPBACK_PHYXS) + ctrl2 |= (1 << LOOPBACK_NEAR_LBN); + else + ctrl2 &= ~(1 << LOOPBACK_NEAR_LBN); + if (ctrl1 != ctrl2) + mdio_clause45_write(efx, phy_id, MDIO_MMD_PHYXS, + PHYXS_TEST1, ctrl2); +} + static void tenxpress_phy_reconfigure(struct efx_nic *efx) { + struct tenxpress_phy_data *phy_data = efx->phy_data; + int loop_change = LOOPBACK_OUT_OF(phy_data, efx, + TENXPRESS_LOOPBACKS); + if (!tenxpress_state_is(efx, TENXPRESS_STATUS_NORMAL)) return; + /* When coming out of transmit disable, coming out of low power + * mode, or moving out of any PHY internal loopback mode, + * perform a special software reset */ + if ((phy_data->tx_disabled && !efx->tx_disabled) || + loop_change) { + (void) tenxpress_special_reset(efx); + falcon_reset_xaui(efx); + } + + mdio_clause45_transmit_disable(efx); + mdio_clause45_phy_reconfigure(efx); + tenxpress_phyxs_loopback(efx); + + phy_data->tx_disabled = efx->tx_disabled; + phy_data->loopback_mode = efx->loopback_mode; efx->link_up = tenxpress_link_ok(efx, 0); efx->link_options = GM_LPA_10000FULL; } @@ -431,4 +513,5 @@ struct efx_phy_operations falcon_tenxpress_phy_ops = { .clear_interrupt = tenxpress_phy_clear_interrupt, .reset_xaui = tenxpress_reset_xaui, .mmds = TENXPRESS_REQUIRED_DEVS, + .loopbacks = TENXPRESS_LOOPBACKS, }; diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c index fbb866b2185ebdd5e37317f9f18341e23ed684e6..9b436f5b48889148792134f397830ea4716a17fb 100644 --- a/drivers/net/sfc/tx.c +++ b/drivers/net/sfc/tx.c @@ -82,6 +82,46 @@ static inline void efx_dequeue_buffer(struct efx_tx_queue *tx_queue, } } +/** + * struct efx_tso_header - a DMA mapped buffer for packet headers + * @next: Linked list of free ones. + * The list is protected by the TX queue lock. + * @dma_unmap_len: Length to unmap for an oversize buffer, or 0. + * @dma_addr: The DMA address of the header below. + * + * This controls the memory used for a TSO header. Use TSOH_DATA() + * to find the packet header data. Use TSOH_SIZE() to calculate the + * total size required for a given packet header length. TSO headers + * in the free list are exactly %TSOH_STD_SIZE bytes in size. + */ +struct efx_tso_header { + union { + struct efx_tso_header *next; + size_t unmap_len; + }; + dma_addr_t dma_addr; +}; + +static int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue, + const struct sk_buff *skb); +static void efx_fini_tso(struct efx_tx_queue *tx_queue); +static void efx_tsoh_heap_free(struct efx_tx_queue *tx_queue, + struct efx_tso_header *tsoh); + +static inline void efx_tsoh_free(struct efx_tx_queue *tx_queue, + struct efx_tx_buffer *buffer) +{ + if (buffer->tsoh) { + if (likely(!buffer->tsoh->unmap_len)) { + buffer->tsoh->next = tx_queue->tso_headers_free; + tx_queue->tso_headers_free = buffer->tsoh; + } else { + efx_tsoh_heap_free(tx_queue, buffer->tsoh); + } + buffer->tsoh = NULL; + } +} + /* * Add a socket buffer to a TX queue @@ -114,6 +154,9 @@ static inline int efx_enqueue_skb(struct efx_tx_queue *tx_queue, EFX_BUG_ON_PARANOID(tx_queue->write_count != tx_queue->insert_count); + if (skb_shinfo((struct sk_buff *)skb)->gso_size) + return efx_enqueue_skb_tso(tx_queue, skb); + /* Get size of the initial fragment */ len = skb_headlen(skb); @@ -166,6 +209,8 @@ static inline int efx_enqueue_skb(struct efx_tx_queue *tx_queue, insert_ptr = (tx_queue->insert_count & efx->type->txd_ring_mask); buffer = &tx_queue->buffer[insert_ptr]; + efx_tsoh_free(tx_queue, buffer); + EFX_BUG_ON_PARANOID(buffer->tsoh); EFX_BUG_ON_PARANOID(buffer->skb); EFX_BUG_ON_PARANOID(buffer->len); EFX_BUG_ON_PARANOID(buffer->continuation != 1); @@ -432,6 +477,9 @@ void efx_fini_tx_queue(struct efx_tx_queue *tx_queue) efx_release_tx_buffers(tx_queue); + /* Free up TSO header cache */ + efx_fini_tso(tx_queue); + /* Release queue's stop on port, if any */ if (tx_queue->stopped) { tx_queue->stopped = 0; @@ -450,3 +498,619 @@ void efx_remove_tx_queue(struct efx_tx_queue *tx_queue) } +/* Efx TCP segmentation acceleration. + * + * Why? Because by doing it here in the driver we can go significantly + * faster than the GSO. + * + * Requires TX checksum offload support. + */ + +/* Number of bytes inserted at the start of a TSO header buffer, + * similar to NET_IP_ALIGN. + */ +#if defined(__i386__) || defined(__x86_64__) +#define TSOH_OFFSET 0 +#else +#define TSOH_OFFSET NET_IP_ALIGN +#endif + +#define TSOH_BUFFER(tsoh) ((u8 *)(tsoh + 1) + TSOH_OFFSET) + +/* Total size of struct efx_tso_header, buffer and padding */ +#define TSOH_SIZE(hdr_len) \ + (sizeof(struct efx_tso_header) + TSOH_OFFSET + hdr_len) + +/* Size of blocks on free list. Larger blocks must be allocated from + * the heap. + */ +#define TSOH_STD_SIZE 128 + +#define PTR_DIFF(p1, p2) ((u8 *)(p1) - (u8 *)(p2)) +#define ETH_HDR_LEN(skb) (skb_network_header(skb) - (skb)->data) +#define SKB_TCP_OFF(skb) PTR_DIFF(tcp_hdr(skb), (skb)->data) +#define SKB_IPV4_OFF(skb) PTR_DIFF(ip_hdr(skb), (skb)->data) + +/** + * struct tso_state - TSO state for an SKB + * @remaining_len: Bytes of data we've yet to segment + * @seqnum: Current sequence number + * @packet_space: Remaining space in current packet + * @ifc: Input fragment cursor. + * Where we are in the current fragment of the incoming SKB. These + * values get updated in place when we split a fragment over + * multiple packets. + * @p: Parameters. + * These values are set once at the start of the TSO send and do + * not get changed as the routine progresses. + * + * The state used during segmentation. It is put into this data structure + * just to make it easy to pass into inline functions. + */ +struct tso_state { + unsigned remaining_len; + unsigned seqnum; + unsigned packet_space; + + struct { + /* DMA address of current position */ + dma_addr_t dma_addr; + /* Remaining length */ + unsigned int len; + /* DMA address and length of the whole fragment */ + unsigned int unmap_len; + dma_addr_t unmap_addr; + struct page *page; + unsigned page_off; + } ifc; + + struct { + /* The number of bytes of header */ + unsigned int header_length; + + /* The number of bytes to put in each outgoing segment. */ + int full_packet_size; + + /* Current IPv4 ID, host endian. */ + unsigned ipv4_id; + } p; +}; + + +/* + * Verify that our various assumptions about sk_buffs and the conditions + * under which TSO will be attempted hold true. + */ +static inline void efx_tso_check_safe(const struct sk_buff *skb) +{ + EFX_BUG_ON_PARANOID(skb->protocol != htons(ETH_P_IP)); + EFX_BUG_ON_PARANOID(((struct ethhdr *)skb->data)->h_proto != + skb->protocol); + EFX_BUG_ON_PARANOID(ip_hdr(skb)->protocol != IPPROTO_TCP); + EFX_BUG_ON_PARANOID((PTR_DIFF(tcp_hdr(skb), skb->data) + + (tcp_hdr(skb)->doff << 2u)) > + skb_headlen(skb)); +} + + +/* + * Allocate a page worth of efx_tso_header structures, and string them + * into the tx_queue->tso_headers_free linked list. Return 0 or -ENOMEM. + */ +static int efx_tsoh_block_alloc(struct efx_tx_queue *tx_queue) +{ + + struct pci_dev *pci_dev = tx_queue->efx->pci_dev; + struct efx_tso_header *tsoh; + dma_addr_t dma_addr; + u8 *base_kva, *kva; + + base_kva = pci_alloc_consistent(pci_dev, PAGE_SIZE, &dma_addr); + if (base_kva == NULL) { + EFX_ERR(tx_queue->efx, "Unable to allocate page for TSO" + " headers\n"); + return -ENOMEM; + } + + /* pci_alloc_consistent() allocates pages. */ + EFX_BUG_ON_PARANOID(dma_addr & (PAGE_SIZE - 1u)); + + for (kva = base_kva; kva < base_kva + PAGE_SIZE; kva += TSOH_STD_SIZE) { + tsoh = (struct efx_tso_header *)kva; + tsoh->dma_addr = dma_addr + (TSOH_BUFFER(tsoh) - base_kva); + tsoh->next = tx_queue->tso_headers_free; + tx_queue->tso_headers_free = tsoh; + } + + return 0; +} + + +/* Free up a TSO header, and all others in the same page. */ +static void efx_tsoh_block_free(struct efx_tx_queue *tx_queue, + struct efx_tso_header *tsoh, + struct pci_dev *pci_dev) +{ + struct efx_tso_header **p; + unsigned long base_kva; + dma_addr_t base_dma; + + base_kva = (unsigned long)tsoh & PAGE_MASK; + base_dma = tsoh->dma_addr & PAGE_MASK; + + p = &tx_queue->tso_headers_free; + while (*p != NULL) + if (((unsigned long)*p & PAGE_MASK) == base_kva) + *p = (*p)->next; + else + p = &(*p)->next; + + pci_free_consistent(pci_dev, PAGE_SIZE, (void *)base_kva, base_dma); +} + +static struct efx_tso_header * +efx_tsoh_heap_alloc(struct efx_tx_queue *tx_queue, size_t header_len) +{ + struct efx_tso_header *tsoh; + + tsoh = kmalloc(TSOH_SIZE(header_len), GFP_ATOMIC | GFP_DMA); + if (unlikely(!tsoh)) + return NULL; + + tsoh->dma_addr = pci_map_single(tx_queue->efx->pci_dev, + TSOH_BUFFER(tsoh), header_len, + PCI_DMA_TODEVICE); + if (unlikely(pci_dma_mapping_error(tsoh->dma_addr))) { + kfree(tsoh); + return NULL; + } + + tsoh->unmap_len = header_len; + return tsoh; +} + +static void +efx_tsoh_heap_free(struct efx_tx_queue *tx_queue, struct efx_tso_header *tsoh) +{ + pci_unmap_single(tx_queue->efx->pci_dev, + tsoh->dma_addr, tsoh->unmap_len, + PCI_DMA_TODEVICE); + kfree(tsoh); +} + +/** + * efx_tx_queue_insert - push descriptors onto the TX queue + * @tx_queue: Efx TX queue + * @dma_addr: DMA address of fragment + * @len: Length of fragment + * @skb: Only non-null for end of last segment + * @end_of_packet: True if last fragment in a packet + * @unmap_addr: DMA address of fragment for unmapping + * @unmap_len: Only set this in last segment of a fragment + * + * Push descriptors onto the TX queue. Return 0 on success or 1 if + * @tx_queue full. + */ +static int efx_tx_queue_insert(struct efx_tx_queue *tx_queue, + dma_addr_t dma_addr, unsigned len, + const struct sk_buff *skb, int end_of_packet, + dma_addr_t unmap_addr, unsigned unmap_len) +{ + struct efx_tx_buffer *buffer; + struct efx_nic *efx = tx_queue->efx; + unsigned dma_len, fill_level, insert_ptr, misalign; + int q_space; + + EFX_BUG_ON_PARANOID(len <= 0); + + fill_level = tx_queue->insert_count - tx_queue->old_read_count; + /* -1 as there is no way to represent all descriptors used */ + q_space = efx->type->txd_ring_mask - 1 - fill_level; + + while (1) { + if (unlikely(q_space-- <= 0)) { + /* It might be that completions have happened + * since the xmit path last checked. Update + * the xmit path's copy of read_count. + */ + ++tx_queue->stopped; + /* This memory barrier protects the change of + * stopped from the access of read_count. */ + smp_mb(); + tx_queue->old_read_count = + *(volatile unsigned *)&tx_queue->read_count; + fill_level = (tx_queue->insert_count + - tx_queue->old_read_count); + q_space = efx->type->txd_ring_mask - 1 - fill_level; + if (unlikely(q_space-- <= 0)) + return 1; + smp_mb(); + --tx_queue->stopped; + } + + insert_ptr = tx_queue->insert_count & efx->type->txd_ring_mask; + buffer = &tx_queue->buffer[insert_ptr]; + ++tx_queue->insert_count; + + EFX_BUG_ON_PARANOID(tx_queue->insert_count - + tx_queue->read_count > + efx->type->txd_ring_mask); + + efx_tsoh_free(tx_queue, buffer); + EFX_BUG_ON_PARANOID(buffer->len); + EFX_BUG_ON_PARANOID(buffer->unmap_len); + EFX_BUG_ON_PARANOID(buffer->skb); + EFX_BUG_ON_PARANOID(buffer->continuation != 1); + EFX_BUG_ON_PARANOID(buffer->tsoh); + + buffer->dma_addr = dma_addr; + + /* Ensure we do not cross a boundary unsupported by H/W */ + dma_len = (~dma_addr & efx->type->tx_dma_mask) + 1; + + misalign = (unsigned)dma_addr & efx->type->bug5391_mask; + if (misalign && dma_len + misalign > 512) + dma_len = 512 - misalign; + + /* If there is enough space to send then do so */ + if (dma_len >= len) + break; + + buffer->len = dma_len; /* Don't set the other members */ + dma_addr += dma_len; + len -= dma_len; + } + + EFX_BUG_ON_PARANOID(!len); + buffer->len = len; + buffer->skb = skb; + buffer->continuation = !end_of_packet; + buffer->unmap_addr = unmap_addr; + buffer->unmap_len = unmap_len; + return 0; +} + + +/* + * Put a TSO header into the TX queue. + * + * This is special-cased because we know that it is small enough to fit in + * a single fragment, and we know it doesn't cross a page boundary. It + * also allows us to not worry about end-of-packet etc. + */ +static inline void efx_tso_put_header(struct efx_tx_queue *tx_queue, + struct efx_tso_header *tsoh, unsigned len) +{ + struct efx_tx_buffer *buffer; + + buffer = &tx_queue->buffer[tx_queue->insert_count & + tx_queue->efx->type->txd_ring_mask]; + efx_tsoh_free(tx_queue, buffer); + EFX_BUG_ON_PARANOID(buffer->len); + EFX_BUG_ON_PARANOID(buffer->unmap_len); + EFX_BUG_ON_PARANOID(buffer->skb); + EFX_BUG_ON_PARANOID(buffer->continuation != 1); + EFX_BUG_ON_PARANOID(buffer->tsoh); + buffer->len = len; + buffer->dma_addr = tsoh->dma_addr; + buffer->tsoh = tsoh; + + ++tx_queue->insert_count; +} + + +/* Remove descriptors put into a tx_queue. */ +static void efx_enqueue_unwind(struct efx_tx_queue *tx_queue) +{ + struct efx_tx_buffer *buffer; + + /* Work backwards until we hit the original insert pointer value */ + while (tx_queue->insert_count != tx_queue->write_count) { + --tx_queue->insert_count; + buffer = &tx_queue->buffer[tx_queue->insert_count & + tx_queue->efx->type->txd_ring_mask]; + efx_tsoh_free(tx_queue, buffer); + EFX_BUG_ON_PARANOID(buffer->skb); + buffer->len = 0; + buffer->continuation = 1; + if (buffer->unmap_len) { + pci_unmap_page(tx_queue->efx->pci_dev, + buffer->unmap_addr, + buffer->unmap_len, PCI_DMA_TODEVICE); + buffer->unmap_len = 0; + } + } +} + + +/* Parse the SKB header and initialise state. */ +static inline void tso_start(struct tso_state *st, const struct sk_buff *skb) +{ + /* All ethernet/IP/TCP headers combined size is TCP header size + * plus offset of TCP header relative to start of packet. + */ + st->p.header_length = ((tcp_hdr(skb)->doff << 2u) + + PTR_DIFF(tcp_hdr(skb), skb->data)); + st->p.full_packet_size = (st->p.header_length + + skb_shinfo(skb)->gso_size); + + st->p.ipv4_id = ntohs(ip_hdr(skb)->id); + st->seqnum = ntohl(tcp_hdr(skb)->seq); + + EFX_BUG_ON_PARANOID(tcp_hdr(skb)->urg); + EFX_BUG_ON_PARANOID(tcp_hdr(skb)->syn); + EFX_BUG_ON_PARANOID(tcp_hdr(skb)->rst); + + st->packet_space = st->p.full_packet_size; + st->remaining_len = skb->len - st->p.header_length; +} + + +/** + * tso_get_fragment - record fragment details and map for DMA + * @st: TSO state + * @efx: Efx NIC + * @data: Pointer to fragment data + * @len: Length of fragment + * + * Record fragment details and map for DMA. Return 0 on success, or + * -%ENOMEM if DMA mapping fails. + */ +static inline int tso_get_fragment(struct tso_state *st, struct efx_nic *efx, + int len, struct page *page, int page_off) +{ + + st->ifc.unmap_addr = pci_map_page(efx->pci_dev, page, page_off, + len, PCI_DMA_TODEVICE); + if (likely(!pci_dma_mapping_error(st->ifc.unmap_addr))) { + st->ifc.unmap_len = len; + st->ifc.len = len; + st->ifc.dma_addr = st->ifc.unmap_addr; + st->ifc.page = page; + st->ifc.page_off = page_off; + return 0; + } + return -ENOMEM; +} + + +/** + * tso_fill_packet_with_fragment - form descriptors for the current fragment + * @tx_queue: Efx TX queue + * @skb: Socket buffer + * @st: TSO state + * + * Form descriptors for the current fragment, until we reach the end + * of fragment or end-of-packet. Return 0 on success, 1 if not enough + * space in @tx_queue. + */ +static inline int tso_fill_packet_with_fragment(struct efx_tx_queue *tx_queue, + const struct sk_buff *skb, + struct tso_state *st) +{ + + int n, end_of_packet, rc; + + if (st->ifc.len == 0) + return 0; + if (st->packet_space == 0) + return 0; + + EFX_BUG_ON_PARANOID(st->ifc.len <= 0); + EFX_BUG_ON_PARANOID(st->packet_space <= 0); + + n = min(st->ifc.len, st->packet_space); + + st->packet_space -= n; + st->remaining_len -= n; + st->ifc.len -= n; + st->ifc.page_off += n; + end_of_packet = st->remaining_len == 0 || st->packet_space == 0; + + rc = efx_tx_queue_insert(tx_queue, st->ifc.dma_addr, n, + st->remaining_len ? NULL : skb, + end_of_packet, st->ifc.unmap_addr, + st->ifc.len ? 0 : st->ifc.unmap_len); + + st->ifc.dma_addr += n; + + return rc; +} + + +/** + * tso_start_new_packet - generate a new header and prepare for the new packet + * @tx_queue: Efx TX queue + * @skb: Socket buffer + * @st: TSO state + * + * Generate a new header and prepare for the new packet. Return 0 on + * success, or -1 if failed to alloc header. + */ +static inline int tso_start_new_packet(struct efx_tx_queue *tx_queue, + const struct sk_buff *skb, + struct tso_state *st) +{ + struct efx_tso_header *tsoh; + struct iphdr *tsoh_iph; + struct tcphdr *tsoh_th; + unsigned ip_length; + u8 *header; + + /* Allocate a DMA-mapped header buffer. */ + if (likely(TSOH_SIZE(st->p.header_length) <= TSOH_STD_SIZE)) { + if (tx_queue->tso_headers_free == NULL) + if (efx_tsoh_block_alloc(tx_queue)) + return -1; + EFX_BUG_ON_PARANOID(!tx_queue->tso_headers_free); + tsoh = tx_queue->tso_headers_free; + tx_queue->tso_headers_free = tsoh->next; + tsoh->unmap_len = 0; + } else { + tx_queue->tso_long_headers++; + tsoh = efx_tsoh_heap_alloc(tx_queue, st->p.header_length); + if (unlikely(!tsoh)) + return -1; + } + + header = TSOH_BUFFER(tsoh); + tsoh_th = (struct tcphdr *)(header + SKB_TCP_OFF(skb)); + tsoh_iph = (struct iphdr *)(header + SKB_IPV4_OFF(skb)); + + /* Copy and update the headers. */ + memcpy(header, skb->data, st->p.header_length); + + tsoh_th->seq = htonl(st->seqnum); + st->seqnum += skb_shinfo(skb)->gso_size; + if (st->remaining_len > skb_shinfo(skb)->gso_size) { + /* This packet will not finish the TSO burst. */ + ip_length = st->p.full_packet_size - ETH_HDR_LEN(skb); + tsoh_th->fin = 0; + tsoh_th->psh = 0; + } else { + /* This packet will be the last in the TSO burst. */ + ip_length = (st->p.header_length - ETH_HDR_LEN(skb) + + st->remaining_len); + tsoh_th->fin = tcp_hdr(skb)->fin; + tsoh_th->psh = tcp_hdr(skb)->psh; + } + tsoh_iph->tot_len = htons(ip_length); + + /* Linux leaves suitable gaps in the IP ID space for us to fill. */ + tsoh_iph->id = htons(st->p.ipv4_id); + st->p.ipv4_id++; + + st->packet_space = skb_shinfo(skb)->gso_size; + ++tx_queue->tso_packets; + + /* Form a descriptor for this header. */ + efx_tso_put_header(tx_queue, tsoh, st->p.header_length); + + return 0; +} + + +/** + * efx_enqueue_skb_tso - segment and transmit a TSO socket buffer + * @tx_queue: Efx TX queue + * @skb: Socket buffer + * + * Context: You must hold netif_tx_lock() to call this function. + * + * Add socket buffer @skb to @tx_queue, doing TSO or return != 0 if + * @skb was not enqueued. In all cases @skb is consumed. Return + * %NETDEV_TX_OK or %NETDEV_TX_BUSY. + */ +static int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue, + const struct sk_buff *skb) +{ + int frag_i, rc, rc2 = NETDEV_TX_OK; + struct tso_state state; + skb_frag_t *f; + + /* Verify TSO is safe - these checks should never fail. */ + efx_tso_check_safe(skb); + + EFX_BUG_ON_PARANOID(tx_queue->write_count != tx_queue->insert_count); + + tso_start(&state, skb); + + /* Assume that skb header area contains exactly the headers, and + * all payload is in the frag list. + */ + if (skb_headlen(skb) == state.p.header_length) { + /* Grab the first payload fragment. */ + EFX_BUG_ON_PARANOID(skb_shinfo(skb)->nr_frags < 1); + frag_i = 0; + f = &skb_shinfo(skb)->frags[frag_i]; + rc = tso_get_fragment(&state, tx_queue->efx, + f->size, f->page, f->page_offset); + if (rc) + goto mem_err; + } else { + /* It may look like this code fragment assumes that the + * skb->data portion does not cross a page boundary, but + * that is not the case. It is guaranteed to be direct + * mapped memory, and therefore is physically contiguous, + * and so DMA will work fine. kmap_atomic() on this region + * will just return the direct mapping, so that will work + * too. + */ + int page_off = (unsigned long)skb->data & (PAGE_SIZE - 1); + int hl = state.p.header_length; + rc = tso_get_fragment(&state, tx_queue->efx, + skb_headlen(skb) - hl, + virt_to_page(skb->data), page_off + hl); + if (rc) + goto mem_err; + frag_i = -1; + } + + if (tso_start_new_packet(tx_queue, skb, &state) < 0) + goto mem_err; + + while (1) { + rc = tso_fill_packet_with_fragment(tx_queue, skb, &state); + if (unlikely(rc)) + goto stop; + + /* Move onto the next fragment? */ + if (state.ifc.len == 0) { + if (++frag_i >= skb_shinfo(skb)->nr_frags) + /* End of payload reached. */ + break; + f = &skb_shinfo(skb)->frags[frag_i]; + rc = tso_get_fragment(&state, tx_queue->efx, + f->size, f->page, f->page_offset); + if (rc) + goto mem_err; + } + + /* Start at new packet? */ + if (state.packet_space == 0 && + tso_start_new_packet(tx_queue, skb, &state) < 0) + goto mem_err; + } + + /* Pass off to hardware */ + falcon_push_buffers(tx_queue); + + tx_queue->tso_bursts++; + return NETDEV_TX_OK; + + mem_err: + EFX_ERR(tx_queue->efx, "Out of memory for TSO headers, or PCI mapping" + " error\n"); + dev_kfree_skb_any((struct sk_buff *)skb); + goto unwind; + + stop: + rc2 = NETDEV_TX_BUSY; + + /* Stop the queue if it wasn't stopped before. */ + if (tx_queue->stopped == 1) + efx_stop_queue(tx_queue->efx); + + unwind: + efx_enqueue_unwind(tx_queue); + return rc2; +} + + +/* + * Free up all TSO datastructures associated with tx_queue. This + * routine should be called only once the tx_queue is both empty and + * will no longer be used. + */ +static void efx_fini_tso(struct efx_tx_queue *tx_queue) +{ + unsigned i; + + if (tx_queue->buffer) + for (i = 0; i <= tx_queue->efx->type->txd_ring_mask; ++i) + efx_tsoh_free(tx_queue, &tx_queue->buffer[i]); + + while (tx_queue->tso_headers_free != NULL) + efx_tsoh_block_free(tx_queue, tx_queue->tso_headers_free, + tx_queue->efx->pci_dev); +} diff --git a/drivers/net/sfc/xfp_phy.c b/drivers/net/sfc/xfp_phy.c index 66dd5bf1eaa90dec3a0883dc5914b1642b5e6a53..3b9f9ddbc3725c9ed95e7b48bb910fc0aec57961 100644 --- a/drivers/net/sfc/xfp_phy.c +++ b/drivers/net/sfc/xfp_phy.c @@ -24,6 +24,10 @@ MDIO_MMDREG_DEVS0_PMAPMD | \ MDIO_MMDREG_DEVS0_PHYXS) +#define XFP_LOOPBACKS ((1 << LOOPBACK_PCS) | \ + (1 << LOOPBACK_PMAPMD) | \ + (1 << LOOPBACK_NETWORK)) + /****************************************************************************/ /* Quake-specific MDIO registers */ #define MDIO_QUAKE_LED0_REG (0xD006) @@ -35,6 +39,10 @@ void xfp_set_led(struct efx_nic *p, int led, int mode) mode); } +struct xfp_phy_data { + int tx_disabled; +}; + #define XFP_MAX_RESET_TIME 500 #define XFP_RESET_WAIT 10 @@ -72,18 +80,31 @@ static int xfp_reset_phy(struct efx_nic *efx) static int xfp_phy_init(struct efx_nic *efx) { + struct xfp_phy_data *phy_data; u32 devid = mdio_clause45_read_id(efx, MDIO_MMD_PHYXS); int rc; + phy_data = kzalloc(sizeof(struct xfp_phy_data), GFP_KERNEL); + efx->phy_data = (void *) phy_data; + EFX_INFO(efx, "XFP: PHY ID reg %x (OUI %x model %x revision" " %x)\n", devid, MDIO_ID_OUI(devid), MDIO_ID_MODEL(devid), MDIO_ID_REV(devid)); + phy_data->tx_disabled = efx->tx_disabled; + rc = xfp_reset_phy(efx); EFX_INFO(efx, "XFP: PHY init %s.\n", rc ? "failed" : "successful"); + if (rc < 0) + goto fail; + return 0; + + fail: + kfree(efx->phy_data); + efx->phy_data = NULL; return rc; } @@ -110,6 +131,16 @@ static int xfp_phy_check_hw(struct efx_nic *efx) static void xfp_phy_reconfigure(struct efx_nic *efx) { + struct xfp_phy_data *phy_data = efx->phy_data; + + /* Reset the PHY when moving from tx off to tx on */ + if (phy_data->tx_disabled && !efx->tx_disabled) + xfp_reset_phy(efx); + + mdio_clause45_transmit_disable(efx); + mdio_clause45_phy_reconfigure(efx); + + phy_data->tx_disabled = efx->tx_disabled; efx->link_up = xfp_link_ok(efx); efx->link_options = GM_LPA_10000FULL; } @@ -119,6 +150,10 @@ static void xfp_phy_fini(struct efx_nic *efx) { /* Clobber the LED if it was blinking */ efx->board_info.blink(efx, 0); + + /* Free the context block */ + kfree(efx->phy_data); + efx->phy_data = NULL; } struct efx_phy_operations falcon_xfp_phy_ops = { @@ -129,4 +164,5 @@ struct efx_phy_operations falcon_xfp_phy_ops = { .clear_interrupt = xfp_phy_clear_interrupt, .reset_xaui = efx_port_dummy_op_void, .mmds = XFP_REQUIRED_DEVS, + .loopbacks = XFP_LOOPBACKS, }; diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index 7bb3ba9bcbd8519ea58804dba861e1b6e2001b79..c0a5eea20007d461660d79f176d2eed00c7e7903 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h @@ -1966,13 +1966,13 @@ struct sky2_status_le { struct tx_ring_info { struct sk_buff *skb; DECLARE_PCI_UNMAP_ADDR(mapaddr); - DECLARE_PCI_UNMAP_ADDR(maplen); + DECLARE_PCI_UNMAP_LEN(maplen); }; struct rx_ring_info { struct sk_buff *skb; dma_addr_t data_addr; - DECLARE_PCI_UNMAP_ADDR(data_size); + DECLARE_PCI_UNMAP_LEN(data_size); dma_addr_t frag_addr[ETH_JUMBO_MTU >> PAGE_SHIFT]; }; diff --git a/drivers/net/sun3lance.c b/drivers/net/sun3lance.c index f8d46134dacaeaa16f66a2d98b8ce2faad4616f2..359452a06c67d7160e444ee3ab893afec2747f6d 100644 --- a/drivers/net/sun3lance.c +++ b/drivers/net/sun3lance.c @@ -250,6 +250,9 @@ struct net_device * __init sun3lance_probe(int unit) static int found; int err = -ENODEV; + if (!MACH_IS_SUN3 && !MACH_IS_SUN3X) + return ERR_PTR(-ENODEV); + /* check that this machine has an onboard lance */ switch(idprom->id_machtype) { case SM_SUN3|SM_3_50: diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c index a59c1f224aa8ef230f8e42f9aa8200373417b70f..2511ca7a12aa168eb09bd6de536db8f88a99cbd6 100644 --- a/drivers/net/tulip/uli526x.c +++ b/drivers/net/tulip/uli526x.c @@ -434,10 +434,6 @@ static int uli526x_open(struct net_device *dev) ULI526X_DBUG(0, "uli526x_open", 0); - ret = request_irq(dev->irq, &uli526x_interrupt, IRQF_SHARED, dev->name, dev); - if (ret) - return ret; - /* system variable init */ db->cr6_data = CR6_DEFAULT | uli526x_cr6_user_set; db->tx_packet_cnt = 0; @@ -456,6 +452,10 @@ static int uli526x_open(struct net_device *dev) /* Initialize ULI526X board */ uli526x_init(dev); + ret = request_irq(dev->irq, &uli526x_interrupt, IRQF_SHARED, dev->name, dev); + if (ret) + return ret; + /* Active System Interface */ netif_wake_queue(dev); @@ -1368,6 +1368,12 @@ static void update_cr6(u32 cr6_data, unsigned long ioaddr) * This setup frame initialize ULI526X address filter mode */ +#ifdef __BIG_ENDIAN +#define FLT_SHIFT 16 +#else +#define FLT_SHIFT 0 +#endif + static void send_filter_frame(struct net_device *dev, int mc_cnt) { struct uli526x_board_info *db = netdev_priv(dev); @@ -1384,27 +1390,27 @@ static void send_filter_frame(struct net_device *dev, int mc_cnt) /* Node address */ addrptr = (u16 *) dev->dev_addr; - *suptr++ = addrptr[0]; - *suptr++ = addrptr[1]; - *suptr++ = addrptr[2]; + *suptr++ = addrptr[0] << FLT_SHIFT; + *suptr++ = addrptr[1] << FLT_SHIFT; + *suptr++ = addrptr[2] << FLT_SHIFT; /* broadcast address */ - *suptr++ = 0xffff; - *suptr++ = 0xffff; - *suptr++ = 0xffff; + *suptr++ = 0xffff << FLT_SHIFT; + *suptr++ = 0xffff << FLT_SHIFT; + *suptr++ = 0xffff << FLT_SHIFT; /* fit the multicast address */ for (mcptr = dev->mc_list, i = 0; i < mc_cnt; i++, mcptr = mcptr->next) { addrptr = (u16 *) mcptr->dmi_addr; - *suptr++ = addrptr[0]; - *suptr++ = addrptr[1]; - *suptr++ = addrptr[2]; + *suptr++ = addrptr[0] << FLT_SHIFT; + *suptr++ = addrptr[1] << FLT_SHIFT; + *suptr++ = addrptr[2] << FLT_SHIFT; } for (; i<14; i++) { - *suptr++ = 0xffff; - *suptr++ = 0xffff; - *suptr++ = 0xffff; + *suptr++ = 0xffff << FLT_SHIFT; + *suptr++ = 0xffff << FLT_SHIFT; + *suptr++ = 0xffff << FLT_SHIFT; } /* prepare the setup frame */ diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 281ce3d395324787c8b986f0dae5648e793aa853..ca0bdac07a7841c23b0ddc10010ae310e28df999 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -62,7 +62,6 @@ #endif /* UGETH_VERBOSE_DEBUG */ #define UGETH_MSG_DEFAULT (NETIF_MSG_IFUP << 1 ) - 1 -void uec_set_ethtool_ops(struct net_device *netdev); static DEFINE_SPINLOCK(ugeth_lock); @@ -216,7 +215,8 @@ static struct list_head *dequeue(struct list_head *lh) } } -static struct sk_buff *get_new_skb(struct ucc_geth_private *ugeth, u8 *bd) +static struct sk_buff *get_new_skb(struct ucc_geth_private *ugeth, + u8 __iomem *bd) { struct sk_buff *skb = NULL; @@ -236,21 +236,22 @@ static struct sk_buff *get_new_skb(struct ucc_geth_private *ugeth, u8 *bd) skb->dev = ugeth->dev; - out_be32(&((struct qe_bd *)bd)->buf, + out_be32(&((struct qe_bd __iomem *)bd)->buf, dma_map_single(NULL, skb->data, ugeth->ug_info->uf_info.max_rx_buf_length + UCC_GETH_RX_DATA_BUF_ALIGNMENT, DMA_FROM_DEVICE)); - out_be32((u32 *)bd, (R_E | R_I | (in_be32((u32 *)bd) & R_W))); + out_be32((u32 __iomem *)bd, + (R_E | R_I | (in_be32((u32 __iomem*)bd) & R_W))); return skb; } static int rx_bd_buffer_set(struct ucc_geth_private *ugeth, u8 rxQ) { - u8 *bd; + u8 __iomem *bd; u32 bd_status; struct sk_buff *skb; int i; @@ -259,7 +260,7 @@ static int rx_bd_buffer_set(struct ucc_geth_private *ugeth, u8 rxQ) i = 0; do { - bd_status = in_be32((u32*)bd); + bd_status = in_be32((u32 __iomem *)bd); skb = get_new_skb(ugeth, bd); if (!skb) /* If can not allocate data buffer, @@ -277,7 +278,7 @@ static int rx_bd_buffer_set(struct ucc_geth_private *ugeth, u8 rxQ) } static int fill_init_enet_entries(struct ucc_geth_private *ugeth, - volatile u32 *p_start, + u32 *p_start, u8 num_entries, u32 thread_size, u32 thread_alignment, @@ -316,7 +317,7 @@ static int fill_init_enet_entries(struct ucc_geth_private *ugeth, } static int return_init_enet_entries(struct ucc_geth_private *ugeth, - volatile u32 *p_start, + u32 *p_start, u8 num_entries, enum qe_risc_allocation risc, int skip_page_for_first_entry) @@ -326,21 +327,22 @@ static int return_init_enet_entries(struct ucc_geth_private *ugeth, int snum; for (i = 0; i < num_entries; i++) { + u32 val = *p_start; + /* Check that this entry was actually valid -- needed in case failed in allocations */ - if ((*p_start & ENET_INIT_PARAM_RISC_MASK) == risc) { + if ((val & ENET_INIT_PARAM_RISC_MASK) == risc) { snum = - (u32) (*p_start & ENET_INIT_PARAM_SNUM_MASK) >> + (u32) (val & ENET_INIT_PARAM_SNUM_MASK) >> ENET_INIT_PARAM_SNUM_SHIFT; qe_put_snum((u8) snum); if (!((i == 0) && skip_page_for_first_entry)) { /* First entry of Rx does not have page */ init_enet_offset = - (in_be32(p_start) & - ENET_INIT_PARAM_PTR_MASK); + (val & ENET_INIT_PARAM_PTR_MASK); qe_muram_free(init_enet_offset); } - *(p_start++) = 0; /* Just for cosmetics */ + *p_start++ = 0; } } @@ -349,7 +351,7 @@ static int return_init_enet_entries(struct ucc_geth_private *ugeth, #ifdef DEBUG static int dump_init_enet_entries(struct ucc_geth_private *ugeth, - volatile u32 *p_start, + u32 __iomem *p_start, u8 num_entries, u32 thread_size, enum qe_risc_allocation risc, @@ -360,11 +362,13 @@ static int dump_init_enet_entries(struct ucc_geth_private *ugeth, int snum; for (i = 0; i < num_entries; i++) { + u32 val = in_be32(p_start); + /* Check that this entry was actually valid -- needed in case failed in allocations */ - if ((*p_start & ENET_INIT_PARAM_RISC_MASK) == risc) { + if ((val & ENET_INIT_PARAM_RISC_MASK) == risc) { snum = - (u32) (*p_start & ENET_INIT_PARAM_SNUM_MASK) >> + (u32) (val & ENET_INIT_PARAM_SNUM_MASK) >> ENET_INIT_PARAM_SNUM_SHIFT; qe_put_snum((u8) snum); if (!((i == 0) && skip_page_for_first_entry)) { @@ -440,7 +444,7 @@ static int hw_add_addr_in_paddr(struct ucc_geth_private *ugeth, static int hw_clear_addr_in_paddr(struct ucc_geth_private *ugeth, u8 paddr_num) { - struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt; + struct ucc_geth_82xx_address_filtering_pram __iomem *p_82xx_addr_filt; if (!(paddr_num < NUM_OF_PADDRS)) { ugeth_warn("%s: Illagel paddr_num.", __FUNCTION__); @@ -448,7 +452,7 @@ static int hw_clear_addr_in_paddr(struct ucc_geth_private *ugeth, u8 paddr_num) } p_82xx_addr_filt = - (struct ucc_geth_82xx_address_filtering_pram *) ugeth->p_rx_glbl_pram-> + (struct ucc_geth_82xx_address_filtering_pram __iomem *) ugeth->p_rx_glbl_pram-> addressfiltering; /* Writing address ff.ff.ff.ff.ff.ff disables address @@ -463,11 +467,11 @@ static int hw_clear_addr_in_paddr(struct ucc_geth_private *ugeth, u8 paddr_num) static void hw_add_addr_in_hash(struct ucc_geth_private *ugeth, u8 *p_enet_addr) { - struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt; + struct ucc_geth_82xx_address_filtering_pram __iomem *p_82xx_addr_filt; u32 cecr_subblock; p_82xx_addr_filt = - (struct ucc_geth_82xx_address_filtering_pram *) ugeth->p_rx_glbl_pram-> + (struct ucc_geth_82xx_address_filtering_pram __iomem *) ugeth->p_rx_glbl_pram-> addressfiltering; cecr_subblock = @@ -487,7 +491,7 @@ static void hw_add_addr_in_hash(struct ucc_geth_private *ugeth, static void magic_packet_detection_enable(struct ucc_geth_private *ugeth) { struct ucc_fast_private *uccf; - struct ucc_geth *ug_regs; + struct ucc_geth __iomem *ug_regs; u32 maccfg2, uccm; uccf = ugeth->uccf; @@ -507,7 +511,7 @@ static void magic_packet_detection_enable(struct ucc_geth_private *ugeth) static void magic_packet_detection_disable(struct ucc_geth_private *ugeth) { struct ucc_fast_private *uccf; - struct ucc_geth *ug_regs; + struct ucc_geth __iomem *ug_regs; u32 maccfg2, uccm; uccf = ugeth->uccf; @@ -538,13 +542,13 @@ static void get_statistics(struct ucc_geth_private *ugeth, rx_firmware_statistics, struct ucc_geth_hardware_statistics *hardware_statistics) { - struct ucc_fast *uf_regs; - struct ucc_geth *ug_regs; + struct ucc_fast __iomem *uf_regs; + struct ucc_geth __iomem *ug_regs; struct ucc_geth_tx_firmware_statistics_pram *p_tx_fw_statistics_pram; struct ucc_geth_rx_firmware_statistics_pram *p_rx_fw_statistics_pram; ug_regs = ugeth->ug_regs; - uf_regs = (struct ucc_fast *) ug_regs; + uf_regs = (struct ucc_fast __iomem *) ug_regs; p_tx_fw_statistics_pram = ugeth->p_tx_fw_statistics_pram; p_rx_fw_statistics_pram = ugeth->p_rx_fw_statistics_pram; @@ -1132,9 +1136,9 @@ static void dump_regs(struct ucc_geth_private *ugeth) } #endif /* DEBUG */ -static void init_default_reg_vals(volatile u32 *upsmr_register, - volatile u32 *maccfg1_register, - volatile u32 *maccfg2_register) +static void init_default_reg_vals(u32 __iomem *upsmr_register, + u32 __iomem *maccfg1_register, + u32 __iomem *maccfg2_register) { out_be32(upsmr_register, UCC_GETH_UPSMR_INIT); out_be32(maccfg1_register, UCC_GETH_MACCFG1_INIT); @@ -1148,7 +1152,7 @@ static int init_half_duplex_params(int alt_beb, u8 alt_beb_truncation, u8 max_retransmissions, u8 collision_window, - volatile u32 *hafdup_register) + u32 __iomem *hafdup_register) { u32 value = 0; @@ -1180,7 +1184,7 @@ static int init_inter_frame_gap_params(u8 non_btb_cs_ipg, u8 non_btb_ipg, u8 min_ifg, u8 btb_ipg, - volatile u32 *ipgifg_register) + u32 __iomem *ipgifg_register) { u32 value = 0; @@ -1215,9 +1219,9 @@ int init_flow_control_params(u32 automatic_flow_control_mode, int tx_flow_control_enable, u16 pause_period, u16 extension_field, - volatile u32 *upsmr_register, - volatile u32 *uempr_register, - volatile u32 *maccfg1_register) + u32 __iomem *upsmr_register, + u32 __iomem *uempr_register, + u32 __iomem *maccfg1_register) { u32 value = 0; @@ -1243,8 +1247,8 @@ int init_flow_control_params(u32 automatic_flow_control_mode, static int init_hw_statistics_gathering_mode(int enable_hardware_statistics, int auto_zero_hardware_statistics, - volatile u32 *upsmr_register, - volatile u16 *uescr_register) + u32 __iomem *upsmr_register, + u16 __iomem *uescr_register) { u32 upsmr_value = 0; u16 uescr_value = 0; @@ -1270,12 +1274,12 @@ static int init_hw_statistics_gathering_mode(int enable_hardware_statistics, static int init_firmware_statistics_gathering_mode(int enable_tx_firmware_statistics, int enable_rx_firmware_statistics, - volatile u32 *tx_rmon_base_ptr, + u32 __iomem *tx_rmon_base_ptr, u32 tx_firmware_statistics_structure_address, - volatile u32 *rx_rmon_base_ptr, + u32 __iomem *rx_rmon_base_ptr, u32 rx_firmware_statistics_structure_address, - volatile u16 *temoder_register, - volatile u32 *remoder_register) + u16 __iomem *temoder_register, + u32 __iomem *remoder_register) { /* Note: this function does not check if */ /* the parameters it receives are NULL */ @@ -1307,8 +1311,8 @@ static int init_mac_station_addr_regs(u8 address_byte_0, u8 address_byte_3, u8 address_byte_4, u8 address_byte_5, - volatile u32 *macstnaddr1_register, - volatile u32 *macstnaddr2_register) + u32 __iomem *macstnaddr1_register, + u32 __iomem *macstnaddr2_register) { u32 value = 0; @@ -1344,7 +1348,7 @@ static int init_mac_station_addr_regs(u8 address_byte_0, } static int init_check_frame_length_mode(int length_check, - volatile u32 *maccfg2_register) + u32 __iomem *maccfg2_register) { u32 value = 0; @@ -1360,7 +1364,7 @@ static int init_check_frame_length_mode(int length_check, } static int init_preamble_length(u8 preamble_length, - volatile u32 *maccfg2_register) + u32 __iomem *maccfg2_register) { u32 value = 0; @@ -1376,7 +1380,7 @@ static int init_preamble_length(u8 preamble_length, static int init_rx_parameters(int reject_broadcast, int receive_short_frames, - int promiscuous, volatile u32 *upsmr_register) + int promiscuous, u32 __iomem *upsmr_register) { u32 value = 0; @@ -1403,7 +1407,7 @@ static int init_rx_parameters(int reject_broadcast, } static int init_max_rx_buff_len(u16 max_rx_buf_len, - volatile u16 *mrblr_register) + u16 __iomem *mrblr_register) { /* max_rx_buf_len value must be a multiple of 128 */ if ((max_rx_buf_len == 0) @@ -1415,8 +1419,8 @@ static int init_max_rx_buff_len(u16 max_rx_buf_len, } static int init_min_frame_len(u16 min_frame_length, - volatile u16 *minflr_register, - volatile u16 *mrblr_register) + u16 __iomem *minflr_register, + u16 __iomem *mrblr_register) { u16 mrblr_value = 0; @@ -1431,8 +1435,8 @@ static int init_min_frame_len(u16 min_frame_length, static int adjust_enet_interface(struct ucc_geth_private *ugeth) { struct ucc_geth_info *ug_info; - struct ucc_geth *ug_regs; - struct ucc_fast *uf_regs; + struct ucc_geth __iomem *ug_regs; + struct ucc_fast __iomem *uf_regs; int ret_val; u32 upsmr, maccfg2, tbiBaseAddress; u16 value; @@ -1517,8 +1521,8 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth) static void adjust_link(struct net_device *dev) { struct ucc_geth_private *ugeth = netdev_priv(dev); - struct ucc_geth *ug_regs; - struct ucc_fast *uf_regs; + struct ucc_geth __iomem *ug_regs; + struct ucc_fast __iomem *uf_regs; struct phy_device *phydev = ugeth->phydev; unsigned long flags; int new_state = 0; @@ -1678,9 +1682,9 @@ static int ugeth_graceful_stop_rx(struct ucc_geth_private * ugeth) uccf = ugeth->uccf; /* Clear acknowledge bit */ - temp = ugeth->p_rx_glbl_pram->rxgstpack; + temp = in_8(&ugeth->p_rx_glbl_pram->rxgstpack); temp &= ~GRACEFUL_STOP_ACKNOWLEDGE_RX; - ugeth->p_rx_glbl_pram->rxgstpack = temp; + out_8(&ugeth->p_rx_glbl_pram->rxgstpack, temp); /* Keep issuing command and checking acknowledge bit until it is asserted, according to spec */ @@ -1692,7 +1696,7 @@ static int ugeth_graceful_stop_rx(struct ucc_geth_private * ugeth) qe_issue_cmd(QE_GRACEFUL_STOP_RX, cecr_subblock, QE_CR_PROTOCOL_ETHERNET, 0); - temp = ugeth->p_rx_glbl_pram->rxgstpack; + temp = in_8(&ugeth->p_rx_glbl_pram->rxgstpack); } while (!(temp & GRACEFUL_STOP_ACKNOWLEDGE_RX)); uccf->stopped_rx = 1; @@ -1991,19 +1995,20 @@ static int ugeth_82xx_filtering_clear_all_addr_in_hash(struct ucc_geth_private * enum enet_addr_type enet_addr_type) { - struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt; + struct ucc_geth_82xx_address_filtering_pram __iomem *p_82xx_addr_filt; struct ucc_fast_private *uccf; enum comm_dir comm_dir; struct list_head *p_lh; u16 i, num; - u32 *addr_h, *addr_l; + u32 __iomem *addr_h; + u32 __iomem *addr_l; u8 *p_counter; uccf = ugeth->uccf; p_82xx_addr_filt = - (struct ucc_geth_82xx_address_filtering_pram *) ugeth->p_rx_glbl_pram-> - addressfiltering; + (struct ucc_geth_82xx_address_filtering_pram __iomem *) + ugeth->p_rx_glbl_pram->addressfiltering; if (enet_addr_type == ENET_ADDR_TYPE_GROUP) { addr_h = &(p_82xx_addr_filt->gaddr_h); @@ -2079,7 +2084,7 @@ static int ugeth_82xx_filtering_clear_addr_in_paddr(struct ucc_geth_private *uge static void ucc_geth_memclean(struct ucc_geth_private *ugeth) { u16 i, j; - u8 *bd; + u8 __iomem *bd; if (!ugeth) return; @@ -2154,8 +2159,8 @@ static void ucc_geth_memclean(struct ucc_geth_private *ugeth) for (j = 0; j < ugeth->ug_info->bdRingLenTx[i]; j++) { if (ugeth->tx_skbuff[i][j]) { dma_unmap_single(NULL, - ((struct qe_bd *)bd)->buf, - (in_be32((u32 *)bd) & + in_be32(&((struct qe_bd __iomem *)bd)->buf), + (in_be32((u32 __iomem *)bd) & BD_LENGTH_MASK), DMA_TO_DEVICE); dev_kfree_skb_any(ugeth->tx_skbuff[i][j]); @@ -2182,7 +2187,7 @@ static void ucc_geth_memclean(struct ucc_geth_private *ugeth) for (j = 0; j < ugeth->ug_info->bdRingLenRx[i]; j++) { if (ugeth->rx_skbuff[i][j]) { dma_unmap_single(NULL, - ((struct qe_bd *)bd)->buf, + in_be32(&((struct qe_bd __iomem *)bd)->buf), ugeth->ug_info-> uf_info.max_rx_buf_length + UCC_GETH_RX_DATA_BUF_ALIGNMENT, @@ -2218,8 +2223,8 @@ static void ucc_geth_set_multi(struct net_device *dev) { struct ucc_geth_private *ugeth; struct dev_mc_list *dmi; - struct ucc_fast *uf_regs; - struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt; + struct ucc_fast __iomem *uf_regs; + struct ucc_geth_82xx_address_filtering_pram __iomem *p_82xx_addr_filt; int i; ugeth = netdev_priv(dev); @@ -2228,14 +2233,14 @@ static void ucc_geth_set_multi(struct net_device *dev) if (dev->flags & IFF_PROMISC) { - uf_regs->upsmr |= UPSMR_PRO; + out_be32(&uf_regs->upsmr, in_be32(&uf_regs->upsmr) | UPSMR_PRO); } else { - uf_regs->upsmr &= ~UPSMR_PRO; + out_be32(&uf_regs->upsmr, in_be32(&uf_regs->upsmr)&~UPSMR_PRO); p_82xx_addr_filt = - (struct ucc_geth_82xx_address_filtering_pram *) ugeth-> + (struct ucc_geth_82xx_address_filtering_pram __iomem *) ugeth-> p_rx_glbl_pram->addressfiltering; if (dev->flags & IFF_ALLMULTI) { @@ -2270,7 +2275,7 @@ static void ucc_geth_set_multi(struct net_device *dev) static void ucc_geth_stop(struct ucc_geth_private *ugeth) { - struct ucc_geth *ug_regs = ugeth->ug_regs; + struct ucc_geth __iomem *ug_regs = ugeth->ug_regs; struct phy_device *phydev = ugeth->phydev; u32 tempval; @@ -2419,20 +2424,20 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth) return -ENOMEM; } - ugeth->ug_regs = (struct ucc_geth *) ioremap(uf_info->regs, sizeof(struct ucc_geth)); + ugeth->ug_regs = (struct ucc_geth __iomem *) ioremap(uf_info->regs, sizeof(struct ucc_geth)); return 0; } static int ucc_geth_startup(struct ucc_geth_private *ugeth) { - struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt; - struct ucc_geth_init_pram *p_init_enet_pram; + struct ucc_geth_82xx_address_filtering_pram __iomem *p_82xx_addr_filt; + struct ucc_geth_init_pram __iomem *p_init_enet_pram; struct ucc_fast_private *uccf; struct ucc_geth_info *ug_info; struct ucc_fast_info *uf_info; - struct ucc_fast *uf_regs; - struct ucc_geth *ug_regs; + struct ucc_fast __iomem *uf_regs; + struct ucc_geth __iomem *ug_regs; int ret_val = -EINVAL; u32 remoder = UCC_GETH_REMODER_INIT; u32 init_enet_pram_offset, cecr_subblock, command, maccfg1; @@ -2440,7 +2445,8 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) u16 temoder = UCC_GETH_TEMODER_INIT; u16 test; u8 function_code = 0; - u8 *bd, *endOfRing; + u8 __iomem *bd; + u8 __iomem *endOfRing; u8 numThreadsRxNumerical, numThreadsTxNumerical; ugeth_vdbg("%s: IN", __FUNCTION__); @@ -2602,11 +2608,11 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) if (UCC_GETH_TX_BD_RING_ALIGNMENT > 4) align = UCC_GETH_TX_BD_RING_ALIGNMENT; ugeth->tx_bd_ring_offset[j] = - kmalloc((u32) (length + align), GFP_KERNEL); + (u32) kmalloc((u32) (length + align), GFP_KERNEL); if (ugeth->tx_bd_ring_offset[j] != 0) ugeth->p_tx_bd_ring[j] = - (void*)((ugeth->tx_bd_ring_offset[j] + + (u8 __iomem *)((ugeth->tx_bd_ring_offset[j] + align) & ~(align - 1)); } else if (uf_info->bd_mem_part == MEM_PART_MURAM) { ugeth->tx_bd_ring_offset[j] = @@ -2614,7 +2620,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) UCC_GETH_TX_BD_RING_ALIGNMENT); if (!IS_ERR_VALUE(ugeth->tx_bd_ring_offset[j])) ugeth->p_tx_bd_ring[j] = - (u8 *) qe_muram_addr(ugeth-> + (u8 __iomem *) qe_muram_addr(ugeth-> tx_bd_ring_offset[j]); } if (!ugeth->p_tx_bd_ring[j]) { @@ -2626,8 +2632,8 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) return -ENOMEM; } /* Zero unused end of bd ring, according to spec */ - memset(ugeth->p_tx_bd_ring[j] + - ug_info->bdRingLenTx[j] * sizeof(struct qe_bd), 0, + memset_io((void __iomem *)(ugeth->p_tx_bd_ring[j] + + ug_info->bdRingLenTx[j] * sizeof(struct qe_bd)), 0, length - ug_info->bdRingLenTx[j] * sizeof(struct qe_bd)); } @@ -2639,10 +2645,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) if (UCC_GETH_RX_BD_RING_ALIGNMENT > 4) align = UCC_GETH_RX_BD_RING_ALIGNMENT; ugeth->rx_bd_ring_offset[j] = - kmalloc((u32) (length + align), GFP_KERNEL); + (u32) kmalloc((u32) (length + align), GFP_KERNEL); if (ugeth->rx_bd_ring_offset[j] != 0) ugeth->p_rx_bd_ring[j] = - (void*)((ugeth->rx_bd_ring_offset[j] + + (u8 __iomem *)((ugeth->rx_bd_ring_offset[j] + align) & ~(align - 1)); } else if (uf_info->bd_mem_part == MEM_PART_MURAM) { ugeth->rx_bd_ring_offset[j] = @@ -2650,7 +2656,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) UCC_GETH_RX_BD_RING_ALIGNMENT); if (!IS_ERR_VALUE(ugeth->rx_bd_ring_offset[j])) ugeth->p_rx_bd_ring[j] = - (u8 *) qe_muram_addr(ugeth-> + (u8 __iomem *) qe_muram_addr(ugeth-> rx_bd_ring_offset[j]); } if (!ugeth->p_rx_bd_ring[j]) { @@ -2685,14 +2691,14 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) bd = ugeth->confBd[j] = ugeth->txBd[j] = ugeth->p_tx_bd_ring[j]; for (i = 0; i < ug_info->bdRingLenTx[j]; i++) { /* clear bd buffer */ - out_be32(&((struct qe_bd *)bd)->buf, 0); + out_be32(&((struct qe_bd __iomem *)bd)->buf, 0); /* set bd status and length */ - out_be32((u32 *)bd, 0); + out_be32((u32 __iomem *)bd, 0); bd += sizeof(struct qe_bd); } bd -= sizeof(struct qe_bd); /* set bd status and length */ - out_be32((u32 *)bd, T_W); /* for last BD set Wrap bit */ + out_be32((u32 __iomem *)bd, T_W); /* for last BD set Wrap bit */ } /* Init Rx bds */ @@ -2717,14 +2723,14 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) bd = ugeth->rxBd[j] = ugeth->p_rx_bd_ring[j]; for (i = 0; i < ug_info->bdRingLenRx[j]; i++) { /* set bd status and length */ - out_be32((u32 *)bd, R_I); + out_be32((u32 __iomem *)bd, R_I); /* clear bd buffer */ - out_be32(&((struct qe_bd *)bd)->buf, 0); + out_be32(&((struct qe_bd __iomem *)bd)->buf, 0); bd += sizeof(struct qe_bd); } bd -= sizeof(struct qe_bd); /* set bd status and length */ - out_be32((u32 *)bd, R_W); /* for last BD set Wrap bit */ + out_be32((u32 __iomem *)bd, R_W); /* for last BD set Wrap bit */ } /* @@ -2744,10 +2750,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) return -ENOMEM; } ugeth->p_tx_glbl_pram = - (struct ucc_geth_tx_global_pram *) qe_muram_addr(ugeth-> + (struct ucc_geth_tx_global_pram __iomem *) qe_muram_addr(ugeth-> tx_glbl_pram_offset); /* Zero out p_tx_glbl_pram */ - memset(ugeth->p_tx_glbl_pram, 0, sizeof(struct ucc_geth_tx_global_pram)); + memset_io((void __iomem *)ugeth->p_tx_glbl_pram, 0, sizeof(struct ucc_geth_tx_global_pram)); /* Fill global PRAM */ @@ -2768,7 +2774,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) } ugeth->p_thread_data_tx = - (struct ucc_geth_thread_data_tx *) qe_muram_addr(ugeth-> + (struct ucc_geth_thread_data_tx __iomem *) qe_muram_addr(ugeth-> thread_dat_tx_offset); out_be32(&ugeth->p_tx_glbl_pram->tqptr, ugeth->thread_dat_tx_offset); @@ -2779,7 +2785,8 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) /* iphoffset */ for (i = 0; i < TX_IP_OFFSET_ENTRY_MAX; i++) - ugeth->p_tx_glbl_pram->iphoffset[i] = ug_info->iphoffset[i]; + out_8(&ugeth->p_tx_glbl_pram->iphoffset[i], + ug_info->iphoffset[i]); /* SQPTR */ /* Size varies with number of Tx queues */ @@ -2797,7 +2804,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) } ugeth->p_send_q_mem_reg = - (struct ucc_geth_send_queue_mem_region *) qe_muram_addr(ugeth-> + (struct ucc_geth_send_queue_mem_region __iomem *) qe_muram_addr(ugeth-> send_q_mem_reg_offset); out_be32(&ugeth->p_tx_glbl_pram->sqptr, ugeth->send_q_mem_reg_offset); @@ -2841,25 +2848,26 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) } ugeth->p_scheduler = - (struct ucc_geth_scheduler *) qe_muram_addr(ugeth-> + (struct ucc_geth_scheduler __iomem *) qe_muram_addr(ugeth-> scheduler_offset); out_be32(&ugeth->p_tx_glbl_pram->schedulerbasepointer, ugeth->scheduler_offset); /* Zero out p_scheduler */ - memset(ugeth->p_scheduler, 0, sizeof(struct ucc_geth_scheduler)); + memset_io((void __iomem *)ugeth->p_scheduler, 0, sizeof(struct ucc_geth_scheduler)); /* Set values in scheduler */ out_be32(&ugeth->p_scheduler->mblinterval, ug_info->mblinterval); out_be16(&ugeth->p_scheduler->nortsrbytetime, ug_info->nortsrbytetime); - ugeth->p_scheduler->fracsiz = ug_info->fracsiz; - ugeth->p_scheduler->strictpriorityq = ug_info->strictpriorityq; - ugeth->p_scheduler->txasap = ug_info->txasap; - ugeth->p_scheduler->extrabw = ug_info->extrabw; + out_8(&ugeth->p_scheduler->fracsiz, ug_info->fracsiz); + out_8(&ugeth->p_scheduler->strictpriorityq, + ug_info->strictpriorityq); + out_8(&ugeth->p_scheduler->txasap, ug_info->txasap); + out_8(&ugeth->p_scheduler->extrabw, ug_info->extrabw); for (i = 0; i < NUM_TX_QUEUES; i++) - ugeth->p_scheduler->weightfactor[i] = - ug_info->weightfactor[i]; + out_8(&ugeth->p_scheduler->weightfactor[i], + ug_info->weightfactor[i]); /* Set pointers to cpucount registers in scheduler */ ugeth->p_cpucount[0] = &(ugeth->p_scheduler->cpucount0); @@ -2890,10 +2898,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) return -ENOMEM; } ugeth->p_tx_fw_statistics_pram = - (struct ucc_geth_tx_firmware_statistics_pram *) + (struct ucc_geth_tx_firmware_statistics_pram __iomem *) qe_muram_addr(ugeth->tx_fw_statistics_pram_offset); /* Zero out p_tx_fw_statistics_pram */ - memset(ugeth->p_tx_fw_statistics_pram, + memset_io((void __iomem *)ugeth->p_tx_fw_statistics_pram, 0, sizeof(struct ucc_geth_tx_firmware_statistics_pram)); } @@ -2930,10 +2938,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) return -ENOMEM; } ugeth->p_rx_glbl_pram = - (struct ucc_geth_rx_global_pram *) qe_muram_addr(ugeth-> + (struct ucc_geth_rx_global_pram __iomem *) qe_muram_addr(ugeth-> rx_glbl_pram_offset); /* Zero out p_rx_glbl_pram */ - memset(ugeth->p_rx_glbl_pram, 0, sizeof(struct ucc_geth_rx_global_pram)); + memset_io((void __iomem *)ugeth->p_rx_glbl_pram, 0, sizeof(struct ucc_geth_rx_global_pram)); /* Fill global PRAM */ @@ -2953,7 +2961,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) } ugeth->p_thread_data_rx = - (struct ucc_geth_thread_data_rx *) qe_muram_addr(ugeth-> + (struct ucc_geth_thread_data_rx __iomem *) qe_muram_addr(ugeth-> thread_dat_rx_offset); out_be32(&ugeth->p_rx_glbl_pram->rqptr, ugeth->thread_dat_rx_offset); @@ -2976,10 +2984,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) return -ENOMEM; } ugeth->p_rx_fw_statistics_pram = - (struct ucc_geth_rx_firmware_statistics_pram *) + (struct ucc_geth_rx_firmware_statistics_pram __iomem *) qe_muram_addr(ugeth->rx_fw_statistics_pram_offset); /* Zero out p_rx_fw_statistics_pram */ - memset(ugeth->p_rx_fw_statistics_pram, 0, + memset_io((void __iomem *)ugeth->p_rx_fw_statistics_pram, 0, sizeof(struct ucc_geth_rx_firmware_statistics_pram)); } @@ -3000,7 +3008,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) } ugeth->p_rx_irq_coalescing_tbl = - (struct ucc_geth_rx_interrupt_coalescing_table *) + (struct ucc_geth_rx_interrupt_coalescing_table __iomem *) qe_muram_addr(ugeth->rx_irq_coalescing_tbl_offset); out_be32(&ugeth->p_rx_glbl_pram->intcoalescingptr, ugeth->rx_irq_coalescing_tbl_offset); @@ -3069,11 +3077,11 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) } ugeth->p_rx_bd_qs_tbl = - (struct ucc_geth_rx_bd_queues_entry *) qe_muram_addr(ugeth-> + (struct ucc_geth_rx_bd_queues_entry __iomem *) qe_muram_addr(ugeth-> rx_bd_qs_tbl_offset); out_be32(&ugeth->p_rx_glbl_pram->rbdqptr, ugeth->rx_bd_qs_tbl_offset); /* Zero out p_rx_bd_qs_tbl */ - memset(ugeth->p_rx_bd_qs_tbl, + memset_io((void __iomem *)ugeth->p_rx_bd_qs_tbl, 0, ug_info->numQueuesRx * (sizeof(struct ucc_geth_rx_bd_queues_entry) + sizeof(struct ucc_geth_rx_prefetched_bds))); @@ -3133,7 +3141,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) &ugeth->p_rx_glbl_pram->remoder); /* function code register */ - ugeth->p_rx_glbl_pram->rstate = function_code; + out_8(&ugeth->p_rx_glbl_pram->rstate, function_code); /* initialize extended filtering */ if (ug_info->rxExtendedFiltering) { @@ -3160,7 +3168,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) } ugeth->p_exf_glbl_param = - (struct ucc_geth_exf_global_pram *) qe_muram_addr(ugeth-> + (struct ucc_geth_exf_global_pram __iomem *) qe_muram_addr(ugeth-> exf_glbl_param_offset); out_be32(&ugeth->p_rx_glbl_pram->exfGlobalParam, ugeth->exf_glbl_param_offset); @@ -3175,7 +3183,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) ugeth_82xx_filtering_clear_addr_in_paddr(ugeth, (u8) j); p_82xx_addr_filt = - (struct ucc_geth_82xx_address_filtering_pram *) ugeth-> + (struct ucc_geth_82xx_address_filtering_pram __iomem *) ugeth-> p_rx_glbl_pram->addressfiltering; ugeth_82xx_filtering_clear_all_addr_in_hash(ugeth, @@ -3307,17 +3315,21 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) return -ENOMEM; } p_init_enet_pram = - (struct ucc_geth_init_pram *) qe_muram_addr(init_enet_pram_offset); + (struct ucc_geth_init_pram __iomem *) qe_muram_addr(init_enet_pram_offset); /* Copy shadow InitEnet command parameter structure into PRAM */ - p_init_enet_pram->resinit1 = ugeth->p_init_enet_param_shadow->resinit1; - p_init_enet_pram->resinit2 = ugeth->p_init_enet_param_shadow->resinit2; - p_init_enet_pram->resinit3 = ugeth->p_init_enet_param_shadow->resinit3; - p_init_enet_pram->resinit4 = ugeth->p_init_enet_param_shadow->resinit4; + out_8(&p_init_enet_pram->resinit1, + ugeth->p_init_enet_param_shadow->resinit1); + out_8(&p_init_enet_pram->resinit2, + ugeth->p_init_enet_param_shadow->resinit2); + out_8(&p_init_enet_pram->resinit3, + ugeth->p_init_enet_param_shadow->resinit3); + out_8(&p_init_enet_pram->resinit4, + ugeth->p_init_enet_param_shadow->resinit4); out_be16(&p_init_enet_pram->resinit5, ugeth->p_init_enet_param_shadow->resinit5); - p_init_enet_pram->largestexternallookupkeysize = - ugeth->p_init_enet_param_shadow->largestexternallookupkeysize; + out_8(&p_init_enet_pram->largestexternallookupkeysize, + ugeth->p_init_enet_param_shadow->largestexternallookupkeysize); out_be32(&p_init_enet_pram->rgftgfrxglobal, ugeth->p_init_enet_param_shadow->rgftgfrxglobal); for (i = 0; i < ENET_INIT_PARAM_MAX_ENTRIES_RX; i++) @@ -3371,7 +3383,7 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev) #ifdef CONFIG_UGETH_TX_ON_DEMAND struct ucc_fast_private *uccf; #endif - u8 *bd; /* BD pointer */ + u8 __iomem *bd; /* BD pointer */ u32 bd_status; u8 txQ = 0; @@ -3383,7 +3395,7 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Start from the next BD that should be filled */ bd = ugeth->txBd[txQ]; - bd_status = in_be32((u32 *)bd); + bd_status = in_be32((u32 __iomem *)bd); /* Save the skb pointer so we can free it later */ ugeth->tx_skbuff[txQ][ugeth->skb_curtx[txQ]] = skb; @@ -3393,7 +3405,7 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev) 1) & TX_RING_MOD_MASK(ugeth->ug_info->bdRingLenTx[txQ]); /* set up the buffer descriptor */ - out_be32(&((struct qe_bd *)bd)->buf, + out_be32(&((struct qe_bd __iomem *)bd)->buf, dma_map_single(NULL, skb->data, skb->len, DMA_TO_DEVICE)); /* printk(KERN_DEBUG"skb->data is 0x%x\n",skb->data); */ @@ -3401,7 +3413,7 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev) bd_status = (bd_status & T_W) | T_R | T_I | T_L | skb->len; /* set bd status and length */ - out_be32((u32 *)bd, bd_status); + out_be32((u32 __iomem *)bd, bd_status); dev->trans_start = jiffies; @@ -3441,7 +3453,7 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev) static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit) { struct sk_buff *skb; - u8 *bd; + u8 __iomem *bd; u16 length, howmany = 0; u32 bd_status; u8 *bdBuffer; @@ -3454,11 +3466,11 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit /* collect received buffers */ bd = ugeth->rxBd[rxQ]; - bd_status = in_be32((u32 *)bd); + bd_status = in_be32((u32 __iomem *)bd); /* while there are received buffers and BD is full (~R_E) */ while (!((bd_status & (R_E)) || (--rx_work_limit < 0))) { - bdBuffer = (u8 *) in_be32(&((struct qe_bd *)bd)->buf); + bdBuffer = (u8 *) in_be32(&((struct qe_bd __iomem *)bd)->buf); length = (u16) ((bd_status & BD_LENGTH_MASK) - 4); skb = ugeth->rx_skbuff[rxQ][ugeth->skb_currx[rxQ]]; @@ -3516,7 +3528,7 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit else bd += sizeof(struct qe_bd); - bd_status = in_be32((u32 *)bd); + bd_status = in_be32((u32 __iomem *)bd); } ugeth->rxBd[rxQ] = bd; @@ -3527,11 +3539,11 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ) { /* Start from the next BD that should be filled */ struct ucc_geth_private *ugeth = netdev_priv(dev); - u8 *bd; /* BD pointer */ + u8 __iomem *bd; /* BD pointer */ u32 bd_status; bd = ugeth->confBd[txQ]; - bd_status = in_be32((u32 *)bd); + bd_status = in_be32((u32 __iomem *)bd); /* Normal processing. */ while ((bd_status & T_R) == 0) { @@ -3561,7 +3573,7 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ) bd += sizeof(struct qe_bd); else bd = ugeth->p_tx_bd_ring[txQ]; - bd_status = in_be32((u32 *)bd); + bd_status = in_be32((u32 __iomem *)bd); } ugeth->confBd[txQ] = bd; return 0; @@ -3910,7 +3922,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma return -EINVAL; } } else { - prop = of_get_property(np, "rx-clock", NULL); + prop = of_get_property(np, "tx-clock", NULL); if (!prop) { printk(KERN_ERR "ucc_geth: mising tx-clock-name property\n"); diff --git a/drivers/net/ucc_geth.h b/drivers/net/ucc_geth.h index 9f8b7580a3a4578ddf6ed205279ccd7ecf1f5b4e..abc0e224263487efb7a28ab7a07f4d40bdce9d87 100644 --- a/drivers/net/ucc_geth.h +++ b/drivers/net/ucc_geth.h @@ -700,8 +700,8 @@ struct ucc_geth_82xx_address_filtering_pram { u32 iaddr_l; /* individual address filter, low */ u32 gaddr_h; /* group address filter, high */ u32 gaddr_l; /* group address filter, low */ - struct ucc_geth_82xx_enet_address taddr; - struct ucc_geth_82xx_enet_address paddr[NUM_OF_PADDRS]; + struct ucc_geth_82xx_enet_address __iomem taddr; + struct ucc_geth_82xx_enet_address __iomem paddr[NUM_OF_PADDRS]; u8 res0[0x40 - 0x38]; } __attribute__ ((packed)); @@ -1186,40 +1186,40 @@ struct ucc_geth_private { struct ucc_fast_private *uccf; struct net_device *dev; struct napi_struct napi; - struct ucc_geth *ug_regs; + struct ucc_geth __iomem *ug_regs; struct ucc_geth_init_pram *p_init_enet_param_shadow; - struct ucc_geth_exf_global_pram *p_exf_glbl_param; + struct ucc_geth_exf_global_pram __iomem *p_exf_glbl_param; u32 exf_glbl_param_offset; - struct ucc_geth_rx_global_pram *p_rx_glbl_pram; + struct ucc_geth_rx_global_pram __iomem *p_rx_glbl_pram; u32 rx_glbl_pram_offset; - struct ucc_geth_tx_global_pram *p_tx_glbl_pram; + struct ucc_geth_tx_global_pram __iomem *p_tx_glbl_pram; u32 tx_glbl_pram_offset; - struct ucc_geth_send_queue_mem_region *p_send_q_mem_reg; + struct ucc_geth_send_queue_mem_region __iomem *p_send_q_mem_reg; u32 send_q_mem_reg_offset; - struct ucc_geth_thread_data_tx *p_thread_data_tx; + struct ucc_geth_thread_data_tx __iomem *p_thread_data_tx; u32 thread_dat_tx_offset; - struct ucc_geth_thread_data_rx *p_thread_data_rx; + struct ucc_geth_thread_data_rx __iomem *p_thread_data_rx; u32 thread_dat_rx_offset; - struct ucc_geth_scheduler *p_scheduler; + struct ucc_geth_scheduler __iomem *p_scheduler; u32 scheduler_offset; - struct ucc_geth_tx_firmware_statistics_pram *p_tx_fw_statistics_pram; + struct ucc_geth_tx_firmware_statistics_pram __iomem *p_tx_fw_statistics_pram; u32 tx_fw_statistics_pram_offset; - struct ucc_geth_rx_firmware_statistics_pram *p_rx_fw_statistics_pram; + struct ucc_geth_rx_firmware_statistics_pram __iomem *p_rx_fw_statistics_pram; u32 rx_fw_statistics_pram_offset; - struct ucc_geth_rx_interrupt_coalescing_table *p_rx_irq_coalescing_tbl; + struct ucc_geth_rx_interrupt_coalescing_table __iomem *p_rx_irq_coalescing_tbl; u32 rx_irq_coalescing_tbl_offset; - struct ucc_geth_rx_bd_queues_entry *p_rx_bd_qs_tbl; + struct ucc_geth_rx_bd_queues_entry __iomem *p_rx_bd_qs_tbl; u32 rx_bd_qs_tbl_offset; - u8 *p_tx_bd_ring[NUM_TX_QUEUES]; + u8 __iomem *p_tx_bd_ring[NUM_TX_QUEUES]; u32 tx_bd_ring_offset[NUM_TX_QUEUES]; - u8 *p_rx_bd_ring[NUM_RX_QUEUES]; + u8 __iomem *p_rx_bd_ring[NUM_RX_QUEUES]; u32 rx_bd_ring_offset[NUM_RX_QUEUES]; - u8 *confBd[NUM_TX_QUEUES]; - u8 *txBd[NUM_TX_QUEUES]; - u8 *rxBd[NUM_RX_QUEUES]; + u8 __iomem *confBd[NUM_TX_QUEUES]; + u8 __iomem *txBd[NUM_TX_QUEUES]; + u8 __iomem *rxBd[NUM_RX_QUEUES]; int badFrame[NUM_RX_QUEUES]; u16 cpucount[NUM_TX_QUEUES]; - volatile u16 *p_cpucount[NUM_TX_QUEUES]; + u16 __iomem *p_cpucount[NUM_TX_QUEUES]; int indAddrRegUsed[NUM_OF_PADDRS]; u8 paddr[NUM_OF_PADDRS][ENET_NUM_OCTETS_PER_ADDRESS]; /* ethernet address */ u8 numGroupAddrInHash; @@ -1251,4 +1251,12 @@ struct ucc_geth_private { int oldlink; }; +void uec_set_ethtool_ops(struct net_device *netdev); +int init_flow_control_params(u32 automatic_flow_control_mode, + int rx_flow_control_enable, int tx_flow_control_enable, + u16 pause_period, u16 extension_field, + u32 __iomem *upsmr_register, u32 __iomem *uempr_register, + u32 __iomem *maccfg1_register); + + #endif /* __UCC_GETH_H__ */ diff --git a/drivers/net/ucc_geth_ethtool.c b/drivers/net/ucc_geth_ethtool.c index 9a9622c13e2b8d578fceec7563de0a703e697d9a..299b7f1769508675c7a82400e98e0f8494272bbe 100644 --- a/drivers/net/ucc_geth_ethtool.c +++ b/drivers/net/ucc_geth_ethtool.c @@ -108,12 +108,6 @@ static char rx_fw_stat_gstrings[][ETH_GSTRING_LEN] = { #define UEC_TX_FW_STATS_LEN ARRAY_SIZE(tx_fw_stat_gstrings) #define UEC_RX_FW_STATS_LEN ARRAY_SIZE(rx_fw_stat_gstrings) -extern int init_flow_control_params(u32 automatic_flow_control_mode, - int rx_flow_control_enable, - int tx_flow_control_enable, u16 pause_period, - u16 extension_field, volatile u32 *upsmr_register, - volatile u32 *uempr_register, volatile u32 *maccfg1_register); - static int uec_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) { diff --git a/drivers/net/ucc_geth_mii.c b/drivers/net/ucc_geth_mii.c index 2af490781005d63dbfe5eb1322ab7142c9c178ea..940474736922d1f15f4f217da2510e3046e9d51f 100644 --- a/drivers/net/ucc_geth_mii.c +++ b/drivers/net/ucc_geth_mii.c @@ -104,7 +104,7 @@ int uec_mdio_read(struct mii_bus *bus, int mii_id, int regnum) } /* Reset the MIIM registers, and wait for the bus to free */ -int uec_mdio_reset(struct mii_bus *bus) +static int uec_mdio_reset(struct mii_bus *bus) { struct ucc_mii_mng __iomem *regs = (void __iomem *)bus->priv; unsigned int timeout = PHY_INIT_TIMEOUT; @@ -240,7 +240,7 @@ reg_map_fail: return err; } -int uec_mdio_remove(struct of_device *ofdev) +static int uec_mdio_remove(struct of_device *ofdev) { struct device *device = &ofdev->dev; struct mii_bus *bus = dev_get_drvdata(device); diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index 6f245cfb662419f3f173a65073d873f4195768db..dc6f097062df3cb385d296cabfde169f54081bf4 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -1380,6 +1380,10 @@ static const struct usb_device_id products [] = { // Buffalo LUA-U2-KTX USB_DEVICE (0x0411, 0x003d), .driver_info = (unsigned long) &ax8817x_info, +}, { + // Buffalo LUA-U2-GT 10/100/1000 + USB_DEVICE (0x0411, 0x006e), + .driver_info = (unsigned long) &ax88178_info, }, { // Sitecom LN-029 "USB 2.0 10/100 Ethernet adapter" USB_DEVICE (0x6189, 0x182d), diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig index 8005dd16fb4e7bdb0772386d116e12e11a395579..d5140aed7b7977cc16475a0100cfb9c1414aea26 100644 --- a/drivers/net/wan/Kconfig +++ b/drivers/net/wan/Kconfig @@ -150,11 +150,9 @@ config HDLC_FR config HDLC_PPP tristate "Synchronous Point-to-Point Protocol (PPP) support" - depends on HDLC && BROKEN + depends on HDLC help Generic HDLC driver supporting PPP over WAN connections. - This module is currently broken and will cause a kernel panic - when a device configured in PPP mode is activated. It will be replaced by new PPP implementation in Linux 2.6.26. diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c index 45ddfc9763ccc176004640a3356be0265c6b3dbc..b0fce1387eaf2555a3d43fe89ccabf801d2a9891 100644 --- a/drivers/net/wan/cosa.c +++ b/drivers/net/wan/cosa.c @@ -629,7 +629,7 @@ static void sppp_channel_init(struct channel_data *chan) d->base_addr = chan->cosa->datareg; d->irq = chan->cosa->irq; d->dma = chan->cosa->dma; - d->priv = chan; + d->ml_priv = chan; sppp_attach(&chan->pppdev); if (register_netdev(d)) { printk(KERN_WARNING "%s: register_netdev failed.\n", d->name); @@ -650,7 +650,7 @@ static void sppp_channel_delete(struct channel_data *chan) static int cosa_sppp_open(struct net_device *d) { - struct channel_data *chan = d->priv; + struct channel_data *chan = d->ml_priv; int err; unsigned long flags; @@ -690,7 +690,7 @@ static int cosa_sppp_open(struct net_device *d) static int cosa_sppp_tx(struct sk_buff *skb, struct net_device *dev) { - struct channel_data *chan = dev->priv; + struct channel_data *chan = dev->ml_priv; netif_stop_queue(dev); @@ -701,7 +701,7 @@ static int cosa_sppp_tx(struct sk_buff *skb, struct net_device *dev) static void cosa_sppp_timeout(struct net_device *dev) { - struct channel_data *chan = dev->priv; + struct channel_data *chan = dev->ml_priv; if (test_bit(RXBIT, &chan->cosa->rxtx)) { chan->stats.rx_errors++; @@ -720,7 +720,7 @@ static void cosa_sppp_timeout(struct net_device *dev) static int cosa_sppp_close(struct net_device *d) { - struct channel_data *chan = d->priv; + struct channel_data *chan = d->ml_priv; unsigned long flags; netif_stop_queue(d); @@ -800,7 +800,7 @@ static int sppp_tx_done(struct channel_data *chan, int size) static struct net_device_stats *cosa_net_stats(struct net_device *dev) { - struct channel_data *chan = dev->priv; + struct channel_data *chan = dev->ml_priv; return &chan->stats; } @@ -1217,7 +1217,7 @@ static int cosa_sppp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { int rv; - struct channel_data *chan = dev->priv; + struct channel_data *chan = dev->ml_priv; rv = cosa_ioctl_common(chan->cosa, chan, cmd, (unsigned long)ifr->ifr_data); if (rv == -ENOIOCTLCMD) { return sppp_do_ioctl(dev, ifr, cmd); diff --git a/drivers/net/wan/hdlc_ppp.c b/drivers/net/wan/hdlc_ppp.c index 10396d9686f4f7a5413d647772ff947831bedf52..00308337928eca21d0b7b1cf2c7cac91b982121e 100644 --- a/drivers/net/wan/hdlc_ppp.c +++ b/drivers/net/wan/hdlc_ppp.c @@ -45,7 +45,7 @@ static int ppp_open(struct net_device *dev) int (*old_ioctl)(struct net_device *, struct ifreq *, int); int result; - dev->priv = &state(hdlc)->syncppp_ptr; + dev->ml_priv = &state(hdlc)->syncppp_ptr; state(hdlc)->syncppp_ptr = &state(hdlc)->pppdev; state(hdlc)->pppdev.dev = dev; diff --git a/drivers/net/wan/hostess_sv11.c b/drivers/net/wan/hostess_sv11.c index 83dbc924fcb577349018fdc8101d042c3e837c8e..f3065d3473fdc711abc928ef13841c5e754e9ca4 100644 --- a/drivers/net/wan/hostess_sv11.c +++ b/drivers/net/wan/hostess_sv11.c @@ -75,7 +75,7 @@ static void hostess_input(struct z8530_channel *c, struct sk_buff *skb) static int hostess_open(struct net_device *d) { - struct sv11_device *sv11=d->priv; + struct sv11_device *sv11=d->ml_priv; int err = -1; /* @@ -128,7 +128,7 @@ static int hostess_open(struct net_device *d) static int hostess_close(struct net_device *d) { - struct sv11_device *sv11=d->priv; + struct sv11_device *sv11=d->ml_priv; /* * Discard new frames */ @@ -159,14 +159,14 @@ static int hostess_close(struct net_device *d) static int hostess_ioctl(struct net_device *d, struct ifreq *ifr, int cmd) { - /* struct sv11_device *sv11=d->priv; + /* struct sv11_device *sv11=d->ml_priv; z8530_ioctl(d,&sv11->sync.chanA,ifr,cmd) */ return sppp_do_ioctl(d, ifr,cmd); } static struct net_device_stats *hostess_get_stats(struct net_device *d) { - struct sv11_device *sv11=d->priv; + struct sv11_device *sv11=d->ml_priv; if(sv11) return z8530_get_stats(&sv11->sync.chanA); else @@ -179,7 +179,7 @@ static struct net_device_stats *hostess_get_stats(struct net_device *d) static int hostess_queue_xmit(struct sk_buff *skb, struct net_device *d) { - struct sv11_device *sv11=d->priv; + struct sv11_device *sv11=d->ml_priv; return z8530_queue_xmit(&sv11->sync.chanA, skb); } @@ -325,6 +325,7 @@ static struct sv11_device *sv11_init(int iobase, int irq) /* * Initialise the PPP components */ + d->ml_priv = sv; sppp_attach(&sv->netdev); /* @@ -333,7 +334,6 @@ static struct sv11_device *sv11_init(int iobase, int irq) d->base_addr = iobase; d->irq = irq; - d->priv = sv; if(register_netdev(d)) { diff --git a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c index b5860b97a93e4b5d5dc8f290707f4dab7eec23f4..24fd613466b7ea0925d5c98c5aada6a82a1fc6cc 100644 --- a/drivers/net/wan/lapbether.c +++ b/drivers/net/wan/lapbether.c @@ -459,6 +459,7 @@ static void __exit lapbeth_cleanup_driver(void) list_for_each_safe(entry, tmp, &lapbeth_devices) { lapbeth = list_entry(entry, struct lapbethdev, node); + dev_put(lapbeth->ethdev); unregister_netdevice(lapbeth->axdev); } rtnl_unlock(); diff --git a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c index 6635ecef36e5096702035bfb3af8da662a3caab4..62133cee446a3f2cac931bc426848ed7b30bb36d 100644 --- a/drivers/net/wan/lmc/lmc_main.c +++ b/drivers/net/wan/lmc/lmc_main.c @@ -891,6 +891,7 @@ static int __devinit lmc_init_one(struct pci_dev *pdev, /* Initialize the sppp layer */ /* An ioctl can cause a subsequent detach for raw frame interface */ + dev->ml_priv = sc; sc->if_type = LMC_PPP; sc->check = 0xBEAFCAFE; dev->base_addr = pci_resource_start(pdev, 0); diff --git a/drivers/net/wan/sealevel.c b/drivers/net/wan/sealevel.c index 11276bf3149f081c8bd081bc7ead3c6515324d88..44a89df1b8bf88bda8233193a2c50cf281db5664 100644 --- a/drivers/net/wan/sealevel.c +++ b/drivers/net/wan/sealevel.c @@ -241,6 +241,7 @@ static inline struct slvl_device *slvl_alloc(int iobase, int irq) return NULL; sv = d->priv; + d->ml_priv = sv; sv->if_ptr = &sv->pppdev; sv->pppdev.dev = d; d->base_addr = iobase; diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index ef2da4023d685e075426ade0e9c5cc3315c2ebea..438e63ecccf1038f6402d1ee433b39dbfa3a8f73 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -60,7 +61,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index d5b7a76fcaad62b3d684ad9bf697b4f27d9b3c59..62fb89d8231821637de3feb9f46862aa5b1da410 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig @@ -1,6 +1,5 @@ config IWLWIFI - bool - default n + tristate config IWLCORE tristate "Intel Wireless Wifi Core" diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index d3406830c8e3591231d7234680effc342d4ef69a..62a3d8f8563ed07cbd7d6a743831dfdc66bf78cb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -666,7 +666,7 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv, rx_status.flag = 0; rx_status.mactime = le64_to_cpu(rx_end->timestamp); rx_status.freq = - ieee80211_frequency_to_channel(le16_to_cpu(rx_hdr->channel)); + ieee80211_channel_to_frequency(le16_to_cpu(rx_hdr->channel)); rx_status.band = (rx_hdr->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c index b608e1ca8b4062fdd101a7c56d2868bcce7cd9a6..c9847b1a67f7d9ee5c58abfcc4f391167da890ff 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c @@ -163,8 +163,8 @@ struct iwl4965_lq_sta { struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file; #endif struct iwl4965_rate dbg_fixed; - struct iwl_priv *drv; #endif + struct iwl_priv *drv; }; static void rs_rate_scale_perform(struct iwl_priv *priv, diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 17f629fb96ff2a0ed7299202473e11e15f281c31..bf19eb8aafd02f4db85e4d4f856d79f5ec2825fc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -3978,7 +3978,7 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv, rx_status.mactime = le64_to_cpu(rx_start->timestamp); rx_status.freq = - ieee80211_frequency_to_channel(le16_to_cpu(rx_start->channel)); + ieee80211_channel_to_frequency(le16_to_cpu(rx_start->channel)); rx_status.band = (rx_start->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; rx_status.rate_idx = diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c index 04c2638d75ad335c1f70fec3dbffbe48908c1042..9196825ed1b52539d92aad7bfa7de1db7c88529d 100644 --- a/drivers/net/wireless/prism54/islpci_dev.c +++ b/drivers/net/wireless/prism54/islpci_dev.c @@ -388,8 +388,15 @@ islpci_open(struct net_device *ndev) netif_start_queue(ndev); - /* Turn off carrier unless we know we have associated */ - netif_carrier_off(ndev); + /* Turn off carrier if in STA or Ad-hoc mode. It will be turned on + * once the firmware receives a trap of being associated + * (GEN_OID_LINKSTATE). In other modes (AP or WDS or monitor) we + * should just leave the carrier on as its expected the firmware + * won't send us a trigger. */ + if (priv->iw_mode == IW_MODE_INFRA || priv->iw_mode == IW_MODE_ADHOC) + netif_carrier_off(ndev); + else + netif_carrier_on(ndev); return 0; } diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 8d8657fb64dd4517de49b1d9adf74d5b8ec28dcb..b22c02737185a32149ac74b8f1f2ed109c09fb87 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -1032,8 +1032,10 @@ static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev) * Initialize the device. */ status = rt2x00dev->ops->lib->initialize(rt2x00dev); - if (status) - goto exit; + if (status) { + rt2x00queue_uninitialize(rt2x00dev); + return status; + } __set_bit(DEVICE_INITIALIZED, &rt2x00dev->flags); @@ -1043,11 +1045,6 @@ static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev) rt2x00rfkill_register(rt2x00dev); return 0; - -exit: - rt2x00lib_uninitialize(rt2x00dev); - - return status; } int rt2x00lib_start(struct rt2x00_dev *rt2x00dev) diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index 7867ec64bd2cceda4b25c7a97ddc8ae4ab9a0da1..971af2546b59a85e3e820f6d9b7e14e9276a515f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c @@ -314,13 +314,14 @@ int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev) if (status) { ERROR(rt2x00dev, "IRQ %d allocation failed (error %d).\n", pci_dev->irq, status); - return status; + goto exit; } return 0; exit: - rt2x00pci_uninitialize(rt2x00dev); + queue_for_each(rt2x00dev, queue) + rt2x00pci_free_queue_dma(rt2x00dev, queue); return status; } diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index ae12dcdd3c24f60df4d1bdc0bd97f011e43caa42..14bc7b281659c621bdd380c190c6e8bb181cc326 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -2366,6 +2366,7 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, { struct rt2x00_dev *rt2x00dev = hw->priv; struct rt2x00_intf *intf = vif_to_intf(control->vif); + struct queue_entry_priv_pci_tx *priv_tx; struct skb_frame_desc *skbdesc; unsigned int beacon_base; u32 reg; @@ -2373,21 +2374,8 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, if (unlikely(!intf->beacon)) return -ENOBUFS; - /* - * We need to append the descriptor in front of the - * beacon frame. - */ - if (skb_headroom(skb) < intf->beacon->queue->desc_size) { - if (pskb_expand_head(skb, intf->beacon->queue->desc_size, - 0, GFP_ATOMIC)) - return -ENOMEM; - } - - /* - * Add the descriptor in front of the skb. - */ - skb_push(skb, intf->beacon->queue->desc_size); - memset(skb->data, 0, intf->beacon->queue->desc_size); + priv_tx = intf->beacon->priv_data; + memset(priv_tx->desc, 0, intf->beacon->queue->desc_size); /* * Fill in skb descriptor @@ -2395,9 +2383,9 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, skbdesc = get_skb_frame_desc(skb); memset(skbdesc, 0, sizeof(*skbdesc)); skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; - skbdesc->data = skb->data + intf->beacon->queue->desc_size; - skbdesc->data_len = skb->len - intf->beacon->queue->desc_size; - skbdesc->desc = skb->data; + skbdesc->data = skb->data; + skbdesc->data_len = skb->len; + skbdesc->desc = priv_tx->desc; skbdesc->desc_len = intf->beacon->queue->desc_size; skbdesc->entry = intf->beacon; @@ -2425,7 +2413,10 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, */ beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); rt2x00pci_register_multiwrite(rt2x00dev, beacon_base, - skb->data, skb->len); + skbdesc->desc, skbdesc->desc_len); + rt2x00pci_register_multiwrite(rt2x00dev, + beacon_base + skbdesc->desc_len, + skbdesc->data, skbdesc->data_len); rt61pci_kick_tx_queue(rt2x00dev, control->queue); return 0; @@ -2490,7 +2481,7 @@ static const struct data_queue_desc rt61pci_queue_tx = { static const struct data_queue_desc rt61pci_queue_bcn = { .entry_num = 4 * BEACON_ENTRIES, - .data_size = MGMT_FRAME_SIZE, + .data_size = 0, /* No DMA required for beacons */ .desc_size = TXINFO_SIZE, .priv_size = sizeof(struct queue_entry_priv_pci_tx), }; diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c index 5dd23c93497db90163365b84a7e62917571cd122..883af891ebfb4c54d19daff25495af0a063734f4 100644 --- a/drivers/net/wireless/strip.c +++ b/drivers/net/wireless/strip.c @@ -2611,7 +2611,7 @@ static int strip_open(struct tty_struct *tty) * We need a write method. */ - if (tty->ops->write == NULL) + if (tty->ops->write == NULL || tty->ops->set_termios == NULL) return -EOPNOTSUPP; /* diff --git a/drivers/net/wireless/wavelan.c b/drivers/net/wireless/wavelan.c index 03384a43186b3470d81744e7f75ee584e4fe57ce..49ae970039524bea6dd6e47c173045f49c01f60c 100644 --- a/drivers/net/wireless/wavelan.c +++ b/drivers/net/wireless/wavelan.c @@ -908,9 +908,9 @@ static void wv_psa_show(psa_t * p) p->psa_call_code[3], p->psa_call_code[4], p->psa_call_code[5], p->psa_call_code[6], p->psa_call_code[7]); #ifdef DEBUG_SHOW_UNUSED - printk(KERN_DEBUG "psa_reserved[]: %02X:%02X:%02X:%02X\n", + printk(KERN_DEBUG "psa_reserved[]: %02X:%02X\n", p->psa_reserved[0], - p->psa_reserved[1], p->psa_reserved[2], p->psa_reserved[3]); + p->psa_reserved[1]); #endif /* DEBUG_SHOW_UNUSED */ printk(KERN_DEBUG "psa_conf_status: %d, ", p->psa_conf_status); printk("psa_crc: 0x%02x%02x, ", p->psa_crc[0], p->psa_crc[1]); diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c index baf74015751c4cb04c3ad5b4940db68bb04080b6..b584c0ecc62d1eeb191d6d5443eb34ec650b242d 100644 --- a/drivers/net/wireless/wavelan_cs.c +++ b/drivers/net/wireless/wavelan_cs.c @@ -1074,11 +1074,9 @@ wv_psa_show(psa_t * p) p->psa_call_code[6], p->psa_call_code[7]); #ifdef DEBUG_SHOW_UNUSED - printk(KERN_DEBUG "psa_reserved[]: %02X:%02X:%02X:%02X\n", + printk(KERN_DEBUG "psa_reserved[]: %02X:%02X\n", p->psa_reserved[0], - p->psa_reserved[1], - p->psa_reserved[2], - p->psa_reserved[3]); + p->psa_reserved[1]); #endif /* DEBUG_SHOW_UNUSED */ printk(KERN_DEBUG "psa_conf_status: %d, ", p->psa_conf_status); printk("psa_crc: 0x%02x%02x, ", p->psa_crc[0], p->psa_crc[1]); diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index 5316074f39f0b0c28e73ace87813ecb0e3883ef6..12e24f04dddfcd48aa65526dfe94bbd5beab5c83 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c @@ -889,9 +889,13 @@ static void tx_urb_complete(struct urb *urb) } free_urb: skb = (struct sk_buff *)urb->context; - zd_mac_tx_to_dev(skb, urb->status); + /* + * grab 'usb' pointer before handing off the skb (since + * it might be freed by zd_mac_tx_to_dev or mac80211) + */ cb = (struct zd_tx_skb_control_block *)skb->cb; usb = &zd_hw_mac(cb->hw)->chip.usb; + zd_mac_tx_to_dev(skb, urb->status); free_tx_urb(usb, urb); tx_dec_submitted_urbs(usb); return; diff --git a/drivers/of/base.c b/drivers/of/base.c index 9bd7c4a31253a5d7349d5b2fd3cb383e826d9680..23ffb7c0caf24148277ddd19c7430b5c90fb6fcb 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -65,6 +65,9 @@ struct property *of_find_property(const struct device_node *np, { struct property *pp; + if (!np) + return NULL; + read_lock(&devtree_lock); for (pp = np->properties; pp != 0; pp = pp->next) { if (of_prop_cmp(pp->name, name) == 0) { diff --git a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c index efcbf4b4579f275bccea1b00fda95891925e4be6..2450b3a393ff37f6ab1bd02d523f38027a838671 100644 --- a/drivers/oprofile/cpu_buffer.c +++ b/drivers/oprofile/cpu_buffer.c @@ -27,7 +27,7 @@ #include "buffer_sync.h" #include "oprof.h" -DEFINE_PER_CPU_SHARED_ALIGNED(struct oprofile_cpu_buffer, cpu_buffer); +DEFINE_PER_CPU(struct oprofile_cpu_buffer, cpu_buffer); static void wq_sync_buffer(struct work_struct *work); diff --git a/drivers/oprofile/cpu_buffer.h b/drivers/oprofile/cpu_buffer.h index 13588174311d452fc17108717907f23737f0d15d..c3e366b522619bd135964a17022638f4adfdec82 100644 --- a/drivers/oprofile/cpu_buffer.h +++ b/drivers/oprofile/cpu_buffer.h @@ -46,7 +46,7 @@ struct oprofile_cpu_buffer { unsigned long sample_invalid_eip; int cpu; struct delayed_work work; -} ____cacheline_aligned; +}; DECLARE_PER_CPU(struct oprofile_cpu_buffer, cpu_buffer); diff --git a/drivers/parisc/asp.c b/drivers/parisc/asp.c index 558420bc9f8811527e3b62a0a4d7b5f06fe8c23b..821369135369c52c0e141a10867e3233b655293f 100644 --- a/drivers/parisc/asp.c +++ b/drivers/parisc/asp.c @@ -88,7 +88,7 @@ asp_init_chip(struct parisc_device *dev) ret = -EBUSY; dev->irq = gsc_claim_irq(&gsc_irq, ASP_GSC_IRQ); if (dev->irq < 0) { - printk(KERN_ERR "%s(): cannot get GSC irq\n", __FUNCTION__); + printk(KERN_ERR "%s(): cannot get GSC irq\n", __func__); goto out; } diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c index 07d2a8d4498f395f52e822b9ff493555e1f3d600..b30e38f3a50d736d95d591594c04f9aeae7c62ea 100644 --- a/drivers/parisc/ccio-dma.c +++ b/drivers/parisc/ccio-dma.c @@ -359,7 +359,7 @@ ccio_alloc_range(struct ioc *ioc, struct device *dev, size_t size) BUG_ON((pages_needed * IOVP_SIZE) > DMA_CHUNK_SIZE); DBG_RES("%s() size: %d pages_needed %d\n", - __FUNCTION__, size, pages_needed); + __func__, size, pages_needed); /* ** "seek and ye shall find"...praying never hurts either... @@ -395,16 +395,16 @@ ccio_alloc_range(struct ioc *ioc, struct device *dev, size_t size) #endif } else { panic("%s: %s() Too many pages to map. pages_needed: %u\n", - __FILE__, __FUNCTION__, pages_needed); + __FILE__, __func__, pages_needed); } panic("%s: %s() I/O MMU is out of mapping resources.\n", __FILE__, - __FUNCTION__); + __func__); resource_found: DBG_RES("%s() res_idx %d res_hint: %d\n", - __FUNCTION__, res_idx, ioc->res_hint); + __func__, res_idx, ioc->res_hint); #ifdef CCIO_SEARCH_TIME { @@ -450,7 +450,7 @@ ccio_free_range(struct ioc *ioc, dma_addr_t iova, unsigned long pages_mapped) BUG_ON(pages_mapped > BITS_PER_LONG); DBG_RES("%s(): res_idx: %d pages_mapped %d\n", - __FUNCTION__, res_idx, pages_mapped); + __func__, res_idx, pages_mapped); #ifdef CCIO_MAP_STATS ioc->used_pages -= pages_mapped; @@ -474,7 +474,7 @@ ccio_free_range(struct ioc *ioc, dma_addr_t iova, unsigned long pages_mapped) #endif } else { panic("%s:%s() Too many pages to unmap.\n", __FILE__, - __FUNCTION__); + __func__); } } @@ -775,7 +775,7 @@ ccio_map_single(struct device *dev, void *addr, size_t size, pdir_start = &(ioc->pdir_base[idx]); DBG_RUN("%s() 0x%p -> 0x%lx size: %0x%x\n", - __FUNCTION__, addr, (long)iovp | offset, size); + __func__, addr, (long)iovp | offset, size); /* If not cacheline aligned, force SAFE_DMA on the whole mess */ if((size % L1_CACHE_BYTES) || ((unsigned long)addr % L1_CACHE_BYTES)) @@ -820,7 +820,7 @@ ccio_unmap_single(struct device *dev, dma_addr_t iova, size_t size, ioc = GET_IOC(dev); DBG_RUN("%s() iovp 0x%lx/%x\n", - __FUNCTION__, (long)iova, size); + __func__, (long)iova, size); iova ^= offset; /* clear offset bits */ size += offset; @@ -922,7 +922,7 @@ ccio_map_sg(struct device *dev, struct scatterlist *sglist, int nents, BUG_ON(!dev); ioc = GET_IOC(dev); - DBG_RUN_SG("%s() START %d entries\n", __FUNCTION__, nents); + DBG_RUN_SG("%s() START %d entries\n", __func__, nents); /* Fast path single entry scatterlists. */ if (nents == 1) { @@ -966,7 +966,7 @@ ccio_map_sg(struct device *dev, struct scatterlist *sglist, int nents, BUG_ON(coalesced != filled); - DBG_RUN_SG("%s() DONE %d mappings\n", __FUNCTION__, filled); + DBG_RUN_SG("%s() DONE %d mappings\n", __func__, filled); for (i = 0; i < filled; i++) current_len += sg_dma_len(sglist + i); @@ -995,7 +995,7 @@ ccio_unmap_sg(struct device *dev, struct scatterlist *sglist, int nents, ioc = GET_IOC(dev); DBG_RUN_SG("%s() START %d entries, %08lx,%x\n", - __FUNCTION__, nents, sg_virt_addr(sglist), sglist->length); + __func__, nents, sg_virt_addr(sglist), sglist->length); #ifdef CCIO_MAP_STATS ioc->usg_calls++; @@ -1011,7 +1011,7 @@ ccio_unmap_sg(struct device *dev, struct scatterlist *sglist, int nents, ++sglist; } - DBG_RUN_SG("%s() DONE (nents %d)\n", __FUNCTION__, nents); + DBG_RUN_SG("%s() DONE (nents %d)\n", __func__, nents); } static struct hppa_dma_ops ccio_ops = { @@ -1225,7 +1225,7 @@ static int ccio_get_iotlb_size(struct parisc_device *dev) { if (dev->spa_shift == 0) { - panic("%s() : Can't determine I/O TLB size.\n", __FUNCTION__); + panic("%s() : Can't determine I/O TLB size.\n", __func__); } return (1 << dev->spa_shift); } @@ -1315,7 +1315,7 @@ ccio_ioc_init(struct ioc *ioc) BUG_ON((1 << get_order(ioc->pdir_size)) != (ioc->pdir_size >> PAGE_SHIFT)); DBG_INIT("%s() hpa 0x%p mem %luMB IOV %dMB (%d bits)\n", - __FUNCTION__, ioc->ioc_regs, + __func__, ioc->ioc_regs, (unsigned long) num_physpages >> (20 - PAGE_SHIFT), iova_space_size>>20, iov_order + PAGE_SHIFT); @@ -1323,7 +1323,7 @@ ccio_ioc_init(struct ioc *ioc) ioc->pdir_base = (u64 *)__get_free_pages(GFP_KERNEL, get_order(ioc->pdir_size)); if(NULL == ioc->pdir_base) { - panic("%s() could not allocate I/O Page Table\n", __FUNCTION__); + panic("%s() could not allocate I/O Page Table\n", __func__); } memset(ioc->pdir_base, 0, ioc->pdir_size); @@ -1332,12 +1332,12 @@ ccio_ioc_init(struct ioc *ioc) /* resource map size dictated by pdir_size */ ioc->res_size = (ioc->pdir_size / sizeof(u64)) >> 3; - DBG_INIT("%s() res_size 0x%x\n", __FUNCTION__, ioc->res_size); + DBG_INIT("%s() res_size 0x%x\n", __func__, ioc->res_size); ioc->res_map = (u8 *)__get_free_pages(GFP_KERNEL, get_order(ioc->res_size)); if(NULL == ioc->res_map) { - panic("%s() could not allocate resource map\n", __FUNCTION__); + panic("%s() could not allocate resource map\n", __func__); } memset(ioc->res_map, 0, ioc->res_size); @@ -1409,7 +1409,7 @@ ccio_init_resource(struct resource *res, char *name, void __iomem *ioaddr) result = insert_resource(&iomem_resource, res); if (result < 0) { printk(KERN_ERR "%s() failed to claim CCIO bus address space (%08lx,%08lx)\n", - __FUNCTION__, res->start, res->end); + __func__, res->start, res->end); } } diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c index d9c6322a721b8390879f4f71a017756691ddfd5a..fd56128525d1b11e01bc71624025258957da15dd 100644 --- a/drivers/parisc/dino.c +++ b/drivers/parisc/dino.c @@ -180,7 +180,7 @@ static int dino_cfg_read(struct pci_bus *bus, unsigned int devfn, int where, void __iomem *base_addr = d->hba.base_addr; unsigned long flags; - DBG("%s: %p, %d, %d, %d\n", __FUNCTION__, base_addr, devfn, where, + DBG("%s: %p, %d, %d, %d\n", __func__, base_addr, devfn, where, size); spin_lock_irqsave(&d->dinosaur_pen, flags); @@ -215,7 +215,7 @@ static int dino_cfg_write(struct pci_bus *bus, unsigned int devfn, int where, void __iomem *base_addr = d->hba.base_addr; unsigned long flags; - DBG("%s: %p, %d, %d, %d\n", __FUNCTION__, base_addr, devfn, where, + DBG("%s: %p, %d, %d, %d\n", __func__, base_addr, devfn, where, size); spin_lock_irqsave(&d->dinosaur_pen, flags); @@ -301,7 +301,7 @@ static void dino_disable_irq(unsigned int irq) struct dino_device *dino_dev = irq_desc[irq].chip_data; int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS); - DBG(KERN_WARNING "%s(0x%p, %d)\n", __FUNCTION__, dino_dev, irq); + DBG(KERN_WARNING "%s(0x%p, %d)\n", __func__, dino_dev, irq); /* Clear the matching bit in the IMR register */ dino_dev->imr &= ~(DINO_MASK_IRQ(local_irq)); @@ -314,7 +314,7 @@ static void dino_enable_irq(unsigned int irq) int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS); u32 tmp; - DBG(KERN_WARNING "%s(0x%p, %d)\n", __FUNCTION__, dino_dev, irq); + DBG(KERN_WARNING "%s(0x%p, %d)\n", __func__, dino_dev, irq); /* ** clear pending IRQ bits @@ -340,7 +340,7 @@ static void dino_enable_irq(unsigned int irq) tmp = __raw_readl(dino_dev->hba.base_addr+DINO_ILR); if (tmp & DINO_MASK_IRQ(local_irq)) { DBG(KERN_WARNING "%s(): IRQ asserted! (ILR 0x%x)\n", - __FUNCTION__, tmp); + __func__, tmp); gsc_writel(dino_dev->txn_data, dino_dev->txn_addr); } } @@ -388,7 +388,7 @@ ilr_again: int local_irq = __ffs(mask); int irq = dino_dev->global_irq[local_irq]; DBG(KERN_DEBUG "%s(%d, %p) mask 0x%x\n", - __FUNCTION__, irq, intr_dev, mask); + __func__, irq, intr_dev, mask); __do_IRQ(irq); mask &= ~(1 << local_irq); } while (mask); @@ -566,7 +566,7 @@ dino_fixup_bus(struct pci_bus *bus) int port_base = HBA_PORT_BASE(dino_dev->hba.hba_num); DBG(KERN_WARNING "%s(0x%p) bus %d platform_data 0x%p\n", - __FUNCTION__, bus, bus->secondary, + __func__, bus, bus->secondary, bus->bridge->platform_data); /* Firmware doesn't set up card-mode dino, so we have to */ diff --git a/drivers/parisc/gsc.c b/drivers/parisc/gsc.c index 1b3e3fd12d95882492c6bd86ab9f367eb925bbb8..f7d088b897ee384f849081e92851ac08fd4ea164 100644 --- a/drivers/parisc/gsc.c +++ b/drivers/parisc/gsc.c @@ -112,7 +112,7 @@ static void gsc_asic_disable_irq(unsigned int irq) int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32); u32 imr; - DEBPRINTK(KERN_DEBUG "%s(%d) %s: IMR 0x%x\n", __FUNCTION__, irq, + DEBPRINTK(KERN_DEBUG "%s(%d) %s: IMR 0x%x\n", __func__, irq, irq_dev->name, imr); /* Disable the IRQ line by clearing the bit in the IMR */ @@ -127,7 +127,7 @@ static void gsc_asic_enable_irq(unsigned int irq) int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32); u32 imr; - DEBPRINTK(KERN_DEBUG "%s(%d) %s: IMR 0x%x\n", __FUNCTION__, irq, + DEBPRINTK(KERN_DEBUG "%s(%d) %s: IMR 0x%x\n", __func__, irq, irq_dev->name, imr); /* Enable the IRQ line by setting the bit in the IMR */ diff --git a/drivers/parisc/lasi.c b/drivers/parisc/lasi.c index cb3d281761293f82eb5e7fbeec1e26d28d7bc473..bee510098ce86ce23963dbf442b084fa02400d94 100644 --- a/drivers/parisc/lasi.c +++ b/drivers/parisc/lasi.c @@ -193,7 +193,7 @@ lasi_init_chip(struct parisc_device *dev) dev->irq = gsc_alloc_irq(&gsc_irq); if (dev->irq < 0) { printk(KERN_ERR "%s(): cannot get GSC irq\n", - __FUNCTION__); + __func__); kfree(lasi); return -EBUSY; } diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c index 66ce61048361ab665d6a7359d0cb7d43dcabbb38..a28c8946deaa1602cc83483fcb8156846443e3e2 100644 --- a/drivers/parisc/lba_pci.c +++ b/drivers/parisc/lba_pci.c @@ -377,12 +377,12 @@ static int elroy_cfg_read(struct pci_bus *bus, unsigned int devfn, int pos, int /* original - Generate config cycle on broken elroy with risk we will miss PCI bus errors. */ *data = lba_rd_cfg(d, tok, pos, size); - DBG_CFG("%s(%x+%2x) -> 0x%x (a)\n", __FUNCTION__, tok, pos, *data); + DBG_CFG("%s(%x+%2x) -> 0x%x (a)\n", __func__, tok, pos, *data); return 0; } if (LBA_SKIP_PROBE(d) && !lba_device_present(bus->secondary, devfn, d)) { - DBG_CFG("%s(%x+%2x) -> -1 (b)\n", __FUNCTION__, tok, pos); + DBG_CFG("%s(%x+%2x) -> -1 (b)\n", __func__, tok, pos); /* either don't want to look or know device isn't present. */ *data = ~0U; return(0); @@ -398,7 +398,7 @@ static int elroy_cfg_read(struct pci_bus *bus, unsigned int devfn, int pos, int case 2: *data = READ_REG16(data_reg + (pos & 2)); break; case 4: *data = READ_REG32(data_reg); break; } - DBG_CFG("%s(%x+%2x) -> 0x%x (c)\n", __FUNCTION__, tok, pos, *data); + DBG_CFG("%s(%x+%2x) -> 0x%x (c)\n", __func__, tok, pos, *data); return 0; } @@ -441,16 +441,16 @@ static int elroy_cfg_write(struct pci_bus *bus, unsigned int devfn, int pos, int if (!LBA_SKIP_PROBE(d)) { /* Original Workaround */ lba_wr_cfg(d, tok, pos, (u32) data, size); - DBG_CFG("%s(%x+%2x) = 0x%x (a)\n", __FUNCTION__, tok, pos,data); + DBG_CFG("%s(%x+%2x) = 0x%x (a)\n", __func__, tok, pos,data); return 0; } if (LBA_SKIP_PROBE(d) && (!lba_device_present(bus->secondary, devfn, d))) { - DBG_CFG("%s(%x+%2x) = 0x%x (b)\n", __FUNCTION__, tok, pos,data); + DBG_CFG("%s(%x+%2x) = 0x%x (b)\n", __func__, tok, pos,data); return 1; /* New Workaround */ } - DBG_CFG("%s(%x+%2x) = 0x%x (c)\n", __FUNCTION__, tok, pos, data); + DBG_CFG("%s(%x+%2x) = 0x%x (c)\n", __func__, tok, pos, data); /* Basic Algorithm */ LBA_CFG_ADDR_SETUP(d, tok | pos); @@ -521,7 +521,7 @@ static int mercury_cfg_write(struct pci_bus *bus, unsigned int devfn, int pos, i if ((pos > 255) || (devfn > 255)) return -EINVAL; - DBG_CFG("%s(%x+%2x) <- 0x%x (c)\n", __FUNCTION__, tok, pos, data); + DBG_CFG("%s(%x+%2x) <- 0x%x (c)\n", __func__, tok, pos, data); LBA_CFG_TR4_ADDR_SETUP(d, tok | pos); switch(size) { @@ -890,7 +890,7 @@ LBA_PORT_IN(32, 0) #define LBA_PORT_OUT(size, mask) \ static void lba_astro_out##size (struct pci_hba_data *d, u16 addr, u##size val) \ { \ - DBG_PORT("%s(0x%p, 0x%x, 0x%x)\n", __FUNCTION__, d, addr, val); \ + DBG_PORT("%s(0x%p, 0x%x, 0x%x)\n", __func__, d, addr, val); \ WRITE_REG##size(val, astro_iop_base + addr); \ if (LBA_DEV(d)->hw_rev < 3) \ lba_t32 = READ_U32(d->base_addr + LBA_FUNC_ID); \ @@ -932,7 +932,7 @@ static struct pci_port_ops lba_astro_port_ops = { static u##size lba_pat_in##size (struct pci_hba_data *l, u16 addr) \ { \ u##size t; \ - DBG_PORT("%s(0x%p, 0x%x) ->", __FUNCTION__, l, addr); \ + DBG_PORT("%s(0x%p, 0x%x) ->", __func__, l, addr); \ t = READ_REG##size(PIOP_TO_GMMIO(LBA_DEV(l), addr)); \ DBG_PORT(" 0x%x\n", t); \ return (t); \ @@ -948,7 +948,7 @@ LBA_PORT_IN(32, 0) static void lba_pat_out##size (struct pci_hba_data *l, u16 addr, u##size val) \ { \ void __iomem *where = PIOP_TO_GMMIO(LBA_DEV(l), addr); \ - DBG_PORT("%s(0x%p, 0x%x, 0x%x)\n", __FUNCTION__, l, addr, val); \ + DBG_PORT("%s(0x%p, 0x%x, 0x%x)\n", __func__, l, addr, val); \ WRITE_REG##size(val, where); \ /* flush the I/O down to the elroy at least */ \ lba_t32 = READ_U32(l->base_addr + LBA_FUNC_ID); \ @@ -1584,7 +1584,7 @@ void lba_set_iregs(struct parisc_device *lba, u32 ibase, u32 imask) WARN_ON((ibase & 0x001fffff) != 0); WARN_ON((imask & 0x001fffff) != 0); - DBG("%s() ibase 0x%x imask 0x%x\n", __FUNCTION__, ibase, imask); + DBG("%s() ibase 0x%x imask 0x%x\n", __func__, ibase, imask); WRITE_REG32( imask, base_addr + LBA_IMASK); WRITE_REG32( ibase, base_addr + LBA_IBASE); iounmap(base_addr); diff --git a/drivers/parisc/led.c b/drivers/parisc/led.c index 703b85edb004b3d5b9f7dca1286ad4cba156291f..f9b12664f9fb90c24e07ce2cc6f49cd8769a81cd 100644 --- a/drivers/parisc/led.c +++ b/drivers/parisc/led.c @@ -569,7 +569,7 @@ int __init register_led_driver(int model, unsigned long cmd_reg, unsigned long d default: printk(KERN_ERR "%s: Wrong LCD/LED model %d !\n", - __FUNCTION__, lcd_info.model); + __func__, lcd_info.model); return 1; } diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c index afc849bd3f58a9ebaf9a0a00785c7a1f068e935d..bc73b96346ff1be8b20130a88d9b9b8a7591e68a 100644 --- a/drivers/parisc/sba_iommu.c +++ b/drivers/parisc/sba_iommu.c @@ -384,7 +384,7 @@ sba_search_bitmap(struct ioc *ioc, struct device *dev, } mask = RESMAP_MASK(bits_wanted) >> bitshiftcnt; - DBG_RES("%s() o %ld %p", __FUNCTION__, o, res_ptr); + DBG_RES("%s() o %ld %p", __func__, o, res_ptr); while(res_ptr < res_end) { DBG_RES(" %p %lx %lx\n", res_ptr, mask, *res_ptr); @@ -454,7 +454,7 @@ sba_alloc_range(struct ioc *ioc, struct device *dev, size_t size) #endif DBG_RES("%s(%x) %d -> %lx hint %x/%x\n", - __FUNCTION__, size, pages_needed, pide, + __func__, size, pages_needed, pide, (uint) ((unsigned long) ioc->res_hint - (unsigned long) ioc->res_map), ioc->res_bitshift ); @@ -497,7 +497,7 @@ sba_free_range(struct ioc *ioc, dma_addr_t iova, size_t size) unsigned long m = RESMAP_MASK(bits_not_wanted) >> (pide & (BITS_PER_LONG - 1)); DBG_RES("%s( ,%x,%x) %x/%lx %x %p %lx\n", - __FUNCTION__, (uint) iova, size, + __func__, (uint) iova, size, bits_not_wanted, m, pide, res_ptr, *res_ptr); #ifdef SBA_COLLECT_STATS @@ -740,7 +740,7 @@ sba_map_single(struct device *dev, void *addr, size_t size, iovp = (dma_addr_t) pide << IOVP_SHIFT; DBG_RUN("%s() 0x%p -> 0x%lx\n", - __FUNCTION__, addr, (long) iovp | offset); + __func__, addr, (long) iovp | offset); pdir_start = &(ioc->pdir_base[pide]); @@ -798,7 +798,7 @@ sba_unmap_single(struct device *dev, dma_addr_t iova, size_t size, unsigned long flags; dma_addr_t offset; - DBG_RUN("%s() iovp 0x%lx/%x\n", __FUNCTION__, (long) iova, size); + DBG_RUN("%s() iovp 0x%lx/%x\n", __func__, (long) iova, size); ioc = GET_IOC(dev); offset = iova & ~IOVP_MASK; @@ -937,7 +937,7 @@ sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents, int coalesced, filled = 0; unsigned long flags; - DBG_RUN_SG("%s() START %d entries\n", __FUNCTION__, nents); + DBG_RUN_SG("%s() START %d entries\n", __func__, nents); ioc = GET_IOC(dev); @@ -998,7 +998,7 @@ sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents, spin_unlock_irqrestore(&ioc->res_lock, flags); - DBG_RUN_SG("%s() DONE %d mappings\n", __FUNCTION__, filled); + DBG_RUN_SG("%s() DONE %d mappings\n", __func__, filled); return filled; } @@ -1023,7 +1023,7 @@ sba_unmap_sg(struct device *dev, struct scatterlist *sglist, int nents, #endif DBG_RUN_SG("%s() START %d entries, %p,%x\n", - __FUNCTION__, nents, sg_virt_addr(sglist), sglist->length); + __func__, nents, sg_virt_addr(sglist), sglist->length); ioc = GET_IOC(dev); @@ -1047,7 +1047,7 @@ sba_unmap_sg(struct device *dev, struct scatterlist *sglist, int nents, ++sglist; } - DBG_RUN_SG("%s() DONE (nents %d)\n", __FUNCTION__, nents); + DBG_RUN_SG("%s() DONE (nents %d)\n", __func__, nents); #ifdef ASSERT_PDIR_SANITY spin_lock_irqsave(&ioc->res_lock, flags); @@ -1118,7 +1118,7 @@ sba_alloc_pdir(unsigned int pdir_size) pdir_base = __get_free_pages(GFP_KERNEL, pdir_order); if (NULL == (void *) pdir_base) { panic("%s() could not allocate I/O Page Table\n", - __FUNCTION__); + __func__); } /* If this is not PA8700 (PCX-W2) @@ -1261,7 +1261,7 @@ sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num) ioc->pdir_size = (iova_space_size / IOVP_SIZE) * sizeof(u64); DBG_INIT("%s() hpa 0x%p IOV %dMB (%d bits)\n", - __FUNCTION__, ioc->ioc_hpa, iova_space_size >> 20, + __func__, ioc->ioc_hpa, iova_space_size >> 20, iov_order + PAGE_SHIFT); ioc->pdir_base = (void *) __get_free_pages(GFP_KERNEL, @@ -1272,7 +1272,7 @@ sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num) memset(ioc->pdir_base, 0, ioc->pdir_size); DBG_INIT("%s() pdir %p size %x\n", - __FUNCTION__, ioc->pdir_base, ioc->pdir_size); + __func__, ioc->pdir_base, ioc->pdir_size); #ifdef SBA_HINT_SUPPORT ioc->hint_shift_pdir = iov_order + PAGE_SHIFT; @@ -1354,7 +1354,7 @@ sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num) if (agp_found && sba_reserve_agpgart) { printk(KERN_INFO "%s: reserving %dMb of IOVA space for agpgart\n", - __FUNCTION__, (iova_space_size/2) >> 20); + __func__, (iova_space_size/2) >> 20); ioc->pdir_size /= 2; ioc->pdir_base[PDIR_INDEX(iova_space_size/2)] = SBA_AGPGART_COOKIE; } @@ -1406,7 +1406,7 @@ sba_ioc_init(struct parisc_device *sba, struct ioc *ioc, int ioc_num) ioc->pdir_size = pdir_size = (iova_space_size/IOVP_SIZE) * sizeof(u64); DBG_INIT("%s() hpa 0x%lx mem %ldMB IOV %dMB (%d bits)\n", - __FUNCTION__, + __func__, ioc->ioc_hpa, (unsigned long) num_physpages >> (20 - PAGE_SHIFT), iova_space_size>>20, @@ -1415,7 +1415,7 @@ sba_ioc_init(struct parisc_device *sba, struct ioc *ioc, int ioc_num) ioc->pdir_base = sba_alloc_pdir(pdir_size); DBG_INIT("%s() pdir %p size %x\n", - __FUNCTION__, ioc->pdir_base, pdir_size); + __func__, ioc->pdir_base, pdir_size); #ifdef SBA_HINT_SUPPORT /* FIXME : DMA HINTs not used */ @@ -1443,7 +1443,7 @@ sba_ioc_init(struct parisc_device *sba, struct ioc *ioc, int ioc_num) #endif DBG_INIT("%s() IOV base 0x%lx mask 0x%0lx\n", - __FUNCTION__, ioc->ibase, ioc->imask); + __func__, ioc->ibase, ioc->imask); /* ** FIXME: Hint registers are programmed with default hint @@ -1470,7 +1470,7 @@ sba_ioc_init(struct parisc_device *sba, struct ioc *ioc, int ioc_num) ioc->ibase = 0; /* used by SBA_IOVA and related macros */ - DBG_INIT("%s() DONE\n", __FUNCTION__); + DBG_INIT("%s() DONE\n", __func__); } @@ -1544,7 +1544,7 @@ printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa, if (!IS_PLUTO(sba_dev->dev)) { ioc_ctl = READ_REG(sba_dev->sba_hpa+IOC_CTRL); DBG_INIT("%s() hpa 0x%lx ioc_ctl 0x%Lx ->", - __FUNCTION__, sba_dev->sba_hpa, ioc_ctl); + __func__, sba_dev->sba_hpa, ioc_ctl); ioc_ctl &= ~(IOC_CTRL_RM | IOC_CTRL_NC | IOC_CTRL_CE); ioc_ctl |= IOC_CTRL_DD | IOC_CTRL_D4 | IOC_CTRL_TC; /* j6700 v1.6 firmware sets 0x294f */ @@ -1675,7 +1675,7 @@ sba_common_init(struct sba_device *sba_dev) res_size >>= 3; /* convert bit count to byte count */ DBG_INIT("%s() res_size 0x%x\n", - __FUNCTION__, res_size); + __func__, res_size); sba_dev->ioc[i].res_size = res_size; sba_dev->ioc[i].res_map = (char *) __get_free_pages(GFP_KERNEL, get_order(res_size)); @@ -1688,7 +1688,7 @@ sba_common_init(struct sba_device *sba_dev) if (NULL == sba_dev->ioc[i].res_map) { panic("%s:%s() could not allocate resource map\n", - __FILE__, __FUNCTION__ ); + __FILE__, __func__ ); } memset(sba_dev->ioc[i].res_map, 0, res_size); @@ -1725,7 +1725,7 @@ sba_common_init(struct sba_device *sba_dev) #endif DBG_INIT("%s() %d res_map %x %p\n", - __FUNCTION__, i, res_size, sba_dev->ioc[i].res_map); + __func__, i, res_size, sba_dev->ioc[i].res_map); } spin_lock_init(&sba_dev->sba_lock); diff --git a/drivers/parisc/wax.c b/drivers/parisc/wax.c index 813c2c24ab1ef8a1273becb3dbfd2ecabcadaebf..892a83bbe73d52d977e980ad5a18fca44914cd66 100644 --- a/drivers/parisc/wax.c +++ b/drivers/parisc/wax.c @@ -93,7 +93,7 @@ wax_init_chip(struct parisc_device *dev) dev->irq = gsc_claim_irq(&gsc_irq, WAX_GSC_IRQ); if (dev->irq < 0) { printk(KERN_ERR "%s(): cannot get GSC irq\n", - __FUNCTION__); + __func__); kfree(wax); return -EBUSY; } diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 1fd8bb7657024c2629858940fc050a35fc3acab7..66c0fd21894b155e9db690b65a86bfddffca29c4 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -49,7 +49,7 @@ #define DEFAULT_DOMAIN_ADDRESS_WIDTH 48 -#define DMAR_OPERATION_TIMEOUT (HZ*60) /* 1m */ +#define DMAR_OPERATION_TIMEOUT ((cycles_t) tsc_khz*10*1000) /* 10sec */ #define DOMAIN_MAX_ADDR(gaw) ((((u64)1) << gaw) - 1) @@ -490,12 +490,12 @@ static int iommu_alloc_root_entry(struct intel_iommu *iommu) #define IOMMU_WAIT_OP(iommu, offset, op, cond, sts) \ {\ - unsigned long start_time = jiffies;\ + cycles_t start_time = get_cycles();\ while (1) {\ sts = op (iommu->reg + offset);\ if (cond)\ break;\ - if (time_after(jiffies, start_time + DMAR_OPERATION_TIMEOUT))\ + if (DMAR_OPERATION_TIMEOUT < (get_cycles() - start_time))\ panic("DMAR hardware is malfunctioning\n");\ cpu_relax();\ }\ diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 72f7476930c857ffa20a4c323dff3af6bf7c9baa..9d6fc8e6285d0c557a5e1778e468f49066ff4da5 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -19,8 +19,31 @@ #include #include "pci.h" -static u32 ctrlset_buf[3] = {0, 0, 0}; -static u32 global_ctrlsets = 0; +struct acpi_osc_data { + acpi_handle handle; + u32 ctrlset_buf[3]; + u32 global_ctrlsets; + struct list_head sibiling; +}; +static LIST_HEAD(acpi_osc_data_list); + +static struct acpi_osc_data *acpi_get_osc_data(acpi_handle handle) +{ + struct acpi_osc_data *data; + + list_for_each_entry(data, &acpi_osc_data_list, sibiling) { + if (data->handle == handle) + return data; + } + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) + return NULL; + INIT_LIST_HEAD(&data->sibiling); + data->handle = handle; + list_add_tail(&data->sibiling, &acpi_osc_data_list); + return data; +} + static u8 OSC_UUID[16] = {0x5B, 0x4D, 0xDB, 0x33, 0xF7, 0x1F, 0x1C, 0x40, 0x96, 0x57, 0x74, 0x41, 0xC0, 0x3D, 0xD7, 0x66}; static acpi_status @@ -37,8 +60,27 @@ acpi_query_osc ( union acpi_object *out_obj; u32 osc_dw0; acpi_status *ret_status = (acpi_status *)retval; + struct acpi_osc_data *osc_data; + u32 flags = (unsigned long)context, temp; + acpi_handle tmp; + + status = acpi_get_handle(handle, "_OSC", &tmp); + if (ACPI_FAILURE(status)) + return status; + + osc_data = acpi_get_osc_data(handle); + if (!osc_data) { + printk(KERN_ERR "acpi osc data array is full\n"); + return AE_ERROR; + } + + osc_data->ctrlset_buf[OSC_SUPPORT_TYPE] |= (flags & OSC_SUPPORT_MASKS); + + /* do _OSC query for all possible controls */ + temp = osc_data->ctrlset_buf[OSC_CONTROL_TYPE]; + osc_data->ctrlset_buf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE; + osc_data->ctrlset_buf[OSC_CONTROL_TYPE] = OSC_CONTROL_MASKS; - /* Setting up input parameters */ input.count = 4; input.pointer = in_params; @@ -51,13 +93,11 @@ acpi_query_osc ( in_params[2].integer.value = 3; in_params[3].type = ACPI_TYPE_BUFFER; in_params[3].buffer.length = 12; - in_params[3].buffer.pointer = (u8 *)context; + in_params[3].buffer.pointer = (u8 *)osc_data->ctrlset_buf; status = acpi_evaluate_object(handle, "_OSC", &input, &output); - if (ACPI_FAILURE (status)) { - *ret_status = status; - return status; - } + if (ACPI_FAILURE(status)) + goto out_nofree; out_obj = output.pointer; if (out_obj->type != ACPI_TYPE_BUFFER) { @@ -76,7 +116,8 @@ acpi_query_osc ( printk(KERN_DEBUG "_OSC invalid revision\n"); if (osc_dw0 & OSC_CAPABILITIES_MASK_ERROR) { /* Update Global Control Set */ - global_ctrlsets = *((u32 *)(out_obj->buffer.pointer+8)); + osc_data->global_ctrlsets = + *((u32 *)(out_obj->buffer.pointer + 8)); status = AE_OK; goto query_osc_out; } @@ -85,12 +126,21 @@ acpi_query_osc ( } /* Update Global Control Set */ - global_ctrlsets = *((u32 *)(out_obj->buffer.pointer + 8)); + osc_data->global_ctrlsets = *((u32 *)(out_obj->buffer.pointer + 8)); status = AE_OK; query_osc_out: kfree(output.pointer); +out_nofree: *ret_status = status; + + osc_data->ctrlset_buf[OSC_QUERY_TYPE] = !OSC_QUERY_ENABLE; + osc_data->ctrlset_buf[OSC_CONTROL_TYPE] = temp; + if (ACPI_FAILURE(status)) { + /* no osc support at all */ + osc_data->ctrlset_buf[OSC_SUPPORT_TYPE] = 0; + } + return status; } @@ -165,28 +215,15 @@ run_osc_out: **/ acpi_status __pci_osc_support_set(u32 flags, const char *hid) { - u32 temp; - acpi_status retval; + acpi_status retval = AE_NOT_FOUND; if (!(flags & OSC_SUPPORT_MASKS)) { return AE_TYPE; } - ctrlset_buf[OSC_SUPPORT_TYPE] |= (flags & OSC_SUPPORT_MASKS); - - /* do _OSC query for all possible controls */ - temp = ctrlset_buf[OSC_CONTROL_TYPE]; - ctrlset_buf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE; - ctrlset_buf[OSC_CONTROL_TYPE] = OSC_CONTROL_MASKS; acpi_get_devices(hid, acpi_query_osc, - ctrlset_buf, + (void *)(unsigned long)flags, (void **) &retval ); - ctrlset_buf[OSC_QUERY_TYPE] = !OSC_QUERY_ENABLE; - ctrlset_buf[OSC_CONTROL_TYPE] = temp; - if (ACPI_FAILURE(retval)) { - /* no osc support at all */ - ctrlset_buf[OSC_SUPPORT_TYPE] = 0; - } return AE_OK; } @@ -201,19 +238,31 @@ acpi_status pci_osc_control_set(acpi_handle handle, u32 flags) { acpi_status status; u32 ctrlset; + acpi_handle tmp; + struct acpi_osc_data *osc_data; + + status = acpi_get_handle(handle, "_OSC", &tmp); + if (ACPI_FAILURE(status)) + return status; + + osc_data = acpi_get_osc_data(handle); + if (!osc_data) { + printk(KERN_ERR "acpi osc data array is full\n"); + return AE_ERROR; + } ctrlset = (flags & OSC_CONTROL_MASKS); if (!ctrlset) { return AE_TYPE; } - if (ctrlset_buf[OSC_SUPPORT_TYPE] && - ((global_ctrlsets & ctrlset) != ctrlset)) { + if (osc_data->ctrlset_buf[OSC_SUPPORT_TYPE] && + ((osc_data->global_ctrlsets & ctrlset) != ctrlset)) { return AE_SUPPORT; } - ctrlset_buf[OSC_CONTROL_TYPE] |= ctrlset; - status = acpi_run_osc(handle, ctrlset_buf); + osc_data->ctrlset_buf[OSC_CONTROL_TYPE] |= ctrlset; + status = acpi_run_osc(handle, osc_data->ctrlset_buf); if (ACPI_FAILURE (status)) { - ctrlset_buf[OSC_CONTROL_TYPE] &= ~ctrlset; + osc_data->ctrlset_buf[OSC_CONTROL_TYPE] &= ~ctrlset; } return status; diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index afd914ebe2153aeca5bb78be50dcfed26c7d2603..dabb563f51d9466e4379f9095c85d2ce04545925 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -1503,8 +1503,7 @@ static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_f (f->device == dev->device || f->device == (u16) PCI_ANY_ID)) { #ifdef DEBUG dev_dbg(&dev->dev, "calling "); - print_fn_descriptor_symbol("%s()\n", - (unsigned long) f->hook); + print_fn_descriptor_symbol("%s\n", f->hook); #endif f->hook(dev); } @@ -1826,6 +1825,7 @@ static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev) } } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, nv_msi_ht_cap_quirk); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_ANY_ID, nv_msi_ht_cap_quirk); static void __devinit quirk_msi_intx_disable_bug(struct pci_dev *dev) { diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h index 4fe7c58f57e92e624b00bb7f5c0f6869b7ed250a..886dac823ed6d6e1f66ff609c433fbd5644646fb 100644 --- a/drivers/pnp/base.h +++ b/drivers/pnp/base.h @@ -19,6 +19,7 @@ void pnp_remove_card(struct pnp_card *card); int pnp_add_card_device(struct pnp_card *card, struct pnp_dev *dev); void pnp_remove_card_device(struct pnp_dev *dev); +struct pnp_option *pnp_build_option(int priority); struct pnp_option *pnp_register_independent_option(struct pnp_dev *dev); struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev, int priority); diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c index 5d9301de17786bd35613e4eecda23ef48f5c35d6..5695a79f3a5262fe3701752a41cce19b43fff937 100644 --- a/drivers/pnp/interface.c +++ b/drivers/pnp/interface.c @@ -424,7 +424,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr, start = simple_strtoul(buf, &buf, 0); pnp_res = pnp_add_irq_resource(dev, start, 0); if (pnp_res) - nirq++; + pnp_res->index = nirq++; continue; } if (!strnicmp(buf, "dma", 3)) { diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c index d049a2279feac460d0dda5e4a21f2471c1b059b0..e2b7de4cb05e46849f60ce4326b289bfe2092e62 100644 --- a/drivers/pnp/quirks.c +++ b/drivers/pnp/quirks.c @@ -111,6 +111,113 @@ static void quirk_sb16audio_resources(struct pnp_dev *dev) dev_info(&dev->dev, "SB audio device quirk - increased port range\n"); } +static struct pnp_option *quirk_isapnp_mpu_options(struct pnp_dev *dev) +{ + struct pnp_option *head = NULL; + struct pnp_option *prev = NULL; + struct pnp_option *res; + + /* + * Build a functional IRQ-less variant of each MPU option. + */ + + for (res = dev->dependent; res; res = res->next) { + struct pnp_option *curr; + struct pnp_port *port; + struct pnp_port *copy; + + port = res->port; + if (!port || !res->irq) + continue; + + copy = pnp_alloc(sizeof *copy); + if (!copy) + break; + + copy->min = port->min; + copy->max = port->max; + copy->align = port->align; + copy->size = port->size; + copy->flags = port->flags; + + curr = pnp_build_option(PNP_RES_PRIORITY_FUNCTIONAL); + if (!curr) { + kfree(copy); + break; + } + curr->port = copy; + + if (prev) + prev->next = curr; + else + head = curr; + prev = curr; + } + if (head) + dev_info(&dev->dev, "adding IRQ-less MPU options\n"); + + return head; +} + +static void quirk_ad1815_mpu_resources(struct pnp_dev *dev) +{ + struct pnp_option *res; + struct pnp_irq *irq; + + /* + * Distribute the independent IRQ over the dependent options + */ + + res = dev->independent; + if (!res) + return; + + irq = res->irq; + if (!irq || irq->next) + return; + + res = dev->dependent; + if (!res) + return; + + while (1) { + struct pnp_irq *copy; + + copy = pnp_alloc(sizeof *copy); + if (!copy) + break; + + memcpy(copy->map, irq->map, sizeof copy->map); + copy->flags = irq->flags; + + copy->next = res->irq; /* Yes, this is NULL */ + res->irq = copy; + + if (!res->next) + break; + res = res->next; + } + kfree(irq); + + res->next = quirk_isapnp_mpu_options(dev); + + res = dev->independent; + res->irq = NULL; +} + +static void quirk_isapnp_mpu_resources(struct pnp_dev *dev) +{ + struct pnp_option *res; + + res = dev->dependent; + if (!res) + return; + + while (res->next) + res = res->next; + + res->next = quirk_isapnp_mpu_options(dev); +} #include @@ -205,6 +312,11 @@ static struct pnp_fixup pnp_fixups[] = { {"CTL0043", quirk_sb16audio_resources}, {"CTL0044", quirk_sb16audio_resources}, {"CTL0045", quirk_sb16audio_resources}, + /* Add IRQ-less MPU options */ + {"ADS7151", quirk_ad1815_mpu_resources}, + {"ADS7181", quirk_isapnp_mpu_resources}, + {"AZT0002", quirk_isapnp_mpu_resources}, + /* PnP resources that might overlap PCI BARs */ {"PNP0c01", quirk_system_pci_resources}, {"PNP0c02", quirk_system_pci_resources}, {""} @@ -212,20 +324,15 @@ static struct pnp_fixup pnp_fixups[] = { void pnp_fixup_device(struct pnp_dev *dev) { - int i = 0; - void (*quirk)(struct pnp_dev *); - - while (*pnp_fixups[i].id) { - if (compare_pnp_id(dev->id, pnp_fixups[i].id)) { - quirk = pnp_fixups[i].quirk_function; + struct pnp_fixup *f; + for (f = pnp_fixups; *f->id; f++) { + if (!compare_pnp_id(dev->id, f->id)) + continue; #ifdef DEBUG - dev_dbg(&dev->dev, "calling "); - print_fn_descriptor_symbol("%s()\n", - (unsigned long) *quirk); + dev_dbg(&dev->dev, "%s: calling ", f->id); + print_fn_descriptor_symbol("%s\n", f->quirk_function); #endif - (*quirk)(dev); - } - i++; + f->quirk_function(dev); } } diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c index 2041620d5682828a1fd872d9e769e92f76dbedb0..390b50096e30890f57d6cf6f55dc730d18013b47 100644 --- a/drivers/pnp/resource.c +++ b/drivers/pnp/resource.c @@ -28,7 +28,7 @@ static int pnp_reserve_mem[16] = {[0 ... 15] = -1 }; /* reserve (don't use) some * option registration */ -static struct pnp_option *pnp_build_option(int priority) +struct pnp_option *pnp_build_option(int priority) { struct pnp_option *option = pnp_alloc(sizeof(struct pnp_option)); diff --git a/drivers/pnp/support.c b/drivers/pnp/support.c index 3eba85ed729cfb28634e9bdc65f91adb066080c8..95b076c18c075677cd49449b8bec9bf9492ab0d8 100644 --- a/drivers/pnp/support.c +++ b/drivers/pnp/support.c @@ -45,10 +45,10 @@ void pnp_eisa_id_to_string(u32 id, char *str) str[0] = 'A' + ((id >> 26) & 0x3f) - 1; str[1] = 'A' + ((id >> 21) & 0x1f) - 1; str[2] = 'A' + ((id >> 16) & 0x1f) - 1; - str[3] = hex_asc((id >> 12) & 0xf); - str[4] = hex_asc((id >> 8) & 0xf); - str[5] = hex_asc((id >> 4) & 0xf); - str[6] = hex_asc((id >> 0) & 0xf); + str[3] = hex_asc_hi(id >> 8); + str[4] = hex_asc_lo(id >> 8); + str[5] = hex_asc_hi(id); + str[6] = hex_asc_lo(id); str[7] = '\0'; } diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c index a83a40b3ebaaf9ad67b08c97a52a481645a0f4fa..0f0d27d1c4ca366916b7958798ac44570681f679 100644 --- a/drivers/rtc/rtc-ds1511.c +++ b/drivers/rtc/rtc-ds1511.c @@ -184,7 +184,7 @@ ds1511_wdog_disable(void) static int ds1511_rtc_set_time(struct device *dev, struct rtc_time *rtc_tm) { u8 mon, day, dow, hrs, min, sec, yrs, cen; - unsigned int flags; + unsigned long flags; /* * won't have to change this for a while @@ -247,7 +247,7 @@ static int ds1511_rtc_set_time(struct device *dev, struct rtc_time *rtc_tm) static int ds1511_rtc_read_time(struct device *dev, struct rtc_time *rtc_tm) { unsigned int century; - unsigned int flags; + unsigned long flags; spin_lock_irqsave(&ds1511_lock, flags); rtc_disable_update(); diff --git a/drivers/rtc/rtc-lib.c b/drivers/rtc/rtc-lib.c index ba795a4db1e97289829c3c69dbee613fa2720a25..9f996ec881ce90dbf2a97cef5ecb73e090d634c7 100644 --- a/drivers/rtc/rtc-lib.c +++ b/drivers/rtc/rtc-lib.c @@ -51,7 +51,7 @@ EXPORT_SYMBOL(rtc_year_days); */ void rtc_time_to_tm(unsigned long time, struct rtc_time *tm) { - register int days, month, year; + unsigned int days, month, year; days = time / 86400; time -= days * 86400; diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index 316bfaa80872195badfeda9ec87de81265d77d96..a3e0880b38fb2cdb0116b4168664566fdab84ab4 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -803,6 +804,7 @@ static int m41t80_probe(struct i2c_client *client, #ifdef CONFIG_RTC_DRV_M41T80_WDT if (clientdata->features & M41T80_FEATURE_HT) { + save_client = client; rc = misc_register(&wdt_dev); if (rc) goto exit; @@ -811,7 +813,6 @@ static int m41t80_probe(struct i2c_client *client, misc_deregister(&wdt_dev); goto exit; } - save_client = client; } #endif return 0; diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c index 29f47bacfc77b5503086473f858fb1cc6124f33e..a6fa1f2f2ca6b59726ab099e46a698b4e26cae2d 100644 --- a/drivers/rtc/rtc-s35390a.c +++ b/drivers/rtc/rtc-s35390a.c @@ -227,7 +227,7 @@ static int s35390a_probe(struct i2c_client *client, /* This chip uses multiple addresses, use dummy devices for them */ for (i = 1; i < 8; ++i) { s35390a->client[i] = i2c_new_dummy(client->adapter, - client->addr + i, "rtc-s35390a"); + client->addr + i); if (!s35390a->client[i]) { dev_err(&client->dev, "Address %02x unavailable\n", client->addr + i); diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c index 110699bb478751ac619b1e0a6869059dc99318a8..1f88e9e914ec97d41c139519ab6e2e34c77ea4e2 100644 --- a/drivers/rtc/rtc-sh.c +++ b/drivers/rtc/rtc-sh.c @@ -616,7 +616,7 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev) goto err_badres; } - rtc->regbase = (void __iomem *)rtc->res->start; + rtc->regbase = ioremap_nocache(rtc->res->start, rtc->regsize); if (unlikely(!rtc->regbase)) { ret = -EINVAL; goto err_badmap; @@ -626,7 +626,7 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev) &sh_rtc_ops, THIS_MODULE); if (IS_ERR(rtc->rtc_dev)) { ret = PTR_ERR(rtc->rtc_dev); - goto err_badmap; + goto err_unmap; } rtc->capabilities = RTC_DEF_CAPABILITIES; @@ -653,7 +653,7 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev) dev_err(&pdev->dev, "request period IRQ failed with %d, IRQ %d\n", ret, rtc->periodic_irq); - goto err_badmap; + goto err_unmap; } ret = request_irq(rtc->carry_irq, sh_rtc_interrupt, IRQF_DISABLED, @@ -663,7 +663,7 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev) "request carry IRQ failed with %d, IRQ %d\n", ret, rtc->carry_irq); free_irq(rtc->periodic_irq, rtc); - goto err_badmap; + goto err_unmap; } ret = request_irq(rtc->alarm_irq, sh_rtc_alarm, IRQF_DISABLED, @@ -674,7 +674,7 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev) rtc->alarm_irq); free_irq(rtc->carry_irq, rtc); free_irq(rtc->periodic_irq, rtc); - goto err_badmap; + goto err_unmap; } tmp = readb(rtc->regbase + RCR1); @@ -684,6 +684,8 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev) return 0; +err_unmap: + iounmap(rtc->regbase); err_badmap: release_resource(rtc->res); err_badres: @@ -708,6 +710,8 @@ static int __devexit sh_rtc_remove(struct platform_device *pdev) release_resource(rtc->res); + iounmap(rtc->regbase); + platform_set_drvdata(pdev, NULL); kfree(rtc); diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index ac6d4d3218b3d9c4d7652407c5847d87dc844fbb..8ba3f135da221fe59cfeb2badf3c25df8e28cdb5 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -925,6 +925,8 @@ static void dasd_handle_killed_request(struct ccw_device *cdev, struct dasd_ccw_req *cqr; struct dasd_device *device; + if (!intparm) + return; cqr = (struct dasd_ccw_req *) intparm; if (cqr->status != DASD_CQR_IN_IO) { MESSAGE(KERN_DEBUG, @@ -976,17 +978,16 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm, if (IS_ERR(irb)) { switch (PTR_ERR(irb)) { case -EIO: - dasd_handle_killed_request(cdev, intparm); break; case -ETIMEDOUT: printk(KERN_WARNING"%s(%s): request timed out\n", __func__, cdev->dev.bus_id); - //FIXME - dasd uses own timeout interface... break; default: printk(KERN_WARNING"%s(%s): unknown error %ld\n", __func__, cdev->dev.bus_id, PTR_ERR(irb)); } + dasd_handle_killed_request(cdev, intparm); return; } diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c index f4fb40257348e3bd3e42b59b1061332233e1eed0..d774e79476fee0c73e967979781210aa0faffdef 100644 --- a/drivers/s390/block/dasd_devmap.c +++ b/drivers/s390/block/dasd_devmap.c @@ -86,10 +86,10 @@ static DEFINE_SPINLOCK(dasd_devmap_lock); static struct list_head dasd_hashlists[256]; int dasd_max_devindex; -static struct dasd_devmap *dasd_add_busid(char *, int); +static struct dasd_devmap *dasd_add_busid(const char *, int); static inline int -dasd_hash_busid(char *bus_id) +dasd_hash_busid(const char *bus_id) { int hash, i; @@ -394,7 +394,7 @@ dasd_parse(void) * devices. */ static struct dasd_devmap * -dasd_add_busid(char *bus_id, int features) +dasd_add_busid(const char *bus_id, int features) { struct dasd_devmap *devmap, *new, *tmp; int hash; @@ -430,7 +430,7 @@ dasd_add_busid(char *bus_id, int features) * Find devmap for device with given bus_id. */ static struct dasd_devmap * -dasd_find_busid(char *bus_id) +dasd_find_busid(const char *bus_id) { struct dasd_devmap *devmap, *tmp; int hash; @@ -452,7 +452,7 @@ dasd_find_busid(char *bus_id) * Check if busid has been added to the list of dasd ranges. */ int -dasd_busid_known(char *bus_id) +dasd_busid_known(const char *bus_id) { return IS_ERR(dasd_find_busid(bus_id)) ? -ENOENT : 0; } diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index 6c624bf44617174887ceab0e3395fc6491ab0c97..fb2f931cf8441d66c0fab05806c8f218f63d5308 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h @@ -598,7 +598,7 @@ struct dasd_device *dasd_device_from_cdev_locked(struct ccw_device *); struct dasd_device *dasd_device_from_devindex(int); int dasd_parse(void); -int dasd_busid_known(char *); +int dasd_busid_known(const char *); /* externals in dasd_gendisk.c */ int dasd_gendisk_init(void); diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c index 7ad8cf157641a22dd000831de72173f76aa2e5e6..76e44eb7c47f74c7d45988e0fa50316a5480620b 100644 --- a/drivers/s390/char/tape_core.c +++ b/drivers/s390/char/tape_core.c @@ -76,32 +76,9 @@ const char *tape_op_verbose[TO_SIZE] = [TO_KEKL_QUERY] = "KLQ",[TO_RDC] = "RDC", }; -static int -busid_to_int(char *bus_id) +static int devid_to_int(struct ccw_dev_id *dev_id) { - int dec; - int d; - char * s; - - for(s = bus_id, d = 0; *s != '\0' && *s != '.'; s++) - d = (d * 10) + (*s - '0'); - dec = d; - for(s++, d = 0; *s != '\0' && *s != '.'; s++) - d = (d * 10) + (*s - '0'); - dec = (dec << 8) + d; - - for(s++; *s != '\0'; s++) { - if (*s >= '0' && *s <= '9') { - d = *s - '0'; - } else if (*s >= 'a' && *s <= 'f') { - d = *s - 'a' + 10; - } else { - d = *s - 'A' + 10; - } - dec = (dec << 4) + d; - } - - return dec; + return dev_id->devno + (dev_id->ssid << 16); } /* @@ -551,6 +528,7 @@ tape_generic_probe(struct ccw_device *cdev) { struct tape_device *device; int ret; + struct ccw_dev_id dev_id; device = tape_alloc_device(); if (IS_ERR(device)) @@ -565,7 +543,8 @@ tape_generic_probe(struct ccw_device *cdev) cdev->dev.driver_data = device; cdev->handler = __tape_do_irq; device->cdev = cdev; - device->cdev_id = busid_to_int(cdev->dev.bus_id); + ccw_device_get_id(cdev, &dev_id); + device->cdev_id = devid_to_int(&dev_id); PRINT_INFO("tape device %s found\n", cdev->dev.bus_id); return ret; } diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c index c1f2adefad410287fe170ae77a8baa47a8611187..5043150019ac0788e91d4a42ee1d49955c99d527 100644 --- a/drivers/s390/char/tty3270.c +++ b/drivers/s390/char/tty3270.c @@ -965,8 +965,7 @@ tty3270_write_room(struct tty_struct *tty) * Insert character into the screen at the current position with the * current color and highlight. This function does NOT do cursor movement. */ -static int -tty3270_put_character(struct tty3270 *tp, char ch) +static void tty3270_put_character(struct tty3270 *tp, char ch) { struct tty3270_line *line; struct tty3270_cell *cell; @@ -986,7 +985,6 @@ tty3270_put_character(struct tty3270 *tp, char ch) cell->character = tp->view.ascebc[(unsigned int) ch]; cell->highlight = tp->highlight; cell->f_color = tp->f_color; - return 1; } /* @@ -1612,16 +1610,15 @@ tty3270_write(struct tty_struct * tty, /* * Put single characters to the ttys character buffer */ -static void -tty3270_put_char(struct tty_struct *tty, unsigned char ch) +static int tty3270_put_char(struct tty_struct *tty, unsigned char ch) { struct tty3270 *tp; tp = tty->driver_data; - if (!tp) - return; - if (tp->char_count < TTY3270_CHAR_BUF_SIZE) - tp->char_buf[tp->char_count++] = ch; + if (!tp || tp->char_count >= TTY3270_CHAR_BUF_SIZE) + return 0; + tp->char_buf[tp->char_count++] = ch; + return 1; } /* diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c index d364e0bfae12eb1ff999439aee0a94fa7c99087d..e8487347e4d4aa33eb7e844e815ad77028b50f16 100644 --- a/drivers/s390/char/vmlogrdr.c +++ b/drivers/s390/char/vmlogrdr.c @@ -858,7 +858,7 @@ static int __init vmlogrdr_init(void) for (i=0; i < MAXMINOR; ++i ) { sys_ser[i].buffer = (char *) get_zeroed_page(GFP_KERNEL); if (!sys_ser[i].buffer) { - rc = ENOMEM; + rc = -ENOMEM; break; } sys_ser[i].current_position = sys_ser[i].buffer; diff --git a/drivers/s390/cio/blacklist.c b/drivers/s390/cio/blacklist.c index 40ef948fcb3a5e9b2441bacb6a78fd65f9a693cf..a4a5f2efea4865cd4932ef92a01ea3460cd1a300 100644 --- a/drivers/s390/cio/blacklist.c +++ b/drivers/s390/cio/blacklist.c @@ -43,164 +43,169 @@ typedef enum {add, free} range_action; * Function: blacklist_range * (Un-)blacklist the devices from-to */ -static void -blacklist_range (range_action action, unsigned int from, unsigned int to, - unsigned int ssid) +static int blacklist_range(range_action action, unsigned int from_ssid, + unsigned int to_ssid, unsigned int from, + unsigned int to, int msgtrigger) { - if (!to) - to = from; - - if (from > to || to > __MAX_SUBCHANNEL || ssid > __MAX_SSID) { - printk (KERN_WARNING "cio: Invalid blacklist range " - "0.%x.%04x to 0.%x.%04x, skipping\n", - ssid, from, ssid, to); - return; + if ((from_ssid > to_ssid) || ((from_ssid == to_ssid) && (from > to))) { + if (msgtrigger) + printk(KERN_WARNING "cio: Invalid cio_ignore range " + "0.%x.%04x-0.%x.%04x\n", from_ssid, from, + to_ssid, to); + return 1; } - for (; from <= to; from++) { + + while ((from_ssid < to_ssid) || ((from_ssid == to_ssid) && + (from <= to))) { if (action == add) - set_bit (from, bl_dev[ssid]); + set_bit(from, bl_dev[from_ssid]); else - clear_bit (from, bl_dev[ssid]); + clear_bit(from, bl_dev[from_ssid]); + from++; + if (from > __MAX_SUBCHANNEL) { + from_ssid++; + from = 0; + } } + + return 0; } -/* - * Function: blacklist_busid - * Get devno/busid from given string. - * Shamelessly grabbed from dasd_devmap.c. - */ -static int -blacklist_busid(char **str, int *id0, int *ssid, int *devno) +static int pure_hex(char **cp, unsigned int *val, int min_digit, + int max_digit, int max_val) { - int val, old_style; - char *sav; + int diff; + unsigned int value; - sav = *str; + diff = 0; + *val = 0; - /* check for leading '0x' */ - old_style = 0; - if ((*str)[0] == '0' && (*str)[1] == 'x') { - *str += 2; - old_style = 1; - } - if (!isxdigit((*str)[0])) /* We require at least one hex digit */ - goto confused; - val = simple_strtoul(*str, str, 16); - if (old_style || (*str)[0] != '.') { - *id0 = *ssid = 0; - if (val < 0 || val > 0xffff) - goto confused; - *devno = val; - if ((*str)[0] != ',' && (*str)[0] != '-' && - (*str)[0] != '\n' && (*str)[0] != '\0') - goto confused; - return 0; + while (isxdigit(**cp) && (diff <= max_digit)) { + + if (isdigit(**cp)) + value = **cp - '0'; + else + value = tolower(**cp) - 'a' + 10; + *val = *val * 16 + value; + (*cp)++; + diff++; } - /* New style x.y.z busid */ - if (val < 0 || val > 0xff) - goto confused; - *id0 = val; - (*str)++; - if (!isxdigit((*str)[0])) /* We require at least one hex digit */ - goto confused; - val = simple_strtoul(*str, str, 16); - if (val < 0 || val > 0xff || (*str)++[0] != '.') - goto confused; - *ssid = val; - if (!isxdigit((*str)[0])) /* We require at least one hex digit */ - goto confused; - val = simple_strtoul(*str, str, 16); - if (val < 0 || val > 0xffff) - goto confused; - *devno = val; - if ((*str)[0] != ',' && (*str)[0] != '-' && - (*str)[0] != '\n' && (*str)[0] != '\0') - goto confused; + + if ((diff < min_digit) || (diff > max_digit) || (*val > max_val)) + return 1; + return 0; -confused: - strsep(str, ",\n"); - printk(KERN_WARNING "cio: Invalid cio_ignore parameter '%s'\n", sav); - return 1; } -static int -blacklist_parse_parameters (char *str, range_action action) +static int parse_busid(char *str, int *cssid, int *ssid, int *devno, + int msgtrigger) { - int from, to, from_id0, to_id0, from_ssid, to_ssid; - - while (*str != 0 && *str != '\n') { - range_action ra = action; - while(*str == ',') - str++; - if (*str == '!') { - ra = !action; - ++str; + char *str_work; + int val, rc, ret; + + rc = 1; + + if (*str == '\0') + goto out; + + /* old style */ + str_work = str; + val = simple_strtoul(str, &str_work, 16); + + if (*str_work == '\0') { + if (val <= __MAX_SUBCHANNEL) { + *devno = val; + *ssid = 0; + *cssid = 0; + rc = 0; } + goto out; + } - /* - * Since we have to parse the proc commands and the - * kernel arguments we have to check four cases - */ - if (strncmp(str,"all,",4) == 0 || strcmp(str,"all") == 0 || - strncmp(str,"all\n",4) == 0 || strncmp(str,"all ",4) == 0) { - int j; - - str += 3; - for (j=0; j <= __MAX_SSID; j++) - blacklist_range(ra, 0, __MAX_SUBCHANNEL, j); - } else { - int rc; + /* new style */ + str_work = str; + ret = pure_hex(&str_work, cssid, 1, 2, __MAX_CSSID); + if (ret || (str_work[0] != '.')) + goto out; + str_work++; + ret = pure_hex(&str_work, ssid, 1, 1, __MAX_SSID); + if (ret || (str_work[0] != '.')) + goto out; + str_work++; + ret = pure_hex(&str_work, devno, 4, 4, __MAX_SUBCHANNEL); + if (ret || (str_work[0] != '\0')) + goto out; + + rc = 0; +out: + if (rc && msgtrigger) + printk(KERN_WARNING "cio: Invalid cio_ignore device '%s'\n", + str); + + return rc; +} - rc = blacklist_busid(&str, &from_id0, - &from_ssid, &from); - if (rc) - continue; - to = from; - to_id0 = from_id0; - to_ssid = from_ssid; - if (*str == '-') { - str++; - rc = blacklist_busid(&str, &to_id0, - &to_ssid, &to); - if (rc) - continue; - } - if (*str == '-') { - printk(KERN_WARNING "cio: invalid cio_ignore " - "parameter '%s'\n", - strsep(&str, ",\n")); - continue; - } - if ((from_id0 != to_id0) || - (from_ssid != to_ssid)) { - printk(KERN_WARNING "cio: invalid cio_ignore " - "range %x.%x.%04x-%x.%x.%04x\n", - from_id0, from_ssid, from, - to_id0, to_ssid, to); - continue; +static int blacklist_parse_parameters(char *str, range_action action, + int msgtrigger) +{ + int from_cssid, to_cssid, from_ssid, to_ssid, from, to; + int rc, totalrc; + char *parm; + range_action ra; + + totalrc = 0; + + while ((parm = strsep(&str, ","))) { + rc = 0; + ra = action; + if (*parm == '!') { + if (ra == add) + ra = free; + else + ra = add; + parm++; + } + if (strcmp(parm, "all") == 0) { + from_cssid = 0; + from_ssid = 0; + from = 0; + to_cssid = __MAX_CSSID; + to_ssid = __MAX_SSID; + to = __MAX_SUBCHANNEL; + } else { + rc = parse_busid(strsep(&parm, "-"), &from_cssid, + &from_ssid, &from, msgtrigger); + if (!rc) { + if (parm != NULL) + rc = parse_busid(parm, &to_cssid, + &to_ssid, &to, + msgtrigger); + else { + to_cssid = from_cssid; + to_ssid = from_ssid; + to = from; + } } - blacklist_range (ra, from, to, to_ssid); } + if (!rc) { + rc = blacklist_range(ra, from_ssid, to_ssid, from, to, + msgtrigger); + if (rc) + totalrc = 1; + } else + totalrc = 1; } - return 1; + + return totalrc; } -/* Parsing the commandline for blacklist parameters, e.g. to blacklist - * bus ids 0.0.1234, 0.0.1235 and 0.0.1236, you could use any of: - * - cio_ignore=1234-1236 - * - cio_ignore=0x1234-0x1235,1236 - * - cio_ignore=0x1234,1235-1236 - * - cio_ignore=1236 cio_ignore=1234-0x1236 - * - cio_ignore=1234 cio_ignore=1236 cio_ignore=0x1235 - * - cio_ignore=0.0.1234-0.0.1236 - * - cio_ignore=0.0.1234,0x1235,1236 - * - ... - */ static int __init blacklist_setup (char *str) { CIO_MSG_EVENT(6, "Reading blacklist parameters\n"); - return blacklist_parse_parameters (str, add); + if (blacklist_parse_parameters(str, add, 1)) + return 0; + return 1; } __setup ("cio_ignore=", blacklist_setup); @@ -224,27 +229,23 @@ is_blacklisted (int ssid, int devno) * Function: blacklist_parse_proc_parameters * parse the stuff which is piped to /proc/cio_ignore */ -static void -blacklist_parse_proc_parameters (char *buf) +static int blacklist_parse_proc_parameters(char *buf) { - if (strncmp (buf, "free ", 5) == 0) { - blacklist_parse_parameters (buf + 5, free); - } else if (strncmp (buf, "add ", 4) == 0) { - /* - * We don't need to check for known devices since - * css_probe_device will handle this correctly. - */ - blacklist_parse_parameters (buf + 4, add); - } else { - printk (KERN_WARNING "cio: cio_ignore: Parse error; \n" - KERN_WARNING "try using 'free all|," - ",...'\n" - KERN_WARNING "or 'add ," - ",...'\n"); - return; - } + int rc; + char *parm; + + parm = strsep(&buf, " "); + + if (strcmp("free", parm) == 0) + rc = blacklist_parse_parameters(buf, free, 0); + else if (strcmp("add", parm) == 0) + rc = blacklist_parse_parameters(buf, add, 0); + else + return 1; css_schedule_reprobe(); + + return rc; } /* Iterator struct for all devices. */ @@ -328,6 +329,8 @@ cio_ignore_write(struct file *file, const char __user *user_buf, size_t user_len, loff_t *offset) { char *buf; + size_t i; + ssize_t rc, ret; if (*offset) return -EINVAL; @@ -336,16 +339,27 @@ cio_ignore_write(struct file *file, const char __user *user_buf, buf = vmalloc (user_len + 1); /* maybe better use the stack? */ if (buf == NULL) return -ENOMEM; + memset(buf, 0, user_len + 1); + if (strncpy_from_user (buf, user_buf, user_len) < 0) { - vfree (buf); - return -EFAULT; + rc = -EFAULT; + goto out_free; } - buf[user_len] = '\0'; - blacklist_parse_proc_parameters (buf); + i = user_len - 1; + while ((i >= 0) && (isspace(buf[i]) || (buf[i] == 0))) { + buf[i] = '\0'; + i--; + } + ret = blacklist_parse_proc_parameters(buf); + if (ret) + rc = -EINVAL; + else + rc = user_len; +out_free: vfree (buf); - return user_len; + return rc; } static const struct seq_operations cio_ignore_proc_seq_ops = { diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 08a578161306e1088f4fe6786ea85b518cfd7a12..82c6a2d451284424c40fc14791736f642ef80934 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c @@ -39,23 +39,6 @@ debug_info_t *cio_debug_msg_id; debug_info_t *cio_debug_trace_id; debug_info_t *cio_debug_crw_id; -int cio_show_msg; - -static int __init -cio_setup (char *parm) -{ - if (!strcmp (parm, "yes")) - cio_show_msg = 1; - else if (!strcmp (parm, "no")) - cio_show_msg = 0; - else - printk(KERN_ERR "cio: cio_setup: " - "invalid cio_msg parameter '%s'", parm); - return 1; -} - -__setup ("cio_msg=", cio_setup); - /* * Function: cio_debug_init * Initializes three debug logs for common I/O: @@ -166,7 +149,7 @@ cio_start_handle_notoper(struct subchannel *sch, __u8 lpm) stsch (sch->schid, &sch->schib); - CIO_MSG_EVENT(0, "cio_start: 'not oper' status for " + CIO_MSG_EVENT(2, "cio_start: 'not oper' status for " "subchannel 0.%x.%04x!\n", sch->schid.ssid, sch->schid.sch_no); sprintf(dbf_text, "no%s", sch->dev.bus_id); @@ -567,10 +550,9 @@ cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid) * ... just being curious we check for non I/O subchannels */ if (sch->st != 0) { - CIO_DEBUG(KERN_INFO, 0, - "Subchannel 0.%x.%04x reports " - "non-I/O subchannel type %04X\n", - sch->schid.ssid, sch->schid.sch_no, sch->st); + CIO_MSG_EVENT(4, "Subchannel 0.%x.%04x reports " + "non-I/O subchannel type %04X\n", + sch->schid.ssid, sch->schid.sch_no, sch->st); /* We stop here for non-io subchannels. */ err = sch->st; goto out; @@ -588,7 +570,7 @@ cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid) * This device must not be known to Linux. So we simply * say that there is no device and return ENODEV. */ - CIO_MSG_EVENT(4, "Blacklisted device detected " + CIO_MSG_EVENT(6, "Blacklisted device detected " "at devno %04X, subchannel set %x\n", sch->schib.pmcw.dev, sch->schid.ssid); err = -ENODEV; @@ -601,12 +583,11 @@ cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid) sch->lpm = sch->schib.pmcw.pam & sch->opm; sch->isc = 3; - CIO_DEBUG(KERN_INFO, 0, - "Detected device %04x on subchannel 0.%x.%04X" - " - PIM = %02X, PAM = %02X, POM = %02X\n", - sch->schib.pmcw.dev, sch->schid.ssid, - sch->schid.sch_no, sch->schib.pmcw.pim, - sch->schib.pmcw.pam, sch->schib.pmcw.pom); + CIO_MSG_EVENT(6, "Detected device %04x on subchannel 0.%x.%04X " + "- PIM = %02X, PAM = %02X, POM = %02X\n", + sch->schib.pmcw.dev, sch->schid.ssid, + sch->schid.sch_no, sch->schib.pmcw.pim, + sch->schib.pmcw.pam, sch->schib.pmcw.pom); /* * We now have to initially ... diff --git a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h index 3c75412904dc495eade9f6627b148adc730e6e82..6e933aebe01308e2882f45f0320c72a9612e133d 100644 --- a/drivers/s390/cio/cio.h +++ b/drivers/s390/cio/cio.h @@ -118,6 +118,4 @@ extern void *cio_get_console_priv(void); #define cio_get_console_priv() NULL #endif -extern int cio_show_msg; - #endif diff --git a/drivers/s390/cio/cio_debug.h b/drivers/s390/cio/cio_debug.h index d7429ef6c666c1c56a4fa8b2ab05e04cc69901cf..e64e8278c42e9979af1d35fb57c685be02327731 100644 --- a/drivers/s390/cio/cio_debug.h +++ b/drivers/s390/cio/cio_debug.h @@ -31,10 +31,4 @@ static inline void CIO_HEX_EVENT(int level, void *data, int length) } } -#define CIO_DEBUG(printk_level, event_level, msg...) do { \ - if (cio_show_msg) \ - printk(printk_level "cio: " msg); \ - CIO_MSG_EVENT(event_level, msg); \ - } while (0) - #endif diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 595e327d2f76cc4f47d7f7682fb7e99e88647c3e..a76956512b2d41963a0bd89ddba91a69f7b2553a 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -570,7 +570,7 @@ static void reprobe_all(struct work_struct *unused) { int ret; - CIO_MSG_EVENT(2, "reprobe start\n"); + CIO_MSG_EVENT(4, "reprobe start\n"); need_reprobe = 0; /* Make sure initial subchannel scan is done. */ @@ -578,7 +578,7 @@ static void reprobe_all(struct work_struct *unused) atomic_read(&ccw_device_init_count) == 0); ret = for_each_subchannel_staged(NULL, reprobe_subchannel, NULL); - CIO_MSG_EVENT(2, "reprobe done (rc=%d, need_reprobe=%d)\n", ret, + CIO_MSG_EVENT(4, "reprobe done (rc=%d, need_reprobe=%d)\n", ret, need_reprobe); } diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index abfd601d237a1a07c9aa852e671a8bde507f6cc4..e22813db74a2b6bb81d2d0e1e27ec64acde946e2 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -341,7 +341,7 @@ ccw_device_remove_disconnected(struct ccw_device *cdev) rc = device_schedule_callback(&cdev->dev, ccw_device_remove_orphan_cb); if (rc) - CIO_MSG_EVENT(2, "Couldn't unregister orphan " + CIO_MSG_EVENT(0, "Couldn't unregister orphan " "0.%x.%04x\n", cdev->private->dev_id.ssid, cdev->private->dev_id.devno); @@ -351,7 +351,7 @@ ccw_device_remove_disconnected(struct ccw_device *cdev) rc = device_schedule_callback(cdev->dev.parent, ccw_device_remove_sch_cb); if (rc) - CIO_MSG_EVENT(2, "Couldn't unregister disconnected device " + CIO_MSG_EVENT(0, "Couldn't unregister disconnected device " "0.%x.%04x\n", cdev->private->dev_id.ssid, cdev->private->dev_id.devno); @@ -397,7 +397,7 @@ int ccw_device_set_offline(struct ccw_device *cdev) if (ret == 0) wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev)); else { - CIO_MSG_EVENT(2, "ccw_device_offline returned %d, " + CIO_MSG_EVENT(0, "ccw_device_offline returned %d, " "device 0.%x.%04x\n", ret, cdev->private->dev_id.ssid, cdev->private->dev_id.devno); @@ -433,7 +433,7 @@ int ccw_device_set_online(struct ccw_device *cdev) if (ret == 0) wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev)); else { - CIO_MSG_EVENT(2, "ccw_device_online returned %d, " + CIO_MSG_EVENT(0, "ccw_device_online returned %d, " "device 0.%x.%04x\n", ret, cdev->private->dev_id.ssid, cdev->private->dev_id.devno); @@ -451,7 +451,7 @@ int ccw_device_set_online(struct ccw_device *cdev) if (ret == 0) wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev)); else - CIO_MSG_EVENT(2, "ccw_device_offline returned %d, " + CIO_MSG_EVENT(0, "ccw_device_offline returned %d, " "device 0.%x.%04x\n", ret, cdev->private->dev_id.ssid, cdev->private->dev_id.devno); @@ -803,7 +803,7 @@ static void sch_attach_disconnected_device(struct subchannel *sch, other_sch = to_subchannel(get_device(cdev->dev.parent)); ret = device_move(&cdev->dev, &sch->dev); if (ret) { - CIO_MSG_EVENT(2, "Moving disconnected device 0.%x.%04x failed " + CIO_MSG_EVENT(0, "Moving disconnected device 0.%x.%04x failed " "(ret=%d)!\n", cdev->private->dev_id.ssid, cdev->private->dev_id.devno, ret); put_device(&other_sch->dev); @@ -933,7 +933,7 @@ io_subchannel_register(struct work_struct *work) ret = device_reprobe(&cdev->dev); if (ret) /* We can't do much here. */ - CIO_MSG_EVENT(2, "device_reprobe() returned" + CIO_MSG_EVENT(0, "device_reprobe() returned" " %d for 0.%x.%04x\n", ret, cdev->private->dev_id.ssid, cdev->private->dev_id.devno); @@ -1086,7 +1086,7 @@ static void ccw_device_move_to_sch(struct work_struct *work) rc = device_move(&cdev->dev, &sch->dev); mutex_unlock(&sch->reg_mutex); if (rc) { - CIO_MSG_EVENT(2, "Moving device 0.%x.%04x to subchannel " + CIO_MSG_EVENT(0, "Moving device 0.%x.%04x to subchannel " "0.%x.%04x failed (ret=%d)!\n", cdev->private->dev_id.ssid, cdev->private->dev_id.devno, sch->schid.ssid, @@ -1446,8 +1446,7 @@ ccw_device_remove (struct device *dev) wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev)); else - //FIXME: we can't fail! - CIO_MSG_EVENT(2, "ccw_device_offline returned %d, " + CIO_MSG_EVENT(0, "ccw_device_offline returned %d, " "device 0.%x.%04x\n", ret, cdev->private->dev_id.ssid, cdev->private->dev_id.devno); @@ -1524,7 +1523,7 @@ static int recovery_check(struct device *dev, void *data) spin_lock_irq(cdev->ccwlock); switch (cdev->private->state) { case DEV_STATE_DISCONNECTED: - CIO_MSG_EVENT(3, "recovery: trigger 0.%x.%04x\n", + CIO_MSG_EVENT(4, "recovery: trigger 0.%x.%04x\n", cdev->private->dev_id.ssid, cdev->private->dev_id.devno); dev_fsm_event(cdev, DEV_EVENT_VERIFY); @@ -1554,7 +1553,7 @@ static void recovery_work_func(struct work_struct *unused) } spin_unlock_irq(&recovery_lock); } else - CIO_MSG_EVENT(2, "recovery: end\n"); + CIO_MSG_EVENT(4, "recovery: end\n"); } static DECLARE_WORK(recovery_work, recovery_work_func); @@ -1572,7 +1571,7 @@ void ccw_device_schedule_recovery(void) { unsigned long flags; - CIO_MSG_EVENT(2, "recovery: schedule\n"); + CIO_MSG_EVENT(4, "recovery: schedule\n"); spin_lock_irqsave(&recovery_lock, flags); if (!timer_pending(&recovery_timer) || (recovery_phase != 0)) { recovery_phase = 0; diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index 99403b0a97a7737a4865f72d41453048d1fb2600..e268d5a77c12633c4d80d5493add727229fe94fa 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c @@ -322,10 +322,10 @@ ccw_device_recog_done(struct ccw_device *cdev, int state) same_dev = 0; /* Keep the compiler quiet... */ switch (state) { case DEV_STATE_NOT_OPER: - CIO_DEBUG(KERN_WARNING, 2, - "SenseID : unknown device %04x on subchannel " - "0.%x.%04x\n", cdev->private->dev_id.devno, - sch->schid.ssid, sch->schid.sch_no); + CIO_MSG_EVENT(2, "SenseID : unknown device %04x on " + "subchannel 0.%x.%04x\n", + cdev->private->dev_id.devno, + sch->schid.ssid, sch->schid.sch_no); break; case DEV_STATE_OFFLINE: if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID) { @@ -348,20 +348,19 @@ ccw_device_recog_done(struct ccw_device *cdev, int state) return; } /* Issue device info message. */ - CIO_DEBUG(KERN_INFO, 2, - "SenseID : device 0.%x.%04x reports: " - "CU Type/Mod = %04X/%02X, Dev Type/Mod = " - "%04X/%02X\n", - cdev->private->dev_id.ssid, - cdev->private->dev_id.devno, - cdev->id.cu_type, cdev->id.cu_model, - cdev->id.dev_type, cdev->id.dev_model); + CIO_MSG_EVENT(4, "SenseID : device 0.%x.%04x reports: " + "CU Type/Mod = %04X/%02X, Dev Type/Mod = " + "%04X/%02X\n", + cdev->private->dev_id.ssid, + cdev->private->dev_id.devno, + cdev->id.cu_type, cdev->id.cu_model, + cdev->id.dev_type, cdev->id.dev_model); break; case DEV_STATE_BOXED: - CIO_DEBUG(KERN_WARNING, 2, - "SenseID : boxed device %04x on subchannel " - "0.%x.%04x\n", cdev->private->dev_id.devno, - sch->schid.ssid, sch->schid.sch_no); + CIO_MSG_EVENT(0, "SenseID : boxed device %04x on " + " subchannel 0.%x.%04x\n", + cdev->private->dev_id.devno, + sch->schid.ssid, sch->schid.sch_no); break; } cdev->private->state = state; @@ -443,9 +442,8 @@ ccw_device_done(struct ccw_device *cdev, int state) if (state == DEV_STATE_BOXED) - CIO_DEBUG(KERN_WARNING, 2, - "Boxed device %04x on subchannel %04x\n", - cdev->private->dev_id.devno, sch->schid.sch_no); + CIO_MSG_EVENT(0, "Boxed device %04x on subchannel %04x\n", + cdev->private->dev_id.devno, sch->schid.sch_no); if (cdev->private->flags.donotify) { cdev->private->flags.donotify = 0; @@ -900,7 +898,7 @@ ccw_device_w4sense(struct ccw_device *cdev, enum dev_event dev_event) /* Basic sense hasn't started. Try again. */ ccw_device_do_sense(cdev, irb); else { - CIO_MSG_EVENT(2, "Huh? 0.%x.%04x: unsolicited " + CIO_MSG_EVENT(0, "0.%x.%04x: unsolicited " "interrupt during w4sense...\n", cdev->private->dev_id.ssid, cdev->private->dev_id.devno); @@ -1169,8 +1167,10 @@ ccw_device_nop(struct ccw_device *cdev, enum dev_event dev_event) static void ccw_device_bug(struct ccw_device *cdev, enum dev_event dev_event) { - CIO_MSG_EVENT(0, "dev_jumptable[%i][%i] == NULL\n", - cdev->private->state, dev_event); + CIO_MSG_EVENT(0, "Internal state [%i][%i] not handled for device " + "0.%x.%04x\n", cdev->private->state, dev_event, + cdev->private->dev_id.ssid, + cdev->private->dev_id.devno); BUG(); } diff --git a/drivers/s390/cio/device_id.c b/drivers/s390/cio/device_id.c index dc4d87f77f6c4bbb45dd1e15fe9582c5cf3f474f..cba7020517edbaa300e5fd2cfc3b80d52380aea3 100644 --- a/drivers/s390/cio/device_id.c +++ b/drivers/s390/cio/device_id.c @@ -214,7 +214,7 @@ ccw_device_check_sense_id(struct ccw_device *cdev) * sense id information. So, for intervention required, * we use the "whack it until it talks" strategy... */ - CIO_MSG_EVENT(2, "SenseID : device %04x on Subchannel " + CIO_MSG_EVENT(0, "SenseID : device %04x on Subchannel " "0.%x.%04x reports cmd reject\n", cdev->private->dev_id.devno, sch->schid.ssid, sch->schid.sch_no); @@ -239,7 +239,7 @@ ccw_device_check_sense_id(struct ccw_device *cdev) lpm = to_io_private(sch)->orb.lpm; if ((lpm & sch->schib.pmcw.pim & sch->schib.pmcw.pam) != 0) - CIO_MSG_EVENT(2, "SenseID : path %02X for device %04x " + CIO_MSG_EVENT(4, "SenseID : path %02X for device %04x " "on subchannel 0.%x.%04x is " "'not operational'\n", lpm, cdev->private->dev_id.devno, diff --git a/drivers/s390/cio/device_pgid.c b/drivers/s390/cio/device_pgid.c index c52449a1f9fce93f2af14456c88cb7dc7e390d96..5cf7be008e981232742c7d57420e0359dd33e977 100644 --- a/drivers/s390/cio/device_pgid.c +++ b/drivers/s390/cio/device_pgid.c @@ -79,7 +79,7 @@ __ccw_device_sense_pgid_start(struct ccw_device *cdev) /* ret is 0, -EBUSY, -EACCES or -ENODEV */ if (ret != -EACCES) return ret; - CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel " + CIO_MSG_EVENT(3, "SNID - Device %04x on Subchannel " "0.%x.%04x, lpm %02X, became 'not " "operational'\n", cdev->private->dev_id.devno, @@ -159,7 +159,7 @@ __ccw_device_check_sense_pgid(struct ccw_device *cdev) u8 lpm; lpm = to_io_private(sch)->orb.lpm; - CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel 0.%x.%04x," + CIO_MSG_EVENT(3, "SNID - Device %04x on Subchannel 0.%x.%04x," " lpm %02X, became 'not operational'\n", cdev->private->dev_id.devno, sch->schid.ssid, sch->schid.sch_no, lpm); @@ -243,16 +243,10 @@ __ccw_device_do_pgid(struct ccw_device *cdev, __u8 func) /* Setup sense path group id channel program. */ cdev->private->pgid[0].inf.fc = func; ccw = cdev->private->iccws; - if (!cdev->private->flags.pgid_single) { - cdev->private->pgid[0].inf.fc |= SPID_FUNC_MULTI_PATH; - ccw->cmd_code = CCW_CMD_SUSPEND_RECONN; - ccw->cda = 0; - ccw->count = 0; - ccw->flags = CCW_FLAG_SLI | CCW_FLAG_CC; - ccw++; - } else + if (cdev->private->flags.pgid_single) cdev->private->pgid[0].inf.fc |= SPID_FUNC_SINGLE_PATH; - + else + cdev->private->pgid[0].inf.fc |= SPID_FUNC_MULTI_PATH; ccw->cmd_code = CCW_CMD_SET_PGID; ccw->cda = (__u32) __pa (&cdev->private->pgid[0]); ccw->count = sizeof (struct pgid); @@ -275,7 +269,7 @@ __ccw_device_do_pgid(struct ccw_device *cdev, __u8 func) return ret; } /* PGID command failed on this path. */ - CIO_MSG_EVENT(2, "SPID - Device %04x on Subchannel " + CIO_MSG_EVENT(3, "SPID - Device %04x on Subchannel " "0.%x.%04x, lpm %02X, became 'not operational'\n", cdev->private->dev_id.devno, sch->schid.ssid, sch->schid.sch_no, cdev->private->imask); @@ -317,7 +311,7 @@ static int __ccw_device_do_nop(struct ccw_device *cdev) return ret; } /* nop command failed on this path. */ - CIO_MSG_EVENT(2, "NOP - Device %04x on Subchannel " + CIO_MSG_EVENT(3, "NOP - Device %04x on Subchannel " "0.%x.%04x, lpm %02X, became 'not operational'\n", cdev->private->dev_id.devno, sch->schid.ssid, sch->schid.sch_no, cdev->private->imask); @@ -362,7 +356,7 @@ __ccw_device_check_pgid(struct ccw_device *cdev) return -EAGAIN; } if (irb->scsw.cc == 3) { - CIO_MSG_EVENT(2, "SPID - Device %04x on Subchannel 0.%x.%04x," + CIO_MSG_EVENT(3, "SPID - Device %04x on Subchannel 0.%x.%04x," " lpm %02X, became 'not operational'\n", cdev->private->dev_id.devno, sch->schid.ssid, sch->schid.sch_no, cdev->private->imask); @@ -391,7 +385,7 @@ static int __ccw_device_check_nop(struct ccw_device *cdev) return -ETIME; } if (irb->scsw.cc == 3) { - CIO_MSG_EVENT(2, "NOP - Device %04x on Subchannel 0.%x.%04x," + CIO_MSG_EVENT(3, "NOP - Device %04x on Subchannel 0.%x.%04x," " lpm %02X, became 'not operational'\n", cdev->private->dev_id.devno, sch->schid.ssid, sch->schid.sch_no, cdev->private->imask); diff --git a/drivers/s390/kvm/kvm_virtio.c b/drivers/s390/kvm/kvm_virtio.c index 47a7e6200b262f660c4471cc8c23bfccd32203c2..9f55ce6f3c7817380f87a429ae74d0f071fa3047 100644 --- a/drivers/s390/kvm/kvm_virtio.c +++ b/drivers/s390/kvm/kvm_virtio.c @@ -78,27 +78,32 @@ static unsigned desc_size(const struct kvm_device_desc *desc) + desc->config_len; } -/* - * This tests (and acknowleges) a feature bit. - */ -static bool kvm_feature(struct virtio_device *vdev, unsigned fbit) +/* This gets the device's feature bits. */ +static u32 kvm_get_features(struct virtio_device *vdev) { + unsigned int i; + u32 features = 0; struct kvm_device_desc *desc = to_kvmdev(vdev)->desc; - u8 *features; + u8 *in_features = kvm_vq_features(desc); - if (fbit / 8 > desc->feature_len) - return false; + for (i = 0; i < min(desc->feature_len * 8, 32); i++) + if (in_features[i / 8] & (1 << (i % 8))) + features |= (1 << i); + return features; +} - features = kvm_vq_features(desc); - if (!(features[fbit / 8] & (1 << (fbit % 8)))) - return false; +static void kvm_set_features(struct virtio_device *vdev, u32 features) +{ + unsigned int i; + struct kvm_device_desc *desc = to_kvmdev(vdev)->desc; + /* Second half of bitmap is features we accept. */ + u8 *out_features = kvm_vq_features(desc) + desc->feature_len; - /* - * We set the matching bit in the other half of the bitmap to tell the - * Host we want to use this feature. - */ - features[desc->feature_len + fbit / 8] |= (1 << (fbit % 8)); - return true; + memset(out_features, 0, desc->feature_len); + for (i = 0; i < min(desc->feature_len * 8, 32); i++) { + if (features & (1 << i)) + out_features[i / 8] |= (1 << (i % 8)); + } } /* @@ -221,7 +226,8 @@ static void kvm_del_vq(struct virtqueue *vq) * The config ops structure as defined by virtio config */ static struct virtio_config_ops kvm_vq_configspace_ops = { - .feature = kvm_feature, + .get_features = kvm_get_features, + .set_features = kvm_set_features, .get = kvm_get, .set = kvm_set, .get_status = kvm_get_status, diff --git a/drivers/s390/s390mach.c b/drivers/s390/s390mach.c index 4d4b54277c43d2554e81f4cf5207ed8e3107995b..5080f343ad7482ebac5addfc19768ac5adfeeae2 100644 --- a/drivers/s390/s390mach.c +++ b/drivers/s390/s390mach.c @@ -48,10 +48,11 @@ s390_collect_crw_info(void *param) int ccode; struct semaphore *sem; unsigned int chain; + int ignore; sem = (struct semaphore *)param; repeat: - down_interruptible(sem); + ignore = down_interruptible(sem); chain = 0; while (1) { if (unlikely(chain > 1)) { diff --git a/drivers/sbus/char/bpp.c b/drivers/sbus/char/bpp.c index 4fab0c23814c90dda8bf55b85e6242c6dbc07d96..b87037ec9805502a52cd4655f6d40a96847d3b66 100644 --- a/drivers/sbus/char/bpp.c +++ b/drivers/sbus/char/bpp.c @@ -41,7 +41,7 @@ #define BPP_DELAY 100 static const unsigned BPP_MAJOR = LP_MAJOR; -static const char* dev_name = "bpp"; +static const char *bpp_dev_name = "bpp"; /* When switching from compatibility to a mode where I can read, try the following mode first. */ diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c index f5215fd4b73d30bac4603dd7deab26adccb11971..1dca1775f4b14554213fc366b89433e78f2af11c 100644 --- a/drivers/scsi/aha152x.c +++ b/drivers/scsi/aha152x.c @@ -3830,7 +3830,7 @@ static int __init aha152x_init(void) iounmap(p); } if (!ok && setup_count == 0) - return 0; + return -ENODEV; printk(KERN_INFO "aha152x: BIOS test: passed, "); #else @@ -3909,14 +3909,14 @@ static int __init aha152x_init(void) #endif } - return 1; + return 0; } static void __exit aha152x_exit(void) { - struct aha152x_hostdata *hd; + struct aha152x_hostdata *hd, *tmp; - list_for_each_entry(hd, &aha152x_host_list, host_list) { + list_for_each_entry_safe(hd, tmp, &aha152x_host_list, host_list) { struct Scsi_Host *shost = container_of((void *)hd, struct Scsi_Host, hostdata); aha152x_release(shost); diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c index 0fb5bf4c43acd4500b93bc51b1e010c17e3a70d7..8508816f303d08144fb8377da3c5c780ae7c5a9e 100644 --- a/drivers/scsi/dpt_i2o.c +++ b/drivers/scsi/dpt_i2o.c @@ -1967,45 +1967,6 @@ cleanup: return rcode; } - -/* - * This routine returns information about the system. This does not effect - * any logic and if the info is wrong - it doesn't matter. - */ - -/* Get all the info we can not get from kernel services */ -static int adpt_system_info(void __user *buffer) -{ - sysInfo_S si; - - memset(&si, 0, sizeof(si)); - - si.osType = OS_LINUX; - si.osMajorVersion = 0; - si.osMinorVersion = 0; - si.osRevision = 0; - si.busType = SI_PCI_BUS; - si.processorFamily = DPTI_sig.dsProcessorFamily; - -#if defined __i386__ - adpt_i386_info(&si); -#elif defined (__ia64__) - adpt_ia64_info(&si); -#elif defined(__sparc__) - adpt_sparc_info(&si); -#elif defined (__alpha__) - adpt_alpha_info(&si); -#else - si.processorType = 0xff ; -#endif - if(copy_to_user(buffer, &si, sizeof(si))){ - printk(KERN_WARNING"dpti: Could not copy buffer TO user\n"); - return -EFAULT; - } - - return 0; -} - #if defined __ia64__ static void adpt_ia64_info(sysInfo_S* si) { @@ -2016,7 +1977,6 @@ static void adpt_ia64_info(sysInfo_S* si) } #endif - #if defined __sparc__ static void adpt_sparc_info(sysInfo_S* si) { @@ -2026,7 +1986,6 @@ static void adpt_sparc_info(sysInfo_S* si) si->processorType = PROC_ULTRASPARC; } #endif - #if defined __alpha__ static void adpt_alpha_info(sysInfo_S* si) { @@ -2038,7 +1997,6 @@ static void adpt_alpha_info(sysInfo_S* si) #endif #if defined __i386__ - static void adpt_i386_info(sysInfo_S* si) { // This is all the info we need for now @@ -2059,9 +2017,45 @@ static void adpt_i386_info(sysInfo_S* si) break; } } +#endif + +/* + * This routine returns information about the system. This does not effect + * any logic and if the info is wrong - it doesn't matter. + */ +/* Get all the info we can not get from kernel services */ +static int adpt_system_info(void __user *buffer) +{ + sysInfo_S si; + + memset(&si, 0, sizeof(si)); + + si.osType = OS_LINUX; + si.osMajorVersion = 0; + si.osMinorVersion = 0; + si.osRevision = 0; + si.busType = SI_PCI_BUS; + si.processorFamily = DPTI_sig.dsProcessorFamily; + +#if defined __i386__ + adpt_i386_info(&si); +#elif defined (__ia64__) + adpt_ia64_info(&si); +#elif defined(__sparc__) + adpt_sparc_info(&si); +#elif defined (__alpha__) + adpt_alpha_info(&si); +#else + si.processorType = 0xff ; #endif + if (copy_to_user(buffer, &si, sizeof(si))){ + printk(KERN_WARNING"dpti: Could not copy buffer TO user\n"); + return -EFAULT; + } + return 0; +} static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) diff --git a/drivers/scsi/dpti.h b/drivers/scsi/dpti.h index 924cd5a51676a9b7212016722d6d319b60817608..337746d460438417281d25c3aa9aec863f3e002d 100644 --- a/drivers/scsi/dpti.h +++ b/drivers/scsi/dpti.h @@ -316,19 +316,6 @@ static int adpt_close(struct inode *inode, struct file *file); static void adpt_delay(int millisec); #endif -#if defined __ia64__ -static void adpt_ia64_info(sysInfo_S* si); -#endif -#if defined __sparc__ -static void adpt_sparc_info(sysInfo_S* si); -#endif -#if defined __alpha__ -static void adpt_sparc_info(sysInfo_S* si); -#endif -#if defined __i386__ -static void adpt_i386_info(sysInfo_S* si); -#endif - #define PRINT_BUFFER_SIZE 512 #define HBA_FLAGS_DBG_FLAGS_MASK 0xffff0000 // Mask for debug flags diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index 8e2e964af6689c31c3c7c7c7d85a7a7bd477fe74..46771d4c81bdcd8abeb8bad9b81bdd6430f5dfff 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -550,7 +550,6 @@ static int __init gdth_search_isa(ulong32 bios_adr) #endif /* CONFIG_ISA */ #ifdef CONFIG_PCI -static bool gdth_pci_registered; static bool gdth_search_vortex(ushort device) { @@ -3724,6 +3723,8 @@ static void gdth_log_event(gdth_evt_data *dvr, char *buffer) } #ifdef GDTH_STATISTICS +static unchar gdth_timer_running; + static void gdth_timeout(ulong data) { ulong32 i; @@ -3731,7 +3732,10 @@ static void gdth_timeout(ulong data) gdth_ha_str *ha; ulong flags; - BUG_ON(list_empty(&gdth_instances)); + if(unlikely(list_empty(&gdth_instances))) { + gdth_timer_running = 0; + return; + } ha = list_first_entry(&gdth_instances, gdth_ha_str, list); spin_lock_irqsave(&ha->smp_lock, flags); @@ -3751,6 +3755,22 @@ static void gdth_timeout(ulong data) add_timer(&gdth_timer); spin_unlock_irqrestore(&ha->smp_lock, flags); } + +static void gdth_timer_init(void) +{ + if (gdth_timer_running) + return; + gdth_timer_running = 1; + TRACE2(("gdth_detect(): Initializing timer !\n")); + gdth_timer.expires = jiffies + HZ; + gdth_timer.data = 0L; + gdth_timer.function = gdth_timeout; + add_timer(&gdth_timer); +} +#else +static inline void gdth_timer_init(void) +{ +} #endif static void __init internal_setup(char *str,int *ints) @@ -4735,6 +4755,7 @@ static int __init gdth_isa_probe_one(ulong32 isa_bios) if (error) goto out_free_coal_stat; list_add_tail(&ha->list, &gdth_instances); + gdth_timer_init(); scsi_scan_host(shp); @@ -4865,6 +4886,7 @@ static int __init gdth_eisa_probe_one(ushort eisa_slot) if (error) goto out_free_coal_stat; list_add_tail(&ha->list, &gdth_instances); + gdth_timer_init(); scsi_scan_host(shp); @@ -5011,6 +5033,7 @@ static int gdth_pci_probe_one(gdth_pci_str *pcistr, list_add_tail(&ha->list, &gdth_instances); pci_set_drvdata(ha->pdev, ha); + gdth_timer_init(); scsi_scan_host(shp); @@ -5110,6 +5133,7 @@ static int __init gdth_init(void) /* initializations */ gdth_polling = TRUE; gdth_clear_events(); + init_timer(&gdth_timer); /* As default we do not probe for EISA or ISA controllers */ if (probe_eisa_isa) { @@ -5132,23 +5156,17 @@ static int __init gdth_init(void) #ifdef CONFIG_PCI /* scanning for PCI controllers */ - if (pci_register_driver(&gdth_pci_driver) == 0) - gdth_pci_registered = true; + if (pci_register_driver(&gdth_pci_driver)) { + gdth_ha_str *ha; + + list_for_each_entry(ha, &gdth_instances, list) + gdth_remove_one(ha); + return -ENODEV; + } #endif /* CONFIG_PCI */ TRACE2(("gdth_detect() %d controller detected\n", gdth_ctr_count)); - if (list_empty(&gdth_instances)) - return -ENODEV; - -#ifdef GDTH_STATISTICS - TRACE2(("gdth_detect(): Initializing timer !\n")); - init_timer(&gdth_timer); - gdth_timer.expires = jiffies + HZ; - gdth_timer.data = 0L; - gdth_timer.function = gdth_timeout; - add_timer(&gdth_timer); -#endif major = register_chrdev(0,"gdth", &gdth_fops); register_reboot_notifier(&gdth_notifier); gdth_polling = FALSE; @@ -5167,8 +5185,7 @@ static void __exit gdth_exit(void) #endif #ifdef CONFIG_PCI - if (gdth_pci_registered) - pci_unregister_driver(&gdth_pci_driver); + pci_unregister_driver(&gdth_pci_driver); #endif list_for_each_entry(ha, &gdth_instances, list) diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 010c1b9b178cb5ae5ea0e9f54e3a631c210f0a7e..b43bf1d60dac8a5499922f8a66da15b3c26626d2 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -730,7 +730,9 @@ static int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, if (iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen)) rc = ISCSI_ERR_CONN_FAILED; - } + } else + mod_timer(&conn->transport_timer, + jiffies + conn->recv_timeout); iscsi_free_mgmt_task(conn, mtask); break; default: @@ -1453,19 +1455,20 @@ static void iscsi_check_transport_timeouts(unsigned long data) { struct iscsi_conn *conn = (struct iscsi_conn *)data; struct iscsi_session *session = conn->session; - unsigned long timeout, next_timeout = 0, last_recv; + unsigned long recv_timeout, next_timeout = 0, last_recv; spin_lock(&session->lock); if (session->state != ISCSI_STATE_LOGGED_IN) goto done; - timeout = conn->recv_timeout; - if (!timeout) + recv_timeout = conn->recv_timeout; + if (!recv_timeout) goto done; - timeout *= HZ; + recv_timeout *= HZ; last_recv = conn->last_recv; - if (time_before_eq(last_recv + timeout + (conn->ping_timeout * HZ), + if (conn->ping_mtask && + time_before_eq(conn->last_ping + (conn->ping_timeout * HZ), jiffies)) { iscsi_conn_printk(KERN_ERR, conn, "ping timeout of %d secs " "expired, last rx %lu, last ping %lu, " @@ -1476,15 +1479,13 @@ static void iscsi_check_transport_timeouts(unsigned long data) return; } - if (time_before_eq(last_recv + timeout, jiffies)) { - if (time_before_eq(conn->last_ping, last_recv)) { - /* send a ping to try to provoke some traffic */ - debug_scsi("Sending nopout as ping on conn %p\n", conn); - iscsi_send_nopout(conn, NULL); - } - next_timeout = last_recv + timeout + (conn->ping_timeout * HZ); + if (time_before_eq(last_recv + recv_timeout, jiffies)) { + /* send a ping to try to provoke some traffic */ + debug_scsi("Sending nopout as ping on conn %p\n", conn); + iscsi_send_nopout(conn, NULL); + next_timeout = conn->last_ping + (conn->ping_timeout * HZ); } else - next_timeout = last_recv + timeout; + next_timeout = last_recv + recv_timeout; debug_scsi("Setting next tmo %lu\n", next_timeout); mod_timer(&conn->transport_timer, next_timeout); diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c index fa060932d2b4f632c486d59e4d436f79b1c349bb..51e2f299dbbb11e60b0995ac4e5cca14c5a2c634 100644 --- a/drivers/scsi/qla1280.c +++ b/drivers/scsi/qla1280.c @@ -2007,7 +2007,7 @@ qla1280_set_defaults(struct scsi_qla_host *ha) nv->bus[bus].config_2.req_ack_active_negation = 1; nv->bus[bus].config_2.data_line_active_negation = 1; nv->bus[bus].selection_timeout = 250; - nv->bus[bus].max_queue_depth = 256; + nv->bus[bus].max_queue_depth = 32; if (IS_ISP1040(ha)) { nv->bus[bus].bus_reset_delay = 3; @@ -2051,7 +2051,7 @@ qla1280_config_target(struct scsi_qla_host *ha, int bus, int target) status = qla1280_mailbox_command(ha, 0x0f, mb); /* Save Tag queuing enable flag. */ - flag = (BIT_0 << target) & mb[0]; + flag = (BIT_0 << target); if (nv->bus[bus].target[target].parameter.tag_queuing) ha->bus_settings[bus].qtag_enables |= flag; diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index a1ca9b7bf2d5862b7466fbdcee4f5099b882ac76..1400ea6a249192e9a322a5c006595b6ee250e783 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -43,6 +43,7 @@ #include #include +#include #include "8250.h" @@ -92,8 +93,6 @@ static unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS; */ #define CONFIG_HUB6 1 -#include - /* * SERIAL_PORT_DFNS tells us about built-in ports that have no * standard enumeration mechanism. Platforms that can find all @@ -1548,6 +1547,8 @@ static int serial_link_irq_chain(struct uart_8250_port *up) i->head = &up->list; spin_unlock_irq(&i->lock); + irq_flags |= SERIAL_EXTRA_IRQ_FLAGS; + ret = request_irq(up->port.irq, serial8250_interrupt, irq_flags, "serial", i); if (ret < 0) diff --git a/drivers/serial/8250.h b/drivers/serial/8250.h index 91bd28f2bb473c637c8f19b719b9d5d8a84875a3..a10a40cc0d9e607cd972746284af7e32cc885976 100644 --- a/drivers/serial/8250.h +++ b/drivers/serial/8250.h @@ -78,3 +78,8 @@ struct serial8250_config { #else #define ALPHA_KLUDGE_MCR 0 #endif + +#ifndef SERIAL_EXTRA_IRQ_FLAGS +#define SERIAL_EXTRA_IRQ_FLAGS 0 +#endif + diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 36acbcca2d4893c4aa3178e0d7e426cff2029f90..9bc42763623c8de5cf5d48eef56f0f018568fee2 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -976,11 +976,15 @@ config SERIAL_68328_RTS_CTS depends on SERIAL_68328 config SERIAL_COLDFIRE - bool "ColdFire serial support" + bool "ColdFire serial support (DEPRECATED)" depends on COLDFIRE help This driver supports the built-in serial ports of the Motorola ColdFire family of CPUs. + This driver is deprecated because it supports only the old interface + for serial drivers and features like magic keys are not working. + Please switch to the new style driver because this driver will be + removed soon. config SERIAL_MCF bool "Coldfire serial support (new style driver)" @@ -1357,7 +1361,7 @@ config SERIAL_SC26XX_CONSOLE config SERIAL_BFIN_SPORT tristate "Blackfin SPORT emulate UART (EXPERIMENTAL)" - depends on BFIN && EXPERIMENTAL + depends on BLACKFIN && EXPERIMENTAL select SERIAL_CORE help Enble support SPORT emulate UART on Blackfin series. diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c index 8a2f6a1baa74d5b09b31666dd46be9b7bca746c2..d6b4ead693b7b08f798bf12e9e6f09e81287af77 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/serial/bfin_5xx.c @@ -65,9 +65,6 @@ static void bfin_serial_stop_tx(struct uart_port *port) { struct bfin_serial_port *uart = (struct bfin_serial_port *)port; struct circ_buf *xmit = &uart->port.info->xmit; -#if !defined(CONFIG_BF54x) && !defined(CONFIG_SERIAL_BFIN_DMA) - unsigned short ier; -#endif while (!(UART_GET_LSR(uart) & TEMT)) cpu_relax(); @@ -82,12 +79,8 @@ static void bfin_serial_stop_tx(struct uart_port *port) #ifdef CONFIG_BF54x /* Clear TFI bit */ UART_PUT_LSR(uart, TFI); - UART_CLEAR_IER(uart, ETBEI); -#else - ier = UART_GET_IER(uart); - ier &= ~ETBEI; - UART_PUT_IER(uart, ier); #endif + UART_CLEAR_IER(uart, ETBEI); #endif } @@ -102,14 +95,7 @@ static void bfin_serial_start_tx(struct uart_port *port) if (uart->tx_done) bfin_serial_dma_tx_chars(uart); #else -#ifdef CONFIG_BF54x UART_SET_IER(uart, ETBEI); -#else - unsigned short ier; - ier = UART_GET_IER(uart); - ier |= ETBEI; - UART_PUT_IER(uart, ier); -#endif bfin_serial_tx_chars(uart); #endif } @@ -120,21 +106,10 @@ static void bfin_serial_start_tx(struct uart_port *port) static void bfin_serial_stop_rx(struct uart_port *port) { struct bfin_serial_port *uart = (struct bfin_serial_port *)port; -#ifdef CONFIG_KGDB_UART - if (uart->port.line != CONFIG_KGDB_UART_PORT) { +#ifdef CONFIG_KGDB_UART + if (uart->port.line != CONFIG_KGDB_UART_PORT) #endif -#ifdef CONFIG_BF54x UART_CLEAR_IER(uart, ERBFI); -#else - unsigned short ier; - - ier = UART_GET_IER(uart); - ier &= ~ERBFI; - UART_PUT_IER(uart, ier); -#endif -#ifdef CONFIG_KGDB_UART - } -#endif } /* @@ -161,10 +136,7 @@ void kgdb_put_debug_char(int chr) SSYNC(); } -#ifndef CONFIG_BF54x - UART_PUT_LCR(uart, UART_GET_LCR(uart)&(~DLAB)); - SSYNC(); -#endif + UART_CLEAR_DLAB(uart); UART_PUT_CHAR(uart, (unsigned char)chr); SSYNC(); } @@ -183,10 +155,7 @@ int kgdb_get_debug_char(void) while(!(UART_GET_LSR(uart) & DR)) { SSYNC(); } -#ifndef CONFIG_BF54x - UART_PUT_LCR(uart, UART_GET_LCR(uart)&(~DLAB)); - SSYNC(); -#endif + UART_CLEAR_DLAB(uart); chr = UART_GET_CHAR(uart); SSYNC(); @@ -208,9 +177,6 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart) struct tty_struct *tty = uart->port.info->tty; unsigned int status, ch, flg; static struct timeval anomaly_start = { .tv_sec = 0 }; -#ifdef CONFIG_KGDB_UART - struct pt_regs *regs = get_irq_regs(); -#endif status = UART_GET_LSR(uart); UART_CLEAR_LSR(uart); @@ -220,6 +186,7 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart) #ifdef CONFIG_KGDB_UART if (uart->port.line == CONFIG_KGDB_UART_PORT) { + struct pt_regs *regs = get_irq_regs(); if (uart->port.cons->index == CONFIG_KGDB_UART_PORT && ch == 0x1) { /* Ctrl + A */ kgdb_breakkey_pressed(regs); return; @@ -391,7 +358,6 @@ static void bfin_serial_do_work(struct work_struct *work) static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart) { struct circ_buf *xmit = &uart->port.info->xmit; - unsigned short ier; uart->tx_done = 0; @@ -429,13 +395,7 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart) set_dma_x_modify(uart->tx_dma_channel, 1); enable_dma(uart->tx_dma_channel); -#ifdef CONFIG_BF54x UART_SET_IER(uart, ETBEI); -#else - ier = UART_GET_IER(uart); - ier |= ETBEI; - UART_PUT_IER(uart, ier); -#endif } static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart) @@ -513,19 +473,12 @@ static irqreturn_t bfin_serial_dma_tx_int(int irq, void *dev_id) { struct bfin_serial_port *uart = dev_id; struct circ_buf *xmit = &uart->port.info->xmit; - unsigned short ier; spin_lock(&uart->port.lock); if (!(get_dma_curr_irqstat(uart->tx_dma_channel)&DMA_RUN)) { disable_dma(uart->tx_dma_channel); clear_dma_irqstat(uart->tx_dma_channel); -#ifdef CONFIG_BF54x UART_CLEAR_IER(uart, ETBEI); -#else - ier = UART_GET_IER(uart); - ier &= ~ETBEI; - UART_PUT_IER(uart, ier); -#endif xmit->tail = (xmit->tail + uart->tx_count) & (UART_XMIT_SIZE - 1); uart->port.icount.tx += uart->tx_count; @@ -701,7 +654,6 @@ static int bfin_serial_startup(struct uart_port *port) # endif } - if (request_irq (uart->port.irq+1, bfin_serial_tx_int, IRQF_DISABLED, "BFIN_UART_TX", uart)) { @@ -710,11 +662,7 @@ static int bfin_serial_startup(struct uart_port *port) return -EBUSY; } #endif -#ifdef CONFIG_BF54x UART_SET_IER(uart, ERBFI); -#else - UART_PUT_IER(uart, UART_GET_IER(uart) | ERBFI); -#endif return 0; } @@ -810,26 +758,15 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios, UART_PUT_IER(uart, 0); #endif -#ifndef CONFIG_BF54x /* Set DLAB in LCR to Access DLL and DLH */ - val = UART_GET_LCR(uart); - val |= DLAB; - UART_PUT_LCR(uart, val); - SSYNC(); -#endif + UART_SET_DLAB(uart); UART_PUT_DLL(uart, quot & 0xFF); - SSYNC(); UART_PUT_DLH(uart, (quot >> 8) & 0xFF); SSYNC(); -#ifndef CONFIG_BF54x /* Clear DLAB in LCR to Access THR RBR IER */ - val = UART_GET_LCR(uart); - val &= ~DLAB; - UART_PUT_LCR(uart, val); - SSYNC(); -#endif + UART_CLEAR_DLAB(uart); UART_PUT_LCR(uart, lcr); @@ -992,8 +929,7 @@ bfin_serial_console_get_options(struct bfin_serial_port *uart, int *baud, status = UART_GET_IER(uart) & (ERBFI | ETBEI); if (status == (ERBFI | ETBEI)) { /* ok, the port was enabled */ - unsigned short lcr, val; - unsigned short dlh, dll; + u16 lcr, dlh, dll; lcr = UART_GET_LCR(uart); @@ -1010,22 +946,14 @@ bfin_serial_console_get_options(struct bfin_serial_port *uart, int *baud, case 2: *bits = 7; break; case 3: *bits = 8; break; } -#ifndef CONFIG_BF54x /* Set DLAB in LCR to Access DLL and DLH */ - val = UART_GET_LCR(uart); - val |= DLAB; - UART_PUT_LCR(uart, val); -#endif + UART_SET_DLAB(uart); dll = UART_GET_DLL(uart); dlh = UART_GET_DLH(uart); -#ifndef CONFIG_BF54x /* Clear DLAB in LCR to Access THR RBR IER */ - val = UART_GET_LCR(uart); - val &= ~DLAB; - UART_PUT_LCR(uart, val); -#endif + UART_CLEAR_DLAB(uart); *baud = get_sclk() / (16*(dll | dlh << 8)); } @@ -1290,11 +1218,7 @@ static int __init bfin_serial_init(void) request_irq(uart->port.irq, bfin_serial_rx_int, IRQF_DISABLED, "BFIN_UART_RX", uart); pr_info("Request irq for kgdb uart port\n"); -#ifdef CONFIG_BF54x UART_SET_IER(uart, ERBFI); -#else - UART_PUT_IER(uart, UART_GET_IER(uart) | ERBFI); -#endif SSYNC(); t.c_cflag = CS8|B57600; t.c_iflag = 0; diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c index f9fa237aa9496d7cdf88d4cd0589d8b8391ae351..3e0366eab412878258f993f16a0fc1804c401e8c 100644 --- a/drivers/serial/crisv10.c +++ b/drivers/serial/crisv10.c @@ -3808,7 +3808,7 @@ rs_close(struct tty_struct *tty, struct file * filp) shutdown(info); rs_flush_buffer(tty); - tty_ldisc_flush_buffer(tty); + tty_ldisc_flush(tty); tty->closing = 0; info->event = 0; info->tty = 0; diff --git a/drivers/serial/mcfserial.c b/drivers/serial/mcfserial.c index 43af40d59b8af44717621150e13194afd85efdff..56007cc8a9b31c24cd75390a932c4d426efec9f8 100644 --- a/drivers/serial/mcfserial.c +++ b/drivers/serial/mcfserial.c @@ -1,3 +1,4 @@ +#warning This driver is deprecated. Check Kconfig for details. /* * mcfserial.c -- serial driver for ColdFire internal UARTS. * diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index 1e2b9d826f69a5db2756e8eb477f2249587122e4..eab032733790d5524ac9f14e8596c1a5a62e462c 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c @@ -556,7 +556,7 @@ static int uart_chars_in_buffer(struct tty_struct *tty) static void uart_flush_buffer(struct tty_struct *tty) { struct uart_state *state = tty->driver_data; - struct uart_port *port = state->port; + struct uart_port *port; unsigned long flags; /* @@ -568,6 +568,7 @@ static void uart_flush_buffer(struct tty_struct *tty) return; } + port = state->port; pr_debug("uart_flush_buffer(%d) called\n", tty->index); spin_lock_irqsave(&port->lock, flags); diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 969106187718d909e0aacb9478477296d43e04ae..ce6ee92b3a1b32fa001dc79c3716ea797288d57b 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -42,14 +42,12 @@ #include #include #include - -#ifdef CONFIG_CPU_FREQ #include #include -#endif - -#if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64) +#include #include + +#ifdef CONFIG_SUPERH #include #include #include @@ -80,7 +78,7 @@ struct sci_port { struct timer_list break_timer; int break_flag; -#if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64) +#ifdef CONFIG_SUPERH /* Port clock */ struct clk *clk; #endif @@ -186,15 +184,15 @@ static void put_string(struct sci_port *sci_port, const char *buffer, int count) int h, l; c = *p++; - h = highhex(c); - l = lowhex(c); + h = hex_asc_hi(c); + l = hex_asc_lo(c); put_char(port, h); put_char(port, l); checksum += h + l; } put_char(port, '#'); - put_char(port, highhex(checksum)); - put_char(port, lowhex(checksum)); + put_char(port, hex_asc_hi(checksum)); + put_char(port, hex_asc_lo(checksum)); } while (get_char(port) != '+'); } else #endif /* CONFIG_SH_STANDARD_BIOS || CONFIG_SH_KGDB */ @@ -365,21 +363,19 @@ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) { unsigned int fcr_val = 0; + unsigned short data; - if (cflag & CRTSCTS) { - fcr_val |= SCFCR_MCE; - - ctrl_outw(0x0000, PORT_PSCR); - } else { - unsigned short data; - - data = ctrl_inw(PORT_PSCR); - data &= 0x033f; - data |= 0x0400; - ctrl_outw(data, PORT_PSCR); + if (port->mapbase == 0xffe00000) { + data = ctrl_inw(PSCR); + data &= ~0x03cf; + if (cflag & CRTSCTS) + fcr_val |= SCFCR_MCE; + else + data |= 0x0340; - ctrl_outw(ctrl_inw(SCSPTR0) & 0x17, SCSPTR0); + ctrl_outw(data, PSCR); } + /* SCIF1 and SCIF2 should be setup by board code */ sci_out(port, SCFCR, fcr_val); } diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h index fa8700a968fc4be01018a1a916e0660fed6e6530..eb84833233fd98e690a1f08831b6cacf42fe2289 100644 --- a/drivers/serial/sh-sci.h +++ b/drivers/serial/sh-sci.h @@ -76,12 +76,13 @@ # define SCSCR_INIT(port) 0x32 /* TIE=0,RIE=0,TE=1,RE=1,REIE=0,CKE=1 */ # define SCIF_ONLY #elif defined(CONFIG_CPU_SUBTYPE_SH7722) -# define SCPDR0 0xA405013E /* 16 bit SCIF0 PSDR */ -# define SCSPTR0 SCPDR0 +# define PADR 0xA4050120 +# define PSDR 0xA405013e +# define PWDR 0xA4050166 +# define PSCR 0xA405011E # define SCIF_ORER 0x0001 /* overrun error bit */ # define SCSCR_INIT(port) 0x0038 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ # define SCIF_ONLY -# define PORT_PSCR 0xA405011E #elif defined(CONFIG_CPU_SUBTYPE_SH7366) # define SCPDR0 0xA405013E /* 16 bit SCIF0 PSDR */ # define SCSPTR0 SCPDR0 @@ -320,7 +321,7 @@ unsigned int addr = port->mapbase + (offset); \ if ((size) == 8) { \ ctrl_outb(value, addr); \ - } else { \ + } else if ((size) == 16) { \ ctrl_outw(value, addr); \ } @@ -451,7 +452,11 @@ SCIF_FNS(SCSPTR, 0, 0, 0x24, 16) SCIF_FNS(SCLSR, 0, 0, 0x28, 16) #else SCIF_FNS(SCFDR, 0x0e, 16, 0x1C, 16) +#if defined(CONFIG_CPU_SUBTYPE_SH7722) +SCIF_FNS(SCSPTR, 0, 0, 0, 0) +#else SCIF_FNS(SCSPTR, 0, 0, 0x20, 16) +#endif SCIF_FNS(SCLSR, 0, 0, 0x24, 16) #endif #endif @@ -593,13 +598,25 @@ static inline int sci_rxd_in(struct uart_port *port) return ctrl_inw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */ return 1; } -#elif defined(CONFIG_CPU_SUBTYPE_SH7722) || defined(CONFIG_CPU_SUBTYPE_SH7366) +#elif defined(CONFIG_CPU_SUBTYPE_SH7366) static inline int sci_rxd_in(struct uart_port *port) { if (port->mapbase == 0xffe00000) return ctrl_inb(SCPDR0) & 0x0001 ? 1 : 0; /* SCIF0 */ return 1; } +#elif defined(CONFIG_CPU_SUBTYPE_SH7722) +static inline int sci_rxd_in(struct uart_port *port) +{ + if (port->mapbase == 0xffe00000) + return ctrl_inb(PSDR) & 0x02 ? 1 : 0; /* SCIF0 */ + if (port->mapbase == 0xffe10000) + return ctrl_inb(PADR) & 0x40 ? 1 : 0; /* SCIF1 */ + if (port->mapbase == 0xffe20000) + return ctrl_inb(PWDR) & 0x04 ? 1 : 0; /* SCIF2 */ + + return 1; +} #elif defined(CONFIG_CPU_SUBTYPE_SH7723) static inline int sci_rxd_in(struct uart_port *port) { diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index fae9e8f3d092ce6e34afcf4e89ed5cfc73f0d39f..66ec5d8808de83c5393fd0d35fb0d6352bc24161 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -126,7 +126,6 @@ config SPI_MPC52xx_PSC config SPI_MPC83xx tristate "Freescale MPC83xx/QUICC Engine SPI controller" depends on SPI_MASTER && (PPC_83xx || QUICC_ENGINE) && EXPERIMENTAL - select SPI_BITBANG help This enables using the Freescale MPC83xx and QUICC Engine SPI controllers in master mode. diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c index 90729469d481dced3ae3e70d1c284df22e385acf..681d62325d3d2309807877ab3ddd3fb5ebf4585c 100644 --- a/drivers/spi/mpc52xx_psc_spi.c +++ b/drivers/spi/mpc52xx_psc_spi.c @@ -1,5 +1,5 @@ /* - * MPC52xx SPC in SPI mode driver. + * MPC52xx PSC in SPI mode driver. * * Maintainer: Dragos Carp * diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index 654bb58be63099235c711e909e46c13fd4831c62..0c452c46ab0778bf3e1c5458dcec0c270a979016 100644 --- a/drivers/spi/pxa2xx_spi.c +++ b/drivers/spi/pxa2xx_spi.c @@ -1567,7 +1567,7 @@ static int pxa2xx_spi_resume(struct platform_device *pdev) int status = 0; /* Enable the SSP clock */ - clk_disable(ssp->clk); + clk_enable(ssp->clk); /* Start the queue running */ status = start_queue(drv_data); diff --git a/drivers/spi/spi_mpc83xx.c b/drivers/spi/spi_mpc83xx.c index 189f706b9e4b98b517d939c8ece9ed6146121659..6832da6f7109c32a379c169b1943abd56ac6af99 100644 --- a/drivers/spi/spi_mpc83xx.c +++ b/drivers/spi/spi_mpc83xx.c @@ -49,6 +49,7 @@ struct mpc83xx_spi_reg { #define SPMODE_LEN(x) ((x) << 20) #define SPMODE_PM(x) ((x) << 16) #define SPMODE_OP (1 << 14) +#define SPMODE_CG(x) ((x) << 7) /* * Default for SPI Mode: @@ -67,10 +68,6 @@ struct mpc83xx_spi_reg { /* SPI Controller driver's private data. */ struct mpc83xx_spi { - /* bitbang has to be first */ - struct spi_bitbang bitbang; - struct completion done; - struct mpc83xx_spi_reg __iomem *base; /* rx & tx bufs from the spi_transfer */ @@ -82,7 +79,7 @@ struct mpc83xx_spi { u32(*get_tx) (struct mpc83xx_spi *); unsigned int count; - u32 irq; + int irq; unsigned nsecs; /* (clock cycle time)/2 */ @@ -94,6 +91,25 @@ struct mpc83xx_spi { void (*activate_cs) (u8 cs, u8 polarity); void (*deactivate_cs) (u8 cs, u8 polarity); + + u8 busy; + + struct workqueue_struct *workqueue; + struct work_struct work; + + struct list_head queue; + spinlock_t lock; + + struct completion done; +}; + +struct spi_mpc83xx_cs { + /* functions to deal with different sized buffers */ + void (*get_rx) (u32 rx_data, struct mpc83xx_spi *); + u32 (*get_tx) (struct mpc83xx_spi *); + u32 rx_shift; /* RX data reg shift when in qe mode */ + u32 tx_shift; /* TX data reg shift when in qe mode */ + u32 hw_mode; /* Holds HW mode register settings */ }; static inline void mpc83xx_spi_write_reg(__be32 __iomem * reg, u32 val) @@ -137,6 +153,7 @@ static void mpc83xx_spi_chipselect(struct spi_device *spi, int value) { struct mpc83xx_spi *mpc83xx_spi; u8 pol = spi->mode & SPI_CS_HIGH ? 1 : 0; + struct spi_mpc83xx_cs *cs = spi->controller_state; mpc83xx_spi = spi_master_get_devdata(spi->master); @@ -147,50 +164,26 @@ static void mpc83xx_spi_chipselect(struct spi_device *spi, int value) if (value == BITBANG_CS_ACTIVE) { u32 regval = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode); - u32 len = spi->bits_per_word; - u8 pm; - if (len == 32) - len = 0; - else - len = len - 1; - - /* mask out bits we are going to set */ - regval &= ~(SPMODE_CP_BEGIN_EDGECLK | SPMODE_CI_INACTIVEHIGH - | SPMODE_LEN(0xF) | SPMODE_DIV16 - | SPMODE_PM(0xF) | SPMODE_REV | SPMODE_LOOP); - - if (spi->mode & SPI_CPHA) - regval |= SPMODE_CP_BEGIN_EDGECLK; - if (spi->mode & SPI_CPOL) - regval |= SPMODE_CI_INACTIVEHIGH; - if (!(spi->mode & SPI_LSB_FIRST)) - regval |= SPMODE_REV; - if (spi->mode & SPI_LOOP) - regval |= SPMODE_LOOP; - - regval |= SPMODE_LEN(len); - - if ((mpc83xx_spi->spibrg / spi->max_speed_hz) >= 64) { - pm = mpc83xx_spi->spibrg / (spi->max_speed_hz * 64) - 1; - if (pm > 0x0f) { - dev_err(&spi->dev, "Requested speed is too " - "low: %d Hz. Will use %d Hz instead.\n", - spi->max_speed_hz, - mpc83xx_spi->spibrg / 1024); - pm = 0x0f; - } - regval |= SPMODE_PM(pm) | SPMODE_DIV16; - } else { - pm = mpc83xx_spi->spibrg / (spi->max_speed_hz * 4); - if (pm) - pm--; - regval |= SPMODE_PM(pm); + mpc83xx_spi->rx_shift = cs->rx_shift; + mpc83xx_spi->tx_shift = cs->tx_shift; + mpc83xx_spi->get_rx = cs->get_rx; + mpc83xx_spi->get_tx = cs->get_tx; + + if (cs->hw_mode != regval) { + unsigned long flags; + void *tmp_ptr = &mpc83xx_spi->base->mode; + + regval = cs->hw_mode; + /* Turn off IRQs locally to minimize time that + * SPI is disabled + */ + local_irq_save(flags); + /* Turn off SPI unit prior changing mode */ + mpc83xx_spi_write_reg(tmp_ptr, regval & ~SPMODE_ENABLE); + mpc83xx_spi_write_reg(tmp_ptr, regval); + local_irq_restore(flags); } - - /* Turn off SPI unit prior changing mode */ - mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, 0); - mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, regval); if (mpc83xx_spi->activate_cs) mpc83xx_spi->activate_cs(spi->chip_select, pol); } @@ -201,8 +194,9 @@ int mpc83xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) { struct mpc83xx_spi *mpc83xx_spi; u32 regval; - u8 bits_per_word; + u8 bits_per_word, pm; u32 hz; + struct spi_mpc83xx_cs *cs = spi->controller_state; mpc83xx_spi = spi_master_get_devdata(spi->master); @@ -223,61 +217,191 @@ int mpc83xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) || ((bits_per_word > 16) && (bits_per_word != 32))) return -EINVAL; - mpc83xx_spi->rx_shift = 0; - mpc83xx_spi->tx_shift = 0; + if (!hz) + hz = spi->max_speed_hz; + + cs->rx_shift = 0; + cs->tx_shift = 0; if (bits_per_word <= 8) { - mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u8; - mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u8; + cs->get_rx = mpc83xx_spi_rx_buf_u8; + cs->get_tx = mpc83xx_spi_tx_buf_u8; if (mpc83xx_spi->qe_mode) { - mpc83xx_spi->rx_shift = 16; - mpc83xx_spi->tx_shift = 24; + cs->rx_shift = 16; + cs->tx_shift = 24; } } else if (bits_per_word <= 16) { - mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u16; - mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u16; + cs->get_rx = mpc83xx_spi_rx_buf_u16; + cs->get_tx = mpc83xx_spi_tx_buf_u16; if (mpc83xx_spi->qe_mode) { - mpc83xx_spi->rx_shift = 16; - mpc83xx_spi->tx_shift = 16; + cs->rx_shift = 16; + cs->tx_shift = 16; } } else if (bits_per_word <= 32) { - mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u32; - mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u32; + cs->get_rx = mpc83xx_spi_rx_buf_u32; + cs->get_tx = mpc83xx_spi_tx_buf_u32; } else return -EINVAL; if (mpc83xx_spi->qe_mode && spi->mode & SPI_LSB_FIRST) { - mpc83xx_spi->tx_shift = 0; + cs->tx_shift = 0; if (bits_per_word <= 8) - mpc83xx_spi->rx_shift = 8; + cs->rx_shift = 8; else - mpc83xx_spi->rx_shift = 0; + cs->rx_shift = 0; } - /* nsecs = (clock period)/2 */ - if (!hz) - hz = spi->max_speed_hz; - mpc83xx_spi->nsecs = (1000000000 / 2) / hz; - if (mpc83xx_spi->nsecs > MAX_UDELAY_MS * 1000) - return -EINVAL; + mpc83xx_spi->rx_shift = cs->rx_shift; + mpc83xx_spi->tx_shift = cs->tx_shift; + mpc83xx_spi->get_rx = cs->get_rx; + mpc83xx_spi->get_tx = cs->get_tx; if (bits_per_word == 32) bits_per_word = 0; else bits_per_word = bits_per_word - 1; - regval = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode); - /* mask out bits we are going to set */ - regval &= ~(SPMODE_LEN(0xF) | SPMODE_REV); - regval |= SPMODE_LEN(bits_per_word); - if (!(spi->mode & SPI_LSB_FIRST)) - regval |= SPMODE_REV; + cs->hw_mode &= ~(SPMODE_LEN(0xF) | SPMODE_DIV16 + | SPMODE_PM(0xF)); + + cs->hw_mode |= SPMODE_LEN(bits_per_word); + + if ((mpc83xx_spi->spibrg / hz) >= 64) { + pm = mpc83xx_spi->spibrg / (hz * 64) - 1; + if (pm > 0x0f) { + dev_err(&spi->dev, "Requested speed is too " + "low: %d Hz. Will use %d Hz instead.\n", + hz, mpc83xx_spi->spibrg / 1024); + pm = 0x0f; + } + cs->hw_mode |= SPMODE_PM(pm) | SPMODE_DIV16; + } else { + pm = mpc83xx_spi->spibrg / (hz * 4); + if (pm) + pm--; + cs->hw_mode |= SPMODE_PM(pm); + } + regval = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode); + if (cs->hw_mode != regval) { + unsigned long flags; + void *tmp_ptr = &mpc83xx_spi->base->mode; + + regval = cs->hw_mode; + /* Turn off IRQs locally to minimize time + * that SPI is disabled + */ + local_irq_save(flags); + /* Turn off SPI unit prior changing mode */ + mpc83xx_spi_write_reg(tmp_ptr, regval & ~SPMODE_ENABLE); + mpc83xx_spi_write_reg(tmp_ptr, regval); + local_irq_restore(flags); + } + return 0; +} - /* Turn off SPI unit prior changing mode */ - mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, 0); - mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, regval); +static int mpc83xx_spi_bufs(struct spi_device *spi, struct spi_transfer *t) +{ + struct mpc83xx_spi *mpc83xx_spi; + u32 word, len, bits_per_word; - return 0; + mpc83xx_spi = spi_master_get_devdata(spi->master); + + mpc83xx_spi->tx = t->tx_buf; + mpc83xx_spi->rx = t->rx_buf; + bits_per_word = spi->bits_per_word; + if (t->bits_per_word) + bits_per_word = t->bits_per_word; + len = t->len; + if (bits_per_word > 8) + len /= 2; + if (bits_per_word > 16) + len /= 2; + mpc83xx_spi->count = len; + INIT_COMPLETION(mpc83xx_spi->done); + + /* enable rx ints */ + mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, SPIM_NE); + + /* transmit word */ + word = mpc83xx_spi->get_tx(mpc83xx_spi); + mpc83xx_spi_write_reg(&mpc83xx_spi->base->transmit, word); + + wait_for_completion(&mpc83xx_spi->done); + + /* disable rx ints */ + mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, 0); + + return mpc83xx_spi->count; +} + +static void mpc83xx_spi_work(struct work_struct *work) +{ + struct mpc83xx_spi *mpc83xx_spi = + container_of(work, struct mpc83xx_spi, work); + + spin_lock_irq(&mpc83xx_spi->lock); + mpc83xx_spi->busy = 1; + while (!list_empty(&mpc83xx_spi->queue)) { + struct spi_message *m; + struct spi_device *spi; + struct spi_transfer *t = NULL; + unsigned cs_change; + int status, nsecs = 50; + + m = container_of(mpc83xx_spi->queue.next, + struct spi_message, queue); + list_del_init(&m->queue); + spin_unlock_irq(&mpc83xx_spi->lock); + + spi = m->spi; + cs_change = 1; + status = 0; + list_for_each_entry(t, &m->transfers, transfer_list) { + if (t->bits_per_word || t->speed_hz) { + /* Don't allow changes if CS is active */ + status = -EINVAL; + + if (cs_change) + status = mpc83xx_spi_setup_transfer(spi, t); + if (status < 0) + break; + } + + if (cs_change) + mpc83xx_spi_chipselect(spi, BITBANG_CS_ACTIVE); + cs_change = t->cs_change; + if (t->len) + status = mpc83xx_spi_bufs(spi, t); + if (status) { + status = -EMSGSIZE; + break; + } + m->actual_length += t->len; + + if (t->delay_usecs) + udelay(t->delay_usecs); + + if (cs_change) { + ndelay(nsecs); + mpc83xx_spi_chipselect(spi, BITBANG_CS_INACTIVE); + ndelay(nsecs); + } + } + + m->status = status; + m->complete(m->context); + + if (status || !cs_change) { + ndelay(nsecs); + mpc83xx_spi_chipselect(spi, BITBANG_CS_INACTIVE); + } + + mpc83xx_spi_setup_transfer(spi, NULL); + + spin_lock_irq(&mpc83xx_spi->lock); + } + mpc83xx_spi->busy = 0; + spin_unlock_irq(&mpc83xx_spi->lock); } /* the spi->mode bits understood by this driver: */ @@ -286,9 +410,10 @@ int mpc83xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) static int mpc83xx_spi_setup(struct spi_device *spi) { - struct spi_bitbang *bitbang; struct mpc83xx_spi *mpc83xx_spi; int retval; + u32 hw_mode; + struct spi_mpc83xx_cs *cs = spi->controller_state; if (spi->mode & ~MODEBITS) { dev_dbg(&spi->dev, "setup: unsupported mode bits %x\n", @@ -299,63 +424,56 @@ static int mpc83xx_spi_setup(struct spi_device *spi) if (!spi->max_speed_hz) return -EINVAL; - bitbang = spi_master_get_devdata(spi->master); + if (!cs) { + cs = kzalloc(sizeof *cs, GFP_KERNEL); + if (!cs) + return -ENOMEM; + spi->controller_state = cs; + } mpc83xx_spi = spi_master_get_devdata(spi->master); if (!spi->bits_per_word) spi->bits_per_word = 8; + hw_mode = cs->hw_mode; /* Save orginal settings */ + cs->hw_mode = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode); + /* mask out bits we are going to set */ + cs->hw_mode &= ~(SPMODE_CP_BEGIN_EDGECLK | SPMODE_CI_INACTIVEHIGH + | SPMODE_REV | SPMODE_LOOP); + + if (spi->mode & SPI_CPHA) + cs->hw_mode |= SPMODE_CP_BEGIN_EDGECLK; + if (spi->mode & SPI_CPOL) + cs->hw_mode |= SPMODE_CI_INACTIVEHIGH; + if (!(spi->mode & SPI_LSB_FIRST)) + cs->hw_mode |= SPMODE_REV; + if (spi->mode & SPI_LOOP) + cs->hw_mode |= SPMODE_LOOP; + retval = mpc83xx_spi_setup_transfer(spi, NULL); - if (retval < 0) + if (retval < 0) { + cs->hw_mode = hw_mode; /* Restore settings */ return retval; + } - dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u nsec\n", + dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u Hz\n", __func__, spi->mode & (SPI_CPOL | SPI_CPHA), - spi->bits_per_word, 2 * mpc83xx_spi->nsecs); - + spi->bits_per_word, spi->max_speed_hz); +#if 0 /* Don't think this is needed */ /* NOTE we _need_ to call chipselect() early, ideally with adapter * setup, unless the hardware defaults cooperate to avoid confusion * between normal (active low) and inverted chipselects. */ /* deselect chip (low or high) */ - spin_lock(&bitbang->lock); - if (!bitbang->busy) { - bitbang->chipselect(spi, BITBANG_CS_INACTIVE); - ndelay(mpc83xx_spi->nsecs); - } - spin_unlock(&bitbang->lock); - + spin_lock(&mpc83xx_spi->lock); + if (!mpc83xx_spi->busy) + mpc83xx_spi_chipselect(spi, BITBANG_CS_INACTIVE); + spin_unlock(&mpc83xx_spi->lock); +#endif return 0; } -static int mpc83xx_spi_bufs(struct spi_device *spi, struct spi_transfer *t) -{ - struct mpc83xx_spi *mpc83xx_spi; - u32 word; - - mpc83xx_spi = spi_master_get_devdata(spi->master); - - mpc83xx_spi->tx = t->tx_buf; - mpc83xx_spi->rx = t->rx_buf; - mpc83xx_spi->count = t->len; - INIT_COMPLETION(mpc83xx_spi->done); - - /* enable rx ints */ - mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, SPIM_NE); - - /* transmit word */ - word = mpc83xx_spi->get_tx(mpc83xx_spi); - mpc83xx_spi_write_reg(&mpc83xx_spi->base->transmit, word); - - wait_for_completion(&mpc83xx_spi->done); - - /* disable rx ints */ - mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, 0); - - return t->len - mpc83xx_spi->count; -} - irqreturn_t mpc83xx_spi_irq(s32 irq, void *context_data) { struct mpc83xx_spi *mpc83xx_spi = context_data; @@ -395,6 +513,28 @@ irqreturn_t mpc83xx_spi_irq(s32 irq, void *context_data) return ret; } +static int mpc83xx_spi_transfer(struct spi_device *spi, + struct spi_message *m) +{ + struct mpc83xx_spi *mpc83xx_spi = spi_master_get_devdata(spi->master); + unsigned long flags; + + m->actual_length = 0; + m->status = -EINPROGRESS; + + spin_lock_irqsave(&mpc83xx_spi->lock, flags); + list_add_tail(&m->queue, &mpc83xx_spi->queue); + queue_work(mpc83xx_spi->workqueue, &mpc83xx_spi->work); + spin_unlock_irqrestore(&mpc83xx_spi->lock, flags); + + return 0; +} + + +static void mpc83xx_spi_cleanup(struct spi_device *spi) +{ + kfree(spi->controller_state); +} static int __init mpc83xx_spi_probe(struct platform_device *dev) { @@ -426,11 +566,11 @@ static int __init mpc83xx_spi_probe(struct platform_device *dev) ret = -ENODEV; goto free_master; } + master->setup = mpc83xx_spi_setup; + master->transfer = mpc83xx_spi_transfer; + master->cleanup = mpc83xx_spi_cleanup; + mpc83xx_spi = spi_master_get_devdata(master); - mpc83xx_spi->bitbang.master = spi_master_get(master); - mpc83xx_spi->bitbang.chipselect = mpc83xx_spi_chipselect; - mpc83xx_spi->bitbang.setup_transfer = mpc83xx_spi_setup_transfer; - mpc83xx_spi->bitbang.txrx_bufs = mpc83xx_spi_bufs; mpc83xx_spi->activate_cs = pdata->activate_cs; mpc83xx_spi->deactivate_cs = pdata->deactivate_cs; mpc83xx_spi->qe_mode = pdata->qe_mode; @@ -445,7 +585,6 @@ static int __init mpc83xx_spi_probe(struct platform_device *dev) mpc83xx_spi->tx_shift = 24; } - mpc83xx_spi->bitbang.master->setup = mpc83xx_spi_setup; init_completion(&mpc83xx_spi->done); mpc83xx_spi->base = ioremap(r->start, r->end - r->start + 1); @@ -483,11 +622,21 @@ static int __init mpc83xx_spi_probe(struct platform_device *dev) regval |= SPMODE_OP; mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, regval); + spin_lock_init(&mpc83xx_spi->lock); + init_completion(&mpc83xx_spi->done); + INIT_WORK(&mpc83xx_spi->work, mpc83xx_spi_work); + INIT_LIST_HEAD(&mpc83xx_spi->queue); - ret = spi_bitbang_start(&mpc83xx_spi->bitbang); - - if (ret != 0) + mpc83xx_spi->workqueue = create_singlethread_workqueue( + master->dev.parent->bus_id); + if (mpc83xx_spi->workqueue == NULL) { + ret = -EBUSY; goto free_irq; + } + + ret = spi_register_master(master); + if (ret < 0) + goto unreg_master; printk(KERN_INFO "%s: MPC83xx SPI Controller driver at 0x%p (irq = %d)\n", @@ -495,6 +644,8 @@ static int __init mpc83xx_spi_probe(struct platform_device *dev) return ret; +unreg_master: + destroy_workqueue(mpc83xx_spi->workqueue); free_irq: free_irq(mpc83xx_spi->irq, mpc83xx_spi); unmap_io: @@ -515,10 +666,12 @@ static int __exit mpc83xx_spi_remove(struct platform_device *dev) master = platform_get_drvdata(dev); mpc83xx_spi = spi_master_get_devdata(master); - spi_bitbang_stop(&mpc83xx_spi->bitbang); + flush_workqueue(mpc83xx_spi->workqueue); + destroy_workqueue(mpc83xx_spi->workqueue); + spi_unregister_master(master); + free_irq(mpc83xx_spi->irq, mpc83xx_spi); iounmap(mpc83xx_spi->base); - spi_master_put(mpc83xx_spi->bitbang.master); return 0; } diff --git a/drivers/usb/c67x00/c67x00-ll-hpi.c b/drivers/usb/c67x00/c67x00-ll-hpi.c index f3430b372f090e395e5b67273bf72fa97dc7e156..5100fbbf6cb02843db0030c119d598f1fb4f8812 100644 --- a/drivers/usb/c67x00/c67x00-ll-hpi.c +++ b/drivers/usb/c67x00/c67x00-ll-hpi.c @@ -23,6 +23,7 @@ #include #include +#include #include #include "c67x00.h" diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index cefe7f2c6f750d5ac8ab3c0483b0a535cb22c273..63c34043b4d91e0bfb2864672704be838f518fef 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1248,6 +1248,9 @@ static struct usb_device_id acm_ids[] = { { USB_DEVICE(0x22b8, 0x7000), /* Motorola Q Phone */ .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ }, + { USB_DEVICE(0x0803, 0x3095), /* Zoom Telephonics Model 3095F USB MODEM */ + .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ + }, /* control interfaces with various AT-command sets */ { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, diff --git a/drivers/usb/core/endpoint.c b/drivers/usb/core/endpoint.c index 99e5a68a3f120ead6785fc6b880968e97ab47e83..fae55a31e26dca055b5047b8ed70f8a56446cc41 100644 --- a/drivers/usb/core/endpoint.c +++ b/drivers/usb/core/endpoint.c @@ -156,6 +156,10 @@ static struct attribute *ep_dev_attrs[] = { static struct attribute_group ep_dev_attr_grp = { .attrs = ep_dev_attrs, }; +static struct attribute_group *ep_dev_groups[] = { + &ep_dev_attr_grp, + NULL +}; static int usb_endpoint_major_init(void) { @@ -298,6 +302,7 @@ int usb_create_ep_files(struct device *parent, ep_dev->desc = &endpoint->desc; ep_dev->udev = udev; + ep_dev->dev.groups = ep_dev_groups; ep_dev->dev.devt = MKDEV(usb_endpoint_major, ep_dev->minor); ep_dev->dev.class = ep_class->class; ep_dev->dev.parent = parent; @@ -309,9 +314,6 @@ int usb_create_ep_files(struct device *parent, retval = device_register(&ep_dev->dev); if (retval) goto error_chrdev; - retval = sysfs_create_group(&ep_dev->dev.kobj, &ep_dev_attr_grp); - if (retval) - goto error_group; /* create the symlink to the old-style "ep_XX" directory */ sprintf(name, "ep_%02x", endpoint->desc.bEndpointAddress); @@ -322,8 +324,6 @@ int usb_create_ep_files(struct device *parent, return retval; error_link: - sysfs_remove_group(&ep_dev->dev.kobj, &ep_dev_attr_grp); -error_group: device_unregister(&ep_dev->dev); destroy_endpoint_class(); return retval; @@ -348,7 +348,6 @@ void usb_remove_ep_files(struct usb_host_endpoint *endpoint) sprintf(name, "ep_%02x", endpoint->desc.bEndpointAddress); sysfs_remove_link(&ep_dev->dev.parent->kobj, name); - sysfs_remove_group(&ep_dev->dev.kobj, &ep_dev_attr_grp); device_unregister(&ep_dev->dev); endpoint->ep_dev = NULL; destroy_endpoint_class(); diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 3e69266e1f4db327c64f90d693aec503c887722b..fe47d145255ae95f248dbe6825c9abc7836e1bb8 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1607,6 +1607,7 @@ free_interfaces: intf->dev.driver = NULL; intf->dev.bus = &usb_bus_type; intf->dev.type = &usb_if_device_type; + intf->dev.groups = usb_interface_groups; intf->dev.dma_mask = dev->dev.dma_mask; device_initialize(&intf->dev); mark_quiesced(intf); diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 5b20a60de8ba9900bde0c51e7a7e8cb49590e84b..c783cb111847f6f9dab6c3fd990996af9e10c053 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -538,6 +538,46 @@ static struct attribute_group dev_attr_grp = { .attrs = dev_attrs, }; +/* When modifying this list, be sure to modify dev_string_attrs_are_visible() + * accordingly. + */ +static struct attribute *dev_string_attrs[] = { + &dev_attr_manufacturer.attr, + &dev_attr_product.attr, + &dev_attr_serial.attr, + NULL +}; + +static mode_t dev_string_attrs_are_visible(struct kobject *kobj, + struct attribute *a, int n) +{ + struct usb_device *udev = to_usb_device( + container_of(kobj, struct device, kobj)); + + if (a == &dev_attr_manufacturer.attr) { + if (udev->manufacturer == NULL) + return 0; + } else if (a == &dev_attr_product.attr) { + if (udev->product == NULL) + return 0; + } else if (a == &dev_attr_serial.attr) { + if (udev->serial == NULL) + return 0; + } + return a->mode; +} + +static struct attribute_group dev_string_attr_grp = { + .attrs = dev_string_attrs, + .is_visible = dev_string_attrs_are_visible, +}; + +struct attribute_group *usb_device_groups[] = { + &dev_attr_grp, + &dev_string_attr_grp, + NULL +}; + /* Binary descriptors */ static ssize_t @@ -591,10 +631,9 @@ int usb_create_sysfs_dev_files(struct usb_device *udev) struct device *dev = &udev->dev; int retval; - retval = sysfs_create_group(&dev->kobj, &dev_attr_grp); - if (retval) - return retval; - + /* Unforunately these attributes cannot be created before + * the uevent is broadcast. + */ retval = device_create_bin_file(dev, &dev_bin_attr_descriptors); if (retval) goto error; @@ -607,21 +646,6 @@ int usb_create_sysfs_dev_files(struct usb_device *udev) if (retval) goto error; - if (udev->manufacturer) { - retval = device_create_file(dev, &dev_attr_manufacturer); - if (retval) - goto error; - } - if (udev->product) { - retval = device_create_file(dev, &dev_attr_product); - if (retval) - goto error; - } - if (udev->serial) { - retval = device_create_file(dev, &dev_attr_serial); - if (retval) - goto error; - } retval = usb_create_ep_files(dev, &udev->ep0, udev); if (retval) goto error; @@ -636,13 +660,9 @@ void usb_remove_sysfs_dev_files(struct usb_device *udev) struct device *dev = &udev->dev; usb_remove_ep_files(&udev->ep0); - device_remove_file(dev, &dev_attr_manufacturer); - device_remove_file(dev, &dev_attr_product); - device_remove_file(dev, &dev_attr_serial); remove_power_attributes(dev); remove_persist_attributes(dev); device_remove_bin_file(dev, &dev_bin_attr_descriptors); - sysfs_remove_group(&dev->kobj, &dev_attr_grp); } /* Interface Accociation Descriptor fields */ @@ -688,17 +708,15 @@ static ssize_t show_interface_string(struct device *dev, struct device_attribute *attr, char *buf) { struct usb_interface *intf; - struct usb_device *udev; - int len; + char *string; intf = to_usb_interface(dev); - udev = interface_to_usbdev(intf); - len = snprintf(buf, 256, "%s", intf->cur_altsetting->string); - if (len < 0) + string = intf->cur_altsetting->string; + barrier(); /* The altsetting might change! */ + + if (!string) return 0; - buf[len] = '\n'; - buf[len+1] = 0; - return len+1; + return sprintf(buf, "%s\n", string); } static DEVICE_ATTR(interface, S_IRUGO, show_interface_string, NULL); @@ -727,18 +745,6 @@ static ssize_t show_modalias(struct device *dev, } static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL); -static struct attribute *intf_assoc_attrs[] = { - &dev_attr_iad_bFirstInterface.attr, - &dev_attr_iad_bInterfaceCount.attr, - &dev_attr_iad_bFunctionClass.attr, - &dev_attr_iad_bFunctionSubClass.attr, - &dev_attr_iad_bFunctionProtocol.attr, - NULL, -}; -static struct attribute_group intf_assoc_attr_grp = { - .attrs = intf_assoc_attrs, -}; - static struct attribute *intf_attrs[] = { &dev_attr_bInterfaceNumber.attr, &dev_attr_bAlternateSetting.attr, @@ -753,6 +759,37 @@ static struct attribute_group intf_attr_grp = { .attrs = intf_attrs, }; +static struct attribute *intf_assoc_attrs[] = { + &dev_attr_iad_bFirstInterface.attr, + &dev_attr_iad_bInterfaceCount.attr, + &dev_attr_iad_bFunctionClass.attr, + &dev_attr_iad_bFunctionSubClass.attr, + &dev_attr_iad_bFunctionProtocol.attr, + NULL, +}; + +static mode_t intf_assoc_attrs_are_visible(struct kobject *kobj, + struct attribute *a, int n) +{ + struct usb_interface *intf = to_usb_interface( + container_of(kobj, struct device, kobj)); + + if (intf->intf_assoc == NULL) + return 0; + return a->mode; +} + +static struct attribute_group intf_assoc_attr_grp = { + .attrs = intf_assoc_attrs, + .is_visible = intf_assoc_attrs_are_visible, +}; + +struct attribute_group *usb_interface_groups[] = { + &intf_attr_grp, + &intf_assoc_attr_grp, + NULL +}; + static inline void usb_create_intf_ep_files(struct usb_interface *intf, struct usb_device *udev) { @@ -777,23 +814,21 @@ static inline void usb_remove_intf_ep_files(struct usb_interface *intf) int usb_create_sysfs_intf_files(struct usb_interface *intf) { - struct device *dev = &intf->dev; struct usb_device *udev = interface_to_usbdev(intf); struct usb_host_interface *alt = intf->cur_altsetting; int retval; if (intf->sysfs_files_created) return 0; - retval = sysfs_create_group(&dev->kobj, &intf_attr_grp); - if (retval) - return retval; + /* The interface string may be present in some altsettings + * and missing in others. Hence its attribute cannot be created + * before the uevent is broadcast. + */ if (alt->string == NULL) alt->string = usb_cache_string(udev, alt->desc.iInterface); if (alt->string) - retval = device_create_file(dev, &dev_attr_interface); - if (intf->intf_assoc) - retval = sysfs_create_group(&dev->kobj, &intf_assoc_attr_grp); + retval = device_create_file(&intf->dev, &dev_attr_interface); usb_create_intf_ep_files(intf, udev); intf->sysfs_files_created = 1; return 0; @@ -807,7 +842,5 @@ void usb_remove_sysfs_intf_files(struct usb_interface *intf) return; usb_remove_intf_ep_files(intf); device_remove_file(dev, &dev_attr_interface); - sysfs_remove_group(&dev->kobj, &intf_attr_grp); - sysfs_remove_group(&intf->dev.kobj, &intf_assoc_attr_grp); intf->sysfs_files_created = 0; } diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 1f0db51190ccc79c121364de04a39a93c7e54aae..325774375837e5f1c578c7c402fd7bffaf18960a 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -291,6 +291,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, device_initialize(&dev->dev); dev->dev.bus = &usb_bus_type; dev->dev.type = &usb_device_type; + dev->dev.groups = usb_device_groups; dev->dev.dma_mask = bus->controller->dma_mask; set_dev_node(&dev->dev, dev_to_node(bus->controller)); dev->state = USB_STATE_ATTACHED; diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 1bf8ccb9c58dab72f243ff82168fda9cc427f6cc..1a8bc21c335e8848ebe5c2c1947fd5c0c38cd775 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -130,6 +130,10 @@ static inline int is_active(const struct usb_interface *f) /* for labeling diagnostics */ extern const char *usbcore_name; +/* sysfs stuff */ +extern struct attribute_group *usb_device_groups[]; +extern struct attribute_group *usb_interface_groups[]; + /* usbfs stuff */ extern struct mutex usbfs_mutex; extern struct usb_driver usbfs_driver; diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c index ce337cb5d13706a763b42193adf872efe38b309b..f261d2a9a5f00bafd2e02f6cb4b119378773c04a 100644 --- a/drivers/usb/gadget/amd5536udc.c +++ b/drivers/usb/gadget/amd5536udc.c @@ -3251,7 +3251,7 @@ static int udc_pci_probe( /* pci setup */ if (pci_enable_device(pdev) < 0) { kfree(dev); - dev = 0; + dev = NULL; retval = -ENODEV; goto finished; } @@ -3264,7 +3264,7 @@ static int udc_pci_probe( if (!request_mem_region(resource, len, name)) { dev_dbg(&pdev->dev, "pci device used already\n"); kfree(dev); - dev = 0; + dev = NULL; retval = -EBUSY; goto finished; } @@ -3274,7 +3274,7 @@ static int udc_pci_probe( if (dev->virt_addr == NULL) { dev_dbg(&pdev->dev, "start address cannot be mapped\n"); kfree(dev); - dev = 0; + dev = NULL; retval = -EFAULT; goto finished; } @@ -3282,7 +3282,7 @@ static int udc_pci_probe( if (!pdev->irq) { dev_err(&dev->pdev->dev, "irq not set\n"); kfree(dev); - dev = 0; + dev = NULL; retval = -ENODEV; goto finished; } @@ -3290,7 +3290,7 @@ static int udc_pci_probe( if (request_irq(pdev->irq, udc_irq, IRQF_SHARED, name, dev) != 0) { dev_dbg(&dev->pdev->dev, "request_irq(%d) fail\n", pdev->irq); kfree(dev); - dev = 0; + dev = NULL; retval = -EBUSY; goto finished; } diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c index e756023362c26e0429059764ee1630d867624a0f..07e5a0b5dcda49ea70aef4a5ee8f6b814fbf2a79 100644 --- a/drivers/usb/gadget/atmel_usba_udc.c +++ b/drivers/usb/gadget/atmel_usba_udc.c @@ -649,7 +649,13 @@ static int usba_ep_disable(struct usb_ep *_ep) if (!ep->desc) { spin_unlock_irqrestore(&udc->lock, flags); - DBG(DBG_ERR, "ep_disable: %s not enabled\n", ep->ep.name); + /* REVISIT because this driver disables endpoints in + * reset_all_endpoints() before calling disconnect(), + * most gadget drivers would trigger this non-error ... + */ + if (udc->gadget.speed != USB_SPEED_UNKNOWN) + DBG(DBG_ERR, "ep_disable: %s not enabled\n", + ep->ep.name); return -EINVAL; } ep->desc = NULL; @@ -1032,8 +1038,6 @@ static struct usba_udc the_udc = { .release = nop_release, }, }, - - .lock = SPIN_LOCK_UNLOCKED, }; /* @@ -1052,6 +1056,12 @@ static void reset_all_endpoints(struct usba_udc *udc) request_complete(ep, req, -ECONNRESET); } + /* NOTE: normally, the next call to the gadget driver is in + * charge of disabling endpoints... usually disconnect(). + * The exception would be entering a high speed test mode. + * + * FIXME remove this code ... and retest thoroughly. + */ list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) { if (ep->desc) { spin_unlock(&udc->lock); @@ -1219,7 +1229,7 @@ static inline bool feature_is_ep_halt(struct usb_ctrlrequest *crq) static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep, struct usb_ctrlrequest *crq) { - int retval = 0;; + int retval = 0; switch (crq->bRequest) { case USB_REQ_GET_STATUS: { @@ -1693,6 +1703,14 @@ static irqreturn_t usba_udc_irq(int irq, void *devid) usba_writel(udc, INT_CLR, USBA_END_OF_RESET); reset_all_endpoints(udc); + if (udc->gadget.speed != USB_SPEED_UNKNOWN + && udc->driver->disconnect) { + udc->gadget.speed = USB_SPEED_UNKNOWN; + spin_unlock(&udc->lock); + udc->driver->disconnect(&udc->gadget); + spin_lock(&udc->lock); + } + if (status & USBA_HIGH_SPEED) { DBG(DBG_BUS, "High-speed bus reset detected\n"); udc->gadget.speed = USB_SPEED_HIGH; @@ -1716,9 +1734,13 @@ static irqreturn_t usba_udc_irq(int irq, void *devid) | USBA_DET_SUSPEND | USBA_END_OF_RESUME)); + /* + * Unclear why we hit this irregularly, e.g. in usbtest, + * but it's clearly harmless... + */ if (!(usba_ep_readl(ep0, CFG) & USBA_EPT_MAPPED)) - dev_warn(&udc->pdev->dev, - "WARNING: EP0 configuration is invalid!\n"); + dev_dbg(&udc->pdev->dev, + "ODD: EP0 configuration is invalid!\n"); } spin_unlock(&udc->lock); @@ -1751,9 +1773,11 @@ static irqreturn_t usba_vbus_irq(int irq, void *devid) reset_all_endpoints(udc); toggle_bias(0); usba_writel(udc, CTRL, USBA_DISABLE_MASK); - spin_unlock(&udc->lock); - udc->driver->disconnect(&udc->gadget); - spin_lock(&udc->lock); + if (udc->driver->disconnect) { + spin_unlock(&udc->lock); + udc->driver->disconnect(&udc->gadget); + spin_lock(&udc->lock); + } } udc->vbus_prev = vbus; } @@ -1825,7 +1849,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) if (!udc->pdev) return -ENODEV; - if (driver != udc->driver) + if (driver != udc->driver || !driver->unbind) return -EINVAL; if (udc->vbus_pin != -1) @@ -1840,6 +1864,9 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) toggle_bias(0); usba_writel(udc, CTRL, USBA_DISABLE_MASK); + if (udc->driver->disconnect) + udc->driver->disconnect(&udc->gadget); + driver->unbind(&udc->gadget); udc->gadget.dev.driver = NULL; udc->driver = NULL; @@ -1879,6 +1906,7 @@ static int __init usba_udc_probe(struct platform_device *pdev) goto err_get_hclk; } + spin_lock_init(&udc->lock); udc->pdev = pdev; udc->pclk = pclk; udc->hclk = hclk; diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c index 75eba202f737f8807c7393a6eefd05839427d269..499b7a23f351275b0f55fc420f50f029fadcc515 100644 --- a/drivers/usb/gadget/pxa27x_udc.c +++ b/drivers/usb/gadget/pxa27x_udc.c @@ -1546,7 +1546,6 @@ static __init void udc_init_data(struct pxa_udc *dev) INIT_LIST_HEAD(&dev->gadget.ep0->ep_list); dev->udc_usb_ep[0].pxa_ep = &dev->pxa_ep[0]; ep0_idle(dev); - strcpy(dev->dev->bus_id, ""); /* PXA endpoints init */ for (i = 0; i < NR_PXA_ENDPOINTS; i++) { @@ -1746,13 +1745,10 @@ static void handle_ep0_ctrl_req(struct pxa_udc *udc, ep_err(ep, "wrong to have extra bytes for setup : 0x%08x\n", i); } - le16_to_cpus(&u.r.wValue); - le16_to_cpus(&u.r.wIndex); - le16_to_cpus(&u.r.wLength); - ep_dbg(ep, "SETUP %02x.%02x v%04x i%04x l%04x\n", u.r.bRequestType, u.r.bRequest, - u.r.wValue, u.r.wIndex, u.r.wLength); + le16_to_cpu(u.r.wValue), le16_to_cpu(u.r.wIndex), + le16_to_cpu(u.r.wLength)); if (unlikely(have_extrabytes)) goto stall; @@ -2296,7 +2292,8 @@ static void pxa_udc_shutdown(struct platform_device *_dev) { struct pxa_udc *udc = platform_get_drvdata(_dev); - udc_disable(udc); + if (udc_readl(udc, UDCCR) & UDCCR_UDE) + udc_disable(udc); } #ifdef CONFIG_PM @@ -2361,9 +2358,8 @@ static int pxa_udc_resume(struct platform_device *_dev) * Upon exit from sleep mode and before clearing OTGPH, * Software must configure the USB OTG pad, UDC, and UHC * to the state they were in before entering sleep mode. - * - * Should be : PSSR |= PSSR_OTGPH; */ + PSSR |= PSSR_OTGPH; return 0; } @@ -2387,6 +2383,9 @@ static struct platform_driver udc_driver = { static int __init udc_init(void) { + if (!cpu_is_pxa27x()) + return -ENODEV; + printk(KERN_INFO "%s: version %s\n", driver_name, DRIVER_VERSION); return platform_driver_probe(&udc_driver, pxa_udc_probe); } diff --git a/drivers/usb/gadget/pxa27x_udc.h b/drivers/usb/gadget/pxa27x_udc.h index 1d1b7936ee113fdb7a9ee7628fe104dff268fb7d..97453db924ff2bd869f6dadf89426ae71c76ff60 100644 --- a/drivers/usb/gadget/pxa27x_udc.h +++ b/drivers/usb/gadget/pxa27x_udc.h @@ -484,4 +484,12 @@ static inline struct pxa_udc *to_gadget_udc(struct usb_gadget *gadget) #define ep_warn(ep, fmt, arg...) \ dev_warn(ep->dev->dev, "%s:%s:" fmt, EPNAME(ep), __func__, ## arg) +/* + * Cannot include pxa-regs.h, as register names are similar. + * So PSSR is redefined here. This should be removed once UDC registers will + * be gone from pxa-regs.h. + */ +#define PSSR __REG(0x40F00004) /* Power Manager Sleep Status */ +#define PSSR_OTGPH (1 << 6) /* OTG Peripheral Hold */ + #endif /* __LINUX_USB_GADGET_PXA27X_H */ diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index 54cdd6f940346732fe38379ad75cd542a66e5709..fa019fa733346591a1c3c0a16a458f52ee9b423c 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c @@ -14,7 +14,6 @@ * This software is distributed under the terms of the GNU General * Public License ("GPL") as published by the Free Software Foundation, * either version 2 of that License or (at your option) any later version. - * */ #include @@ -33,7 +32,7 @@ /* Defines */ #define GS_VERSION_STR "v2.2" -#define GS_VERSION_NUM 0x0202 +#define GS_VERSION_NUM 0x2200 #define GS_LONG_NAME "Gadget Serial" #define GS_SHORT_NAME "g_serial" @@ -41,7 +40,11 @@ #define GS_MAJOR 127 #define GS_MINOR_START 0 -#define GS_NUM_PORTS 16 +/* REVISIT only one port is supported for now; + * see gs_{send,recv}_packet() ... no multiplexing, + * and no support for multiple ACM devices. + */ +#define GS_NUM_PORTS 1 #define GS_NUM_CONFIGS 1 #define GS_NO_CONFIG_ID 0 @@ -65,6 +68,9 @@ #define GS_DEFAULT_USE_ACM 0 +/* 9600-8-N-1 ... matches init_termios.c_cflag and defaults + * expected by "usbser.sys" on MS-Windows. + */ #define GS_DEFAULT_DTE_RATE 9600 #define GS_DEFAULT_DATA_BITS 8 #define GS_DEFAULT_PARITY USB_CDC_NO_PARITY @@ -107,10 +113,6 @@ static int debug = 1; #define GS_NOTIFY_MAXPACKET 8 -/* Structures */ - -struct gs_dev; - /* circular buffer */ struct gs_buf { unsigned int buf_size; @@ -119,12 +121,6 @@ struct gs_buf { char *buf_put; }; -/* list of requests */ -struct gs_req_entry { - struct list_head re_entry; - struct usb_request *re_req; -}; - /* the port structure holds info for each port, one for each minor number */ struct gs_port { struct gs_dev *port_dev; /* pointer to device struct */ @@ -164,26 +160,7 @@ struct gs_dev { /* Functions */ -/* module */ -static int __init gs_module_init(void); -static void __exit gs_module_exit(void); - -/* tty driver */ -static int gs_open(struct tty_struct *tty, struct file *file); -static void gs_close(struct tty_struct *tty, struct file *file); -static int gs_write(struct tty_struct *tty, - const unsigned char *buf, int count); -static int gs_put_char(struct tty_struct *tty, unsigned char ch); -static void gs_flush_chars(struct tty_struct *tty); -static int gs_write_room(struct tty_struct *tty); -static int gs_chars_in_buffer(struct tty_struct *tty); -static void gs_throttle(struct tty_struct * tty); -static void gs_unthrottle(struct tty_struct * tty); -static void gs_break(struct tty_struct *tty, int break_state); -static int gs_ioctl(struct tty_struct *tty, struct file *file, - unsigned int cmd, unsigned long arg); -static void gs_set_termios(struct tty_struct *tty, struct ktermios *old); - +/* tty driver internals */ static int gs_send(struct gs_dev *dev); static int gs_send_packet(struct gs_dev *dev, char *packet, unsigned int size); @@ -192,19 +169,7 @@ static int gs_recv_packet(struct gs_dev *dev, char *packet, static void gs_read_complete(struct usb_ep *ep, struct usb_request *req); static void gs_write_complete(struct usb_ep *ep, struct usb_request *req); -/* gadget driver */ -static int gs_bind(struct usb_gadget *gadget); -static void gs_unbind(struct usb_gadget *gadget); -static int gs_setup(struct usb_gadget *gadget, - const struct usb_ctrlrequest *ctrl); -static int gs_setup_standard(struct usb_gadget *gadget, - const struct usb_ctrlrequest *ctrl); -static int gs_setup_class(struct usb_gadget *gadget, - const struct usb_ctrlrequest *ctrl); -static void gs_setup_complete(struct usb_ep *ep, struct usb_request *req); -static void gs_setup_complete_set_line_coding(struct usb_ep *ep, - struct usb_request *req); -static void gs_disconnect(struct usb_gadget *gadget); +/* gadget driver internals */ static int gs_set_config(struct gs_dev *dev, unsigned config); static void gs_reset_config(struct gs_dev *dev); static int gs_build_config_buf(u8 *buf, struct usb_gadget *g, @@ -214,10 +179,6 @@ static struct usb_request *gs_alloc_req(struct usb_ep *ep, unsigned int len, gfp_t kmalloc_flags); static void gs_free_req(struct usb_ep *ep, struct usb_request *req); -static struct gs_req_entry *gs_alloc_req_entry(struct usb_ep *ep, unsigned len, - gfp_t kmalloc_flags); -static void gs_free_req_entry(struct usb_ep *ep, struct gs_req_entry *req); - static int gs_alloc_ports(struct gs_dev *dev, gfp_t kmalloc_flags); static void gs_free_ports(struct gs_dev *dev); @@ -232,62 +193,15 @@ static unsigned int gs_buf_put(struct gs_buf *gb, const char *buf, static unsigned int gs_buf_get(struct gs_buf *gb, char *buf, unsigned int count); -/* external functions */ -extern int net2280_set_fifo_mode(struct usb_gadget *gadget, int mode); - /* Globals */ static struct gs_dev *gs_device; -static const char *EP_IN_NAME; -static const char *EP_OUT_NAME; -static const char *EP_NOTIFY_NAME; - static struct mutex gs_open_close_lock[GS_NUM_PORTS]; -static unsigned int read_q_size = GS_DEFAULT_READ_Q_SIZE; -static unsigned int write_q_size = GS_DEFAULT_WRITE_Q_SIZE; - -static unsigned int write_buf_size = GS_DEFAULT_WRITE_BUF_SIZE; - -static unsigned int use_acm = GS_DEFAULT_USE_ACM; - - -/* tty driver struct */ -static const struct tty_operations gs_tty_ops = { - .open = gs_open, - .close = gs_close, - .write = gs_write, - .put_char = gs_put_char, - .flush_chars = gs_flush_chars, - .write_room = gs_write_room, - .ioctl = gs_ioctl, - .set_termios = gs_set_termios, - .throttle = gs_throttle, - .unthrottle = gs_unthrottle, - .break_ctl = gs_break, - .chars_in_buffer = gs_chars_in_buffer, -}; -static struct tty_driver *gs_tty_driver; - -/* gadget driver struct */ -static struct usb_gadget_driver gs_gadget_driver = { -#ifdef CONFIG_USB_GADGET_DUALSPEED - .speed = USB_SPEED_HIGH, -#else - .speed = USB_SPEED_FULL, -#endif /* CONFIG_USB_GADGET_DUALSPEED */ - .function = GS_LONG_NAME, - .bind = gs_bind, - .unbind = gs_unbind, - .setup = gs_setup, - .disconnect = gs_disconnect, - .driver = { - .name = GS_SHORT_NAME, - }, -}; +/*-------------------------------------------------------------------------*/ /* USB descriptors */ @@ -304,7 +218,6 @@ static char manufacturer[50]; static struct usb_string gs_strings[] = { { GS_MANUFACTURER_STR_ID, manufacturer }, { GS_PRODUCT_STR_ID, GS_LONG_NAME }, - { GS_SERIAL_STR_ID, "0" }, { GS_BULK_CONFIG_STR_ID, "Gadget Serial Bulk" }, { GS_ACM_CONFIG_STR_ID, "Gadget Serial CDC ACM" }, { GS_CONTROL_STR_ID, "Gadget Serial Control" }, @@ -327,7 +240,6 @@ static struct usb_device_descriptor gs_device_desc = { .idProduct = __constant_cpu_to_le16(GS_PRODUCT_ID), .iManufacturer = GS_MANUFACTURER_STR_ID, .iProduct = GS_PRODUCT_STR_ID, - .iSerialNumber = GS_SERIAL_STR_ID, .bNumConfigurations = GS_NUM_CONFIGS, }; @@ -364,7 +276,7 @@ static const struct usb_interface_descriptor gs_bulk_interface_desc = { .bDescriptorType = USB_DT_INTERFACE, .bInterfaceNumber = GS_BULK_INTERFACE_ID, .bNumEndpoints = 2, - .bInterfaceClass = USB_CLASS_CDC_DATA, + .bInterfaceClass = USB_CLASS_VENDOR_SPEC, .bInterfaceSubClass = 0, .bInterfaceProtocol = 0, .iInterface = GS_DATA_STR_ID, @@ -521,6 +433,8 @@ static const struct usb_descriptor_header *gs_acm_highspeed_function[] = { }; +/*-------------------------------------------------------------------------*/ + /* Module */ MODULE_DESCRIPTION(GS_LONG_NAME); MODULE_AUTHOR("Al Borchers"); @@ -531,84 +445,23 @@ module_param(debug, int, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(debug, "Enable debugging, 0=off, 1=on"); #endif +static unsigned int read_q_size = GS_DEFAULT_READ_Q_SIZE; module_param(read_q_size, uint, S_IRUGO); MODULE_PARM_DESC(read_q_size, "Read request queue size, default=32"); +static unsigned int write_q_size = GS_DEFAULT_WRITE_Q_SIZE; module_param(write_q_size, uint, S_IRUGO); MODULE_PARM_DESC(write_q_size, "Write request queue size, default=32"); +static unsigned int write_buf_size = GS_DEFAULT_WRITE_BUF_SIZE; module_param(write_buf_size, uint, S_IRUGO); MODULE_PARM_DESC(write_buf_size, "Write buffer size, default=8192"); +static unsigned int use_acm = GS_DEFAULT_USE_ACM; module_param(use_acm, uint, S_IRUGO); MODULE_PARM_DESC(use_acm, "Use CDC ACM, 0=no, 1=yes, default=no"); -module_init(gs_module_init); -module_exit(gs_module_exit); - -/* -* gs_module_init -* -* Register as a USB gadget driver and a tty driver. -*/ -static int __init gs_module_init(void) -{ - int i; - int retval; - - retval = usb_gadget_register_driver(&gs_gadget_driver); - if (retval) { - pr_err("gs_module_init: cannot register gadget driver, " - "ret=%d\n", retval); - return retval; - } - - gs_tty_driver = alloc_tty_driver(GS_NUM_PORTS); - if (!gs_tty_driver) - return -ENOMEM; - gs_tty_driver->owner = THIS_MODULE; - gs_tty_driver->driver_name = GS_SHORT_NAME; - gs_tty_driver->name = "ttygs"; - gs_tty_driver->major = GS_MAJOR; - gs_tty_driver->minor_start = GS_MINOR_START; - gs_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; - gs_tty_driver->subtype = SERIAL_TYPE_NORMAL; - gs_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; - gs_tty_driver->init_termios = tty_std_termios; - gs_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; - tty_set_operations(gs_tty_driver, &gs_tty_ops); - - for (i=0; i < GS_NUM_PORTS; i++) - mutex_init(&gs_open_close_lock[i]); - - retval = tty_register_driver(gs_tty_driver); - if (retval) { - usb_gadget_unregister_driver(&gs_gadget_driver); - put_tty_driver(gs_tty_driver); - pr_err("gs_module_init: cannot register tty driver, " - "ret=%d\n", retval); - return retval; - } - - pr_info("gs_module_init: %s %s loaded\n", - GS_LONG_NAME, GS_VERSION_STR); - return 0; -} - -/* -* gs_module_exit -* -* Unregister as a tty driver and a USB gadget driver. -*/ -static void __exit gs_module_exit(void) -{ - tty_unregister_driver(gs_tty_driver); - put_tty_driver(gs_tty_driver); - usb_gadget_unregister_driver(&gs_gadget_driver); - - pr_info("gs_module_exit: %s %s unloaded\n", - GS_LONG_NAME, GS_VERSION_STR); -} +/*-------------------------------------------------------------------------*/ /* TTY Driver */ @@ -753,15 +606,15 @@ exit_unlock_dev: * gs_close */ -#define GS_WRITE_FINISHED_EVENT_SAFELY(p) \ -({ \ - int cond; \ - \ - spin_lock_irq(&(p)->port_lock); \ - cond = !(p)->port_dev || !gs_buf_data_avail((p)->port_write_buf); \ - spin_unlock_irq(&(p)->port_lock); \ - cond; \ -}) +static int gs_write_finished_event_safely(struct gs_port *p) +{ + int cond; + + spin_lock_irq(&(p)->port_lock); + cond = !(p)->port_dev || !gs_buf_data_avail((p)->port_write_buf); + spin_unlock_irq(&(p)->port_lock); + return cond; +} static void gs_close(struct tty_struct *tty, struct file *file) { @@ -807,7 +660,7 @@ static void gs_close(struct tty_struct *tty, struct file *file) if (gs_buf_data_avail(port->port_write_buf) > 0) { spin_unlock_irq(&port->port_lock); wait_event_interruptible_timeout(port->port_write_wait, - GS_WRITE_FINISHED_EVENT_SAFELY(port), + gs_write_finished_event_safely(port), GS_CLOSE_TIMEOUT * HZ); spin_lock_irq(&port->port_lock); } @@ -1065,6 +918,23 @@ static void gs_set_termios(struct tty_struct *tty, struct ktermios *old) { } +static const struct tty_operations gs_tty_ops = { + .open = gs_open, + .close = gs_close, + .write = gs_write, + .put_char = gs_put_char, + .flush_chars = gs_flush_chars, + .write_room = gs_write_room, + .ioctl = gs_ioctl, + .set_termios = gs_set_termios, + .throttle = gs_throttle, + .unthrottle = gs_unthrottle, + .break_ctl = gs_break, + .chars_in_buffer = gs_chars_in_buffer, +}; + +/*-------------------------------------------------------------------------*/ + /* * gs_send * @@ -1080,7 +950,6 @@ static int gs_send(struct gs_dev *dev) unsigned long flags; struct usb_ep *ep; struct usb_request *req; - struct gs_req_entry *req_entry; if (dev == NULL) { pr_err("gs_send: NULL device pointer\n"); @@ -1093,10 +962,8 @@ static int gs_send(struct gs_dev *dev) while(!list_empty(&dev->dev_req_list)) { - req_entry = list_entry(dev->dev_req_list.next, - struct gs_req_entry, re_entry); - - req = req_entry->re_req; + req = list_entry(dev->dev_req_list.next, + struct usb_request, list); len = gs_send_packet(dev, req->buf, ep->maxpacket); @@ -1106,7 +973,7 @@ static int gs_send(struct gs_dev *dev) *((unsigned char *)req->buf), *((unsigned char *)req->buf+1), *((unsigned char *)req->buf+2)); - list_del(&req_entry->re_entry); + list_del(&req->list); req->length = len; spin_unlock_irqrestore(&dev->dev_lock, flags); if ((ret=usb_ep_queue(ep, req, GFP_ATOMIC))) { @@ -1289,7 +1156,6 @@ requeue: static void gs_write_complete(struct usb_ep *ep, struct usb_request *req) { struct gs_dev *dev = ep->driver_data; - struct gs_req_entry *gs_req = req->context; if (dev == NULL) { pr_err("gs_write_complete: NULL device pointer\n"); @@ -1300,13 +1166,8 @@ static void gs_write_complete(struct usb_ep *ep, struct usb_request *req) case 0: /* normal completion */ requeue: - if (gs_req == NULL) { - pr_err("gs_write_complete: NULL request pointer\n"); - return; - } - spin_lock(&dev->dev_lock); - list_add(&gs_req->re_entry, &dev->dev_req_list); + list_add(&req->list, &dev->dev_req_list); spin_unlock(&dev->dev_lock); gs_send(dev); @@ -1328,8 +1189,38 @@ requeue: } } +/*-------------------------------------------------------------------------*/ + /* Gadget Driver */ +/* + * gs_unbind + * + * Called on module unload. Frees the control request and device + * structure. + */ +static void /* __init_or_exit */ gs_unbind(struct usb_gadget *gadget) +{ + struct gs_dev *dev = get_gadget_data(gadget); + + gs_device = NULL; + + /* read/write requests already freed, only control request remains */ + if (dev != NULL) { + if (dev->dev_ctrl_req != NULL) { + gs_free_req(gadget->ep0, dev->dev_ctrl_req); + dev->dev_ctrl_req = NULL; + } + gs_reset_config(dev); + gs_free_ports(dev); + kfree(dev); + set_gadget_data(gadget, NULL); + } + + pr_info("gs_unbind: %s %s unbound\n", GS_LONG_NAME, + GS_VERSION_STR); +} + /* * gs_bind * @@ -1362,19 +1253,23 @@ static int __init gs_bind(struct usb_gadget *gadget) __constant_cpu_to_le16(GS_VERSION_NUM|0x0099); } + dev = kzalloc(sizeof(struct gs_dev), GFP_KERNEL); + if (dev == NULL) + return -ENOMEM; + usb_ep_autoconfig_reset(gadget); ep = usb_ep_autoconfig(gadget, &gs_fullspeed_in_desc); if (!ep) goto autoconf_fail; - EP_IN_NAME = ep->name; - ep->driver_data = ep; /* claim the endpoint */ + dev->dev_in_ep = ep; + ep->driver_data = dev; /* claim the endpoint */ ep = usb_ep_autoconfig(gadget, &gs_fullspeed_out_desc); if (!ep) goto autoconf_fail; - EP_OUT_NAME = ep->name; - ep->driver_data = ep; /* claim the endpoint */ + dev->dev_out_ep = ep; + ep->driver_data = dev; /* claim the endpoint */ if (use_acm) { ep = usb_ep_autoconfig(gadget, &gs_fullspeed_notify_desc); @@ -1384,8 +1279,8 @@ static int __init gs_bind(struct usb_gadget *gadget) } gs_device_desc.idProduct = __constant_cpu_to_le16( GS_CDC_PRODUCT_ID), - EP_NOTIFY_NAME = ep->name; - ep->driver_data = ep; /* claim the endpoint */ + dev->dev_notify_ep = ep; + ep->driver_data = dev; /* claim the endpoint */ } gs_device_desc.bDeviceClass = use_acm @@ -1415,9 +1310,7 @@ static int __init gs_bind(struct usb_gadget *gadget) gs_acm_config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP; } - gs_device = dev = kzalloc(sizeof(struct gs_dev), GFP_KERNEL); - if (dev == NULL) - return -ENOMEM; + gs_device = dev; snprintf(manufacturer, sizeof(manufacturer), "%s %s with %s", init_utsname()->sysname, init_utsname()->release, @@ -1441,8 +1334,6 @@ static int __init gs_bind(struct usb_gadget *gadget) gs_unbind(gadget); return -ENOMEM; } - dev->dev_ctrl_req->complete = gs_setup_complete; - gadget->ep0->driver_data = dev; pr_info("gs_bind: %s %s bound\n", @@ -1451,99 +1342,11 @@ static int __init gs_bind(struct usb_gadget *gadget) return 0; autoconf_fail: + kfree(dev); pr_err("gs_bind: cannot autoconfigure on %s\n", gadget->name); return -ENODEV; } -/* - * gs_unbind - * - * Called on module unload. Frees the control request and device - * structure. - */ -static void /* __init_or_exit */ gs_unbind(struct usb_gadget *gadget) -{ - struct gs_dev *dev = get_gadget_data(gadget); - - gs_device = NULL; - - /* read/write requests already freed, only control request remains */ - if (dev != NULL) { - if (dev->dev_ctrl_req != NULL) { - gs_free_req(gadget->ep0, dev->dev_ctrl_req); - dev->dev_ctrl_req = NULL; - } - gs_free_ports(dev); - if (dev->dev_notify_ep) - usb_ep_disable(dev->dev_notify_ep); - if (dev->dev_in_ep) - usb_ep_disable(dev->dev_in_ep); - if (dev->dev_out_ep) - usb_ep_disable(dev->dev_out_ep); - kfree(dev); - set_gadget_data(gadget, NULL); - } - - pr_info("gs_unbind: %s %s unbound\n", GS_LONG_NAME, - GS_VERSION_STR); -} - -/* - * gs_setup - * - * Implements all the control endpoint functionality that's not - * handled in hardware or the hardware driver. - * - * Returns the size of the data sent to the host, or a negative - * error number. - */ -static int gs_setup(struct usb_gadget *gadget, - const struct usb_ctrlrequest *ctrl) -{ - int ret = -EOPNOTSUPP; - struct gs_dev *dev = get_gadget_data(gadget); - struct usb_request *req = dev->dev_ctrl_req; - u16 wIndex = le16_to_cpu(ctrl->wIndex); - u16 wValue = le16_to_cpu(ctrl->wValue); - u16 wLength = le16_to_cpu(ctrl->wLength); - - req->complete = gs_setup_complete; - - switch (ctrl->bRequestType & USB_TYPE_MASK) { - case USB_TYPE_STANDARD: - ret = gs_setup_standard(gadget,ctrl); - break; - - case USB_TYPE_CLASS: - ret = gs_setup_class(gadget,ctrl); - break; - - default: - pr_err("gs_setup: unknown request, type=%02x, request=%02x, " - "value=%04x, index=%04x, length=%d\n", - ctrl->bRequestType, ctrl->bRequest, - wValue, wIndex, wLength); - break; - } - - /* respond with data transfer before status phase? */ - if (ret >= 0) { - req->length = ret; - req->zero = ret < wLength - && (ret % gadget->ep0->maxpacket) == 0; - ret = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC); - if (ret < 0) { - pr_err("gs_setup: cannot queue response, ret=%d\n", - ret); - req->status = 0; - gs_setup_complete(gadget->ep0, req); - } - } - - /* device either stalls (ret < 0) or reports success */ - return ret; -} - static int gs_setup_standard(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) { @@ -1673,6 +1476,42 @@ set_interface_done: return ret; } +static void gs_setup_complete_set_line_coding(struct usb_ep *ep, + struct usb_request *req) +{ + struct gs_dev *dev = ep->driver_data; + struct gs_port *port = dev->dev_port[0]; /* ACM only has one port */ + + switch (req->status) { + case 0: + /* normal completion */ + if (req->actual != sizeof(port->port_line_coding)) + usb_ep_set_halt(ep); + else if (port) { + struct usb_cdc_line_coding *value = req->buf; + + /* REVISIT: we currently just remember this data. + * If we change that, (a) validate it first, then + * (b) update whatever hardware needs updating. + */ + spin_lock(&port->port_lock); + port->port_line_coding = *value; + spin_unlock(&port->port_lock); + } + break; + + case -ESHUTDOWN: + /* disconnect */ + gs_free_req(ep, req); + break; + + default: + /* unexpected */ + break; + } + return; +} + static int gs_setup_class(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) { @@ -1734,52 +1573,72 @@ static int gs_setup_class(struct usb_gadget *gadget, return ret; } -static void gs_setup_complete_set_line_coding(struct usb_ep *ep, - struct usb_request *req) +/* + * gs_setup_complete + */ +static void gs_setup_complete(struct usb_ep *ep, struct usb_request *req) { - struct gs_dev *dev = ep->driver_data; - struct gs_port *port = dev->dev_port[0]; /* ACM only has one port */ + if (req->status || req->actual != req->length) { + pr_err("gs_setup_complete: status error, status=%d, " + "actual=%d, length=%d\n", + req->status, req->actual, req->length); + } +} - switch (req->status) { - case 0: - /* normal completion */ - if (req->actual != sizeof(port->port_line_coding)) - usb_ep_set_halt(ep); - else if (port) { - struct usb_cdc_line_coding *value = req->buf; +/* + * gs_setup + * + * Implements all the control endpoint functionality that's not + * handled in hardware or the hardware driver. + * + * Returns the size of the data sent to the host, or a negative + * error number. + */ +static int gs_setup(struct usb_gadget *gadget, + const struct usb_ctrlrequest *ctrl) +{ + int ret = -EOPNOTSUPP; + struct gs_dev *dev = get_gadget_data(gadget); + struct usb_request *req = dev->dev_ctrl_req; + u16 wIndex = le16_to_cpu(ctrl->wIndex); + u16 wValue = le16_to_cpu(ctrl->wValue); + u16 wLength = le16_to_cpu(ctrl->wLength); - /* REVISIT: we currently just remember this data. - * If we change that, (a) validate it first, then - * (b) update whatever hardware needs updating. - */ - spin_lock(&port->port_lock); - port->port_line_coding = *value; - spin_unlock(&port->port_lock); - } + req->complete = gs_setup_complete; + + switch (ctrl->bRequestType & USB_TYPE_MASK) { + case USB_TYPE_STANDARD: + ret = gs_setup_standard(gadget, ctrl); break; - case -ESHUTDOWN: - /* disconnect */ - gs_free_req(ep, req); + case USB_TYPE_CLASS: + ret = gs_setup_class(gadget, ctrl); break; default: - /* unexpected */ + pr_err("gs_setup: unknown request, type=%02x, request=%02x, " + "value=%04x, index=%04x, length=%d\n", + ctrl->bRequestType, ctrl->bRequest, + wValue, wIndex, wLength); break; } - return; -} -/* - * gs_setup_complete - */ -static void gs_setup_complete(struct usb_ep *ep, struct usb_request *req) -{ - if (req->status || req->actual != req->length) { - pr_err("gs_setup_complete: status error, status=%d, " - "actual=%d, length=%d\n", - req->status, req->actual, req->length); + /* respond with data transfer before status phase? */ + if (ret >= 0) { + req->length = ret; + req->zero = ret < wLength + && (ret % gadget->ep0->maxpacket) == 0; + ret = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC); + if (ret < 0) { + pr_err("gs_setup: cannot queue response, ret=%d\n", + ret); + req->status = 0; + gs_setup_complete(gadget->ep0, req); + } } + + /* device either stalls (ret < 0) or reports success */ + return ret; } /* @@ -1811,6 +1670,23 @@ static void gs_disconnect(struct usb_gadget *gadget) pr_info("gs_disconnect: %s disconnected\n", GS_LONG_NAME); } +static struct usb_gadget_driver gs_gadget_driver = { +#ifdef CONFIG_USB_GADGET_DUALSPEED + .speed = USB_SPEED_HIGH, +#else + .speed = USB_SPEED_FULL, +#endif /* CONFIG_USB_GADGET_DUALSPEED */ + .function = GS_LONG_NAME, + .bind = gs_bind, + .unbind = gs_unbind, + .setup = gs_setup, + .disconnect = gs_disconnect, + .driver = { + .name = GS_SHORT_NAME, + .owner = THIS_MODULE, + }, +}; + /* * gs_set_config * @@ -1826,9 +1702,8 @@ static int gs_set_config(struct gs_dev *dev, unsigned config) int ret = 0; struct usb_gadget *gadget = dev->dev_gadget; struct usb_ep *ep; - struct usb_endpoint_descriptor *ep_desc; + struct usb_endpoint_descriptor *out, *in, *notify; struct usb_request *req; - struct gs_req_entry *req_entry; if (dev == NULL) { pr_err("gs_set_config: NULL device pointer\n"); @@ -1846,86 +1721,62 @@ static int gs_set_config(struct gs_dev *dev, unsigned config) case GS_BULK_CONFIG_ID: if (use_acm) return -EINVAL; - /* device specific optimizations */ - if (gadget_is_net2280(gadget)) - net2280_set_fifo_mode(gadget, 1); break; case GS_ACM_CONFIG_ID: if (!use_acm) return -EINVAL; - /* device specific optimizations */ - if (gadget_is_net2280(gadget)) - net2280_set_fifo_mode(gadget, 1); break; default: return -EINVAL; } - dev->dev_config = config; - - gadget_for_each_ep(ep, gadget) { - - if (EP_NOTIFY_NAME - && strcmp(ep->name, EP_NOTIFY_NAME) == 0) { - ep_desc = choose_ep_desc(gadget, + in = choose_ep_desc(gadget, + &gs_highspeed_in_desc, + &gs_fullspeed_in_desc); + out = choose_ep_desc(gadget, + &gs_highspeed_out_desc, + &gs_fullspeed_out_desc); + notify = dev->dev_notify_ep + ? choose_ep_desc(gadget, &gs_highspeed_notify_desc, - &gs_fullspeed_notify_desc); - ret = usb_ep_enable(ep,ep_desc); - if (ret == 0) { - ep->driver_data = dev; - dev->dev_notify_ep = ep; - dev->dev_notify_ep_desc = ep_desc; - } else { - pr_err("gs_set_config: cannot enable NOTIFY " - "endpoint %s, ret=%d\n", - ep->name, ret); - goto exit_reset_config; - } - } - - else if (strcmp(ep->name, EP_IN_NAME) == 0) { - ep_desc = choose_ep_desc(gadget, - &gs_highspeed_in_desc, - &gs_fullspeed_in_desc); - ret = usb_ep_enable(ep,ep_desc); - if (ret == 0) { - ep->driver_data = dev; - dev->dev_in_ep = ep; - dev->dev_in_ep_desc = ep_desc; - } else { - pr_err("gs_set_config: cannot enable IN " - "endpoint %s, ret=%d\n", - ep->name, ret); - goto exit_reset_config; - } - } + &gs_fullspeed_notify_desc) + : NULL; - else if (strcmp(ep->name, EP_OUT_NAME) == 0) { - ep_desc = choose_ep_desc(gadget, - &gs_highspeed_out_desc, - &gs_fullspeed_out_desc); - ret = usb_ep_enable(ep,ep_desc); - if (ret == 0) { - ep->driver_data = dev; - dev->dev_out_ep = ep; - dev->dev_out_ep_desc = ep_desc; - } else { - pr_err("gs_set_config: cannot enable OUT " - "endpoint %s, ret=%d\n", - ep->name, ret); - goto exit_reset_config; - } - } + ret = usb_ep_enable(dev->dev_in_ep, in); + if (ret == 0) { + dev->dev_in_ep_desc = in; + } else { + pr_debug("%s: cannot enable %s %s, ret=%d\n", + __func__, "IN", dev->dev_in_ep->name, ret); + return ret; + } + ret = usb_ep_enable(dev->dev_out_ep, out); + if (ret == 0) { + dev->dev_out_ep_desc = out; + } else { + pr_debug("%s: cannot enable %s %s, ret=%d\n", + __func__, "OUT", dev->dev_out_ep->name, ret); +fail0: + usb_ep_disable(dev->dev_in_ep); + return ret; } - if (dev->dev_in_ep == NULL || dev->dev_out_ep == NULL - || (config != GS_BULK_CONFIG_ID && dev->dev_notify_ep == NULL)) { - pr_err("gs_set_config: cannot find endpoints\n"); - ret = -ENODEV; - goto exit_reset_config; + if (notify) { + ret = usb_ep_enable(dev->dev_notify_ep, notify); + if (ret == 0) { + dev->dev_notify_ep_desc = notify; + } else { + pr_debug("%s: cannot enable %s %s, ret=%d\n", + __func__, "NOTIFY", + dev->dev_notify_ep->name, ret); + usb_ep_disable(dev->dev_out_ep); + goto fail0; + } } + dev->dev_config = config; + /* allocate and queue read requests */ ep = dev->dev_out_ep; for (i=0; idev_in_ep; for (i=0; imaxpacket, GFP_ATOMIC))) { - req_entry->re_req->complete = gs_write_complete; - list_add(&req_entry->re_entry, &dev->dev_req_list); + req = gs_alloc_req(ep, ep->maxpacket, GFP_ATOMIC); + if (req) { + req->complete = gs_write_complete; + list_add(&req->list, &dev->dev_req_list); } else { pr_err("gs_set_config: cannot allocate " "write requests\n"); @@ -1986,7 +1838,7 @@ exit_reset_config: */ static void gs_reset_config(struct gs_dev *dev) { - struct gs_req_entry *req_entry; + struct usb_request *req; if (dev == NULL) { pr_err("gs_reset_config: NULL device pointer\n"); @@ -2000,26 +1852,18 @@ static void gs_reset_config(struct gs_dev *dev) /* free write requests on the free list */ while(!list_empty(&dev->dev_req_list)) { - req_entry = list_entry(dev->dev_req_list.next, - struct gs_req_entry, re_entry); - list_del(&req_entry->re_entry); - gs_free_req_entry(dev->dev_in_ep, req_entry); + req = list_entry(dev->dev_req_list.next, + struct usb_request, list); + list_del(&req->list); + gs_free_req(dev->dev_in_ep, req); } /* disable endpoints, forcing completion of pending i/o; */ /* completion handlers free their requests in this case */ - if (dev->dev_notify_ep) { + if (dev->dev_notify_ep) usb_ep_disable(dev->dev_notify_ep); - dev->dev_notify_ep = NULL; - } - if (dev->dev_in_ep) { - usb_ep_disable(dev->dev_in_ep); - dev->dev_in_ep = NULL; - } - if (dev->dev_out_ep) { - usb_ep_disable(dev->dev_out_ep); - dev->dev_out_ep = NULL; - } + usb_ep_disable(dev->dev_in_ep); + usb_ep_disable(dev->dev_out_ep); } /* @@ -2112,46 +1956,6 @@ static void gs_free_req(struct usb_ep *ep, struct usb_request *req) } } -/* - * gs_alloc_req_entry - * - * Allocates a request and its buffer, using the given - * endpoint, buffer len, and kmalloc flags. - */ -static struct gs_req_entry * -gs_alloc_req_entry(struct usb_ep *ep, unsigned len, gfp_t kmalloc_flags) -{ - struct gs_req_entry *req; - - req = kmalloc(sizeof(struct gs_req_entry), kmalloc_flags); - if (req == NULL) - return NULL; - - req->re_req = gs_alloc_req(ep, len, kmalloc_flags); - if (req->re_req == NULL) { - kfree(req); - return NULL; - } - - req->re_req->context = req; - - return req; -} - -/* - * gs_free_req_entry - * - * Frees a request and its buffer. - */ -static void gs_free_req_entry(struct usb_ep *ep, struct gs_req_entry *req) -{ - if (ep != NULL && req != NULL) { - if (req->re_req != NULL) - gs_free_req(ep, req->re_req); - kfree(req); - } -} - /* * gs_alloc_ports * @@ -2233,6 +2037,8 @@ static void gs_free_ports(struct gs_dev *dev) } } +/*-------------------------------------------------------------------------*/ + /* Circular Buffer */ /* @@ -2393,3 +2199,77 @@ gs_buf_get(struct gs_buf *gb, char *buf, unsigned int count) return count; } + +/*-------------------------------------------------------------------------*/ + +static struct tty_driver *gs_tty_driver; + +/* + * gs_module_init + * + * Register as a USB gadget driver and a tty driver. + */ +static int __init gs_module_init(void) +{ + int i; + int retval; + + retval = usb_gadget_register_driver(&gs_gadget_driver); + if (retval) { + pr_err("gs_module_init: cannot register gadget driver, " + "ret=%d\n", retval); + return retval; + } + + gs_tty_driver = alloc_tty_driver(GS_NUM_PORTS); + if (!gs_tty_driver) + return -ENOMEM; + gs_tty_driver->owner = THIS_MODULE; + gs_tty_driver->driver_name = GS_SHORT_NAME; + gs_tty_driver->name = "ttygs"; + gs_tty_driver->major = GS_MAJOR; + gs_tty_driver->minor_start = GS_MINOR_START; + gs_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; + gs_tty_driver->subtype = SERIAL_TYPE_NORMAL; + gs_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; + gs_tty_driver->init_termios = tty_std_termios; + /* must match GS_DEFAULT_DTE_RATE and friends */ + gs_tty_driver->init_termios.c_cflag = + B9600 | CS8 | CREAD | HUPCL | CLOCAL; + gs_tty_driver->init_termios.c_ispeed = GS_DEFAULT_DTE_RATE; + gs_tty_driver->init_termios.c_ospeed = GS_DEFAULT_DTE_RATE; + tty_set_operations(gs_tty_driver, &gs_tty_ops); + + for (i = 0; i < GS_NUM_PORTS; i++) + mutex_init(&gs_open_close_lock[i]); + + retval = tty_register_driver(gs_tty_driver); + if (retval) { + usb_gadget_unregister_driver(&gs_gadget_driver); + put_tty_driver(gs_tty_driver); + pr_err("gs_module_init: cannot register tty driver, " + "ret=%d\n", retval); + return retval; + } + + pr_info("gs_module_init: %s %s loaded\n", + GS_LONG_NAME, GS_VERSION_STR); + return 0; +} +module_init(gs_module_init); + +/* + * gs_module_exit + * + * Unregister as a tty driver and a USB gadget driver. + */ +static void __exit gs_module_exit(void) +{ + tty_unregister_driver(gs_tty_driver); + put_tty_driver(gs_tty_driver); + usb_gadget_unregister_driver(&gs_gadget_driver); + + pr_info("gs_module_exit: %s %s unloaded\n", + GS_LONG_NAME, GS_VERSION_STR); +} +module_exit(gs_module_exit); diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 33b467a8352dc95892b09dba5a023d64968ebc1f..1ef6df395e0c83954351fa2dcec9d260a6c97a52 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -129,7 +129,7 @@ config USB_ISP1760_PCI config USB_ISP1760_OF bool "Support for the OF platform bus" - depends on USB_ISP1760_HCD && OF + depends on USB_ISP1760_HCD && PPC_OF ---help--- Enables support for the device present on the PowerPC OpenFirmware platform bus. diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index 4ba96c1e060ce213ae8520c822ceac3a05107d7c..c9cec87382619f8f97c1e1d5a0f124e8836f372a 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c @@ -988,7 +988,7 @@ static void do_atl_int(struct usb_hcd *usb_hcd) * This did not trigger for a long time now. */ printk(KERN_ERR "Reloading ptd %p/%p... qh %p readed: " - "%d of %d done: %08x cur: %08x\n", qtd, + "%d of %zu done: %08x cur: %08x\n", qtd, urb, qh, PTD_XFERRED_LENGTH(dw3), qtd->length, done_map, (1 << queue_entry)); @@ -1088,7 +1088,7 @@ static void do_atl_int(struct usb_hcd *usb_hcd) } else if (usb_pipebulk(urb->pipe) && (length < qtd->length)) { /* short BULK received */ - printk(KERN_ERR "short bulk, %d instead %d\n", length, + printk(KERN_ERR "short bulk, %d instead %zu\n", length, qtd->length); if (urb->transfer_flags & URB_SHORT_NOT_OK) { urb->status = -EREMOTEIO; diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c index 73fb2a38f1e40dd594549bd6d797ae6eba2a1216..440bf94f0d4ca178ffed89e67c82371d42e997eb 100644 --- a/drivers/usb/host/isp1760-if.c +++ b/drivers/usb/host/isp1760-if.c @@ -256,7 +256,7 @@ static struct pci_driver isp1761_pci_driver = { static int __init isp1760_init(void) { - int ret; + int ret = -ENODEV; init_kmem_once(); diff --git a/drivers/usb/host/ohci-sm501.c b/drivers/usb/host/ohci-sm501.c index 77204f001b9a6eefcce60ee54b241aa364013f38..e899a77dfb8340ae69e3502dcc8c5c2482a93a70 100644 --- a/drivers/usb/host/ohci-sm501.c +++ b/drivers/usb/host/ohci-sm501.c @@ -90,7 +90,7 @@ static int ohci_hcd_sm501_drv_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct resource *res, *mem; int retval, irq; - struct usb_hcd *hcd = 0; + struct usb_hcd *hcd = NULL; irq = retval = platform_get_irq(pdev, 0); if (retval < 0) diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c index 7aafd53fbcab8452c08b1c510e2f6537a7f8f987..189a9db035090fb35cf4c320d6dffd5a0d63c8db 100644 --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c @@ -63,9 +63,6 @@ #define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004 #define USB_DEVICE_ID_VERNIER_LCSPEC 0x0006 -#define USB_VENDOR_ID_MICROCHIP 0x04d8 -#define USB_DEVICE_ID_PICDEM 0x000c - #ifdef CONFIG_USB_DYNAMIC_MINORS #define USB_LD_MINOR_BASE 0 #else @@ -92,7 +89,6 @@ static struct usb_device_id ld_usb_table [] = { { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) }, { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) }, { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS) }, - { USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICDEM) }, { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LCSPEC) }, { } /* Terminating entry */ }; diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index 742be3c3594788b23464050e1a09afafed91fbde..054dedd2812718c1c1350acb058f983e1dda3331 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -856,6 +856,11 @@ test_ctrl_queue (struct usbtest_dev *dev, struct usbtest_param *param) struct urb *u; struct usb_ctrlrequest req; struct subcase *reqp; + + /* sign of this variable means: + * -: tested code must return this (negative) error code + * +: tested code may return this (negative too) error code + */ int expected = 0; /* requests here are mostly expected to succeed on any diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index 2cffec85ee7e6581d95f14971a2afc7fe1eadbce..9ba64ccc135922af584d74fbc4e1c4877f71dfd8 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig @@ -447,6 +447,15 @@ config USB_SERIAL_MOS7840 To compile this driver as a module, choose M here: the module will be called mos7840. If unsure, choose N. +config USB_SERIAL_MOTOROLA + tristate "USB Motorola Phone modem driver" + ---help--- + Say Y here if you want to use a Motorola phone with a USB + connector as a modem link. + + To compile this driver as a module, choose M here: the + module will be called moto_modem. If unsure, choose N. + config USB_SERIAL_NAVMAN tristate "USB Navman GPS device" help diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile index 756859510d8c2cfff713b6ff13b7f0076b5bf057..17a762ab67697b0b04cc943af8e673fff6e3cc5e 100644 --- a/drivers/usb/serial/Makefile +++ b/drivers/usb/serial/Makefile @@ -39,6 +39,7 @@ obj-$(CONFIG_USB_SERIAL_KOBIL_SCT) += kobil_sct.o obj-$(CONFIG_USB_SERIAL_MCT_U232) += mct_u232.o obj-$(CONFIG_USB_SERIAL_MOS7720) += mos7720.o obj-$(CONFIG_USB_SERIAL_MOS7840) += mos7840.o +obj-$(CONFIG_USB_SERIAL_MOTOROLA) += moto_modem.o obj-$(CONFIG_USB_SERIAL_NAVMAN) += navman.o obj-$(CONFIG_USB_SERIAL_OMNINET) += omninet.o obj-$(CONFIG_USB_SERIAL_OPTION) += option.o diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c index dc0ea08ed2315773b0f85fbcaf25848d83d69be9..f5b57b196c5a0821845209b9ff74052f9eb2bb5a 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp2101.c @@ -73,6 +73,7 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */ { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */ { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */ + { USB_DEVICE(0x10C4, 0x81A6) }, /* ThinkOptics WavIt */ { USB_DEVICE(0x10C4, 0x81AC) }, /* MSD Dash Hawk */ { USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */ { USB_DEVICE(0x10C4, 0x81E2) }, /* Lipowsky Industrie Elektronik GmbH, Baby-LIN */ diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c index 8a217648b250311abf685cd0f89cc558de41f7ca..a01e987c7d32e274d8d060ef15276fae913a1ca0 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c @@ -643,7 +643,7 @@ static void read_buf_callback(struct urb *urb) static int iuu_bulk_write(struct usb_serial_port *port) { struct iuu_private *priv = usb_get_serial_port_data(port); - unsigned int flags; + unsigned long flags; int result; int i; char *buf_ptr = port->write_urb->transfer_buffer; @@ -694,7 +694,7 @@ static void iuu_uart_read_callback(struct urb *urb) { struct usb_serial_port *port = urb->context; struct iuu_private *priv = usb_get_serial_port_data(port); - unsigned int flags; + unsigned long flags; int status; int error = 0; int len = 0; @@ -759,7 +759,7 @@ static int iuu_uart_write(struct usb_serial_port *port, const u8 *buf, int count) { struct iuu_private *priv = usb_get_serial_port_data(port); - unsigned int flags; + unsigned long flags; dbg("%s - enter", __func__); if (count > 256) diff --git a/drivers/usb/serial/moto_modem.c b/drivers/usb/serial/moto_modem.c new file mode 100644 index 0000000000000000000000000000000000000000..2e8e05462ef7ab360d3f5c00044c98aca7d09e09 --- /dev/null +++ b/drivers/usb/serial/moto_modem.c @@ -0,0 +1,70 @@ +/* + * Motorola USB Phone driver + * + * Copyright (C) 2008 Greg Kroah-Hartman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * {sigh} + * Mororola should be using the CDC ACM USB spec, but instead + * they try to just "do their own thing"... This driver should handle a + * few phones in which a basic "dumb serial connection" is needed to be + * able to get a connection through to them. + */ + +#include +#include +#include +#include +#include +#include + +static struct usb_device_id id_table [] = { + { USB_DEVICE(0x05c6, 0x3197) }, /* unknown Motorola phone */ + { USB_DEVICE(0x0c44, 0x0022) }, /* unknown Mororola phone */ + { USB_DEVICE(0x22b8, 0x2a64) }, /* Motorola KRZR K1m */ + { }, +}; +MODULE_DEVICE_TABLE(usb, id_table); + +static struct usb_driver moto_driver = { + .name = "moto-modem", + .probe = usb_serial_probe, + .disconnect = usb_serial_disconnect, + .id_table = id_table, + .no_dynamic_id = 1, +}; + +static struct usb_serial_driver moto_device = { + .driver = { + .owner = THIS_MODULE, + .name = "moto-modem", + }, + .id_table = id_table, + .num_ports = 1, +}; + +static int __init moto_init(void) +{ + int retval; + + retval = usb_serial_register(&moto_device); + if (retval) + return retval; + retval = usb_register(&moto_driver); + if (retval) + usb_serial_deregister(&moto_device); + return retval; +} + +static void __exit moto_exit(void) +{ + usb_deregister(&moto_driver); + usb_serial_deregister(&moto_device); +} + +module_init(moto_init); +module_exit(moto_exit); +MODULE_LICENSE("GPL"); diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index e4be2d442b1ebbc6ea3bca507e85d4905d4f526f..e7e016e60333a481190cbddcb6abc38671f398e9 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -154,8 +154,6 @@ static int option_send_setup(struct usb_serial_port *port); #define NOVATELWIRELESS_PRODUCT_MC727 0x4100 #define NOVATELWIRELESS_PRODUCT_MC950D 0x4400 -#define NOVATELWIRELESS_PRODUCT_U727 0x5010 - /* FUTURE NOVATEL PRODUCTS */ #define NOVATELWIRELESS_PRODUCT_EVDO_1 0x6000 #define NOVATELWIRELESS_PRODUCT_HSPA_1 0x7000 @@ -184,6 +182,9 @@ static int option_send_setup(struct usb_serial_port *port); #define AXESSTEL_VENDOR_ID 0x1726 #define AXESSTEL_PRODUCT_MV110H 0x1000 +#define ONDA_VENDOR_ID 0x19d2 +#define ONDA_PRODUCT_ET502HS 0x0002 + #define BANDRICH_VENDOR_ID 0x1A8D #define BANDRICH_PRODUCT_C100_1 0x1002 #define BANDRICH_PRODUCT_C100_2 0x1003 @@ -269,7 +270,6 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU870D) }, /* Novatel EU850D/EU860D/EU870D */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC950D) }, /* Novatel MC930D/MC950D */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727) }, /* Novatel MC727/U727/USB727 */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U727) }, /* Novatel U727 */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_1) }, /* Novatel EVDO product */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_1) }, /* Novatel HSPA product */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EMBEDDED_1) }, /* Novatel Embedded product */ @@ -293,14 +293,17 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(DELL_VENDOR_ID, 0x8133) }, /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */ { USB_DEVICE(DELL_VENDOR_ID, 0x8136) }, /* Dell Wireless HSDPA 5520 == Novatel Expedite EU860D */ { USB_DEVICE(DELL_VENDOR_ID, 0x8137) }, /* Dell Wireless HSDPA 5520 */ + { USB_DEVICE(DELL_VENDOR_ID, 0x8138) }, /* Dell Wireless 5520 Voda I Mobile Broadband (3G HSDPA) Minicard */ { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, { USB_DEVICE(AXESSTEL_VENDOR_ID, AXESSTEL_PRODUCT_MV110H) }, + { USB_DEVICE(ONDA_VENDOR_ID, ONDA_PRODUCT_ET502HS) }, { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) }, { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) }, { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ { USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */ + { USB_DEVICE(0x19d2, 0x0001) }, /* Telstra NextG CDMA */ { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, option_ids); diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index a0ed889230aa324124575307151d34a6ceb9d09e..1b09578cbb1071b8d210471bb216bd8c519e9136 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -401,6 +401,14 @@ UNUSUAL_DEV( 0x04a5, 0x3010, 0x0100, 0x0100, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_IGNORE_RESIDUE ), +#ifdef CONFIG_USB_STORAGE_CYPRESS_ATACB +UNUSUAL_DEV( 0x04b4, 0x6830, 0x0000, 0x9999, + "Cypress", + "Cypress AT2LP", + US_SC_CYP_ATACB, US_PR_BULK, NULL, + 0), +#endif + /* Reported by Simon Levitt * This entry needs Sub and Proto fields */ UNUSUAL_DEV( 0x04b8, 0x0601, 0x0100, 0x0100, @@ -539,17 +547,6 @@ UNUSUAL_DEV( 0x04e6, 0x0101, 0x0200, 0x0200, "CD-RW Device", US_SC_8020, US_PR_CB, NULL, 0), -/* Entry and supporting patch by Theodore Kilgore . - * Device uses standards-violating 32-byte Bulk Command Block Wrappers and - * reports itself as "Proprietary SCSI Bulk." Cf. device entry 0x084d:0x0011. - */ - -UNUSUAL_DEV( 0x04fc, 0x80c2, 0x0100, 0x0100, - "Kobian Mercury", - "Binocam DCB-132", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_BULK32), - #ifdef CONFIG_USB_STORAGE_USBAT UNUSUAL_DEV( 0x04e6, 0x1010, 0x0000, 0x9999, "Shuttle/SCM", @@ -565,6 +562,16 @@ UNUSUAL_DEV( 0x04e8, 0x507c, 0x0220, 0x0220, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_MAX_SECTORS_64), +/* Entry and supporting patch by Theodore Kilgore . + * Device uses standards-violating 32-byte Bulk Command Block Wrappers and + * reports itself as "Proprietary SCSI Bulk." Cf. device entry 0x084d:0x0011. + */ +UNUSUAL_DEV( 0x04fc, 0x80c2, 0x0100, 0x0100, + "Kobian Mercury", + "Binocam DCB-132", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_BULK32), + /* Reported by Bob Sass -- only rev 1.33 tested */ UNUSUAL_DEV( 0x050d, 0x0115, 0x0133, 0x0133, "Belkin", @@ -1304,6 +1311,16 @@ UNUSUAL_DEV( 0x0ace, 0x20ff, 0x0101, 0x0101, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_IGNORE_DEVICE ), +/* Reported by F. Aben + * This device (wrongly) has a vendor-specific device descriptor. + * The entry is needed so usb-storage can bind to it's mass-storage + * interface as an interface driver */ +UNUSUAL_DEV( 0x0af0, 0x7401, 0x0000, 0x0000, + "Option", + "GI 0401 SD-Card", + US_SC_DEVICE, US_PR_DEVICE, NULL, + 0 ), + #ifdef CONFIG_USB_STORAGE_ISD200 UNUSUAL_DEV( 0x0bf6, 0xa001, 0x0100, 0x0110, "ATI", @@ -1361,13 +1378,6 @@ UNUSUAL_DEV( 0x0d96, 0x410a, 0x0001, 0xffff, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY), -/* Reported by Rohan Hart */ -UNUSUAL_DEV( 0x2770, 0x915d, 0x0010, 0x0010, - "INTOVA", - "Pixtreme", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_FIX_CAPACITY ), - /* * Entry for Jenoptik JD 5200z3 * @@ -1684,6 +1694,16 @@ UNUSUAL_DEV( 0x1652, 0x6600, 0x0201, 0x0201, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_IGNORE_RESIDUE ), +/* Reported by Mauro Andreolini + * This entry is needed to bypass the ZeroCD mechanism + * and to properly load as a modem device. + */ +UNUSUAL_DEV( 0x19d2, 0x2000, 0x0000, 0x0000, + "Onda ET502HS", + "USB MMC Storage", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_IGNORE_DEVICE), + /* patch submitted by Davide Perini * and Renato Perini */ @@ -1721,6 +1741,13 @@ UNUSUAL_DEV( 0x2735, 0x100b, 0x0000, 0x9999, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_GO_SLOW ), +/* Reported by Rohan Hart */ +UNUSUAL_DEV( 0x2770, 0x915d, 0x0010, 0x0010, + "INTOVA", + "Pixtreme", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY ), + /* * David Härdeman * The key makes the SCSI stack print confusing (but harmless) messages @@ -1745,14 +1772,6 @@ UNUSUAL_DEV( 0xed06, 0x4500, 0x0001, 0x0001, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_CAPACITY_HEURISTICS), -#ifdef CONFIG_USB_STORAGE_CYPRESS_ATACB -UNUSUAL_DEV( 0x04b4, 0x6830, 0x0000, 0x9999, - "Cypress", - "Cypress AT2LP", - US_SC_CYP_ATACB, US_PR_BULK, NULL, - 0), -#endif - /* Control/Bulk transport for all SubClass values */ USUAL_DEV(US_SC_RBC, US_PR_CB, USB_US_TYPE_STOR), USUAL_DEV(US_SC_8020, US_PR_CB, USB_US_TYPE_STOR), diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index bb1dadaa4a23a1054cca3fbd56791d3cf50fcb1d..002b61b4f0f6d9fba9c48a9f3216068f816b9ce4 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -171,7 +171,6 @@ config FB_SYS_FOPS config FB_DEFERRED_IO bool depends on FB - default y config FB_METRONOME tristate @@ -628,11 +627,9 @@ config FB_MAC select FB_CFB_IMAGEBLIT select FB_MACMODES -# bool ' Apple DAFB display support' CONFIG_FB_DAFB config FB_HP300 bool - depends on (FB = y) && HP300 - select FB_CFB_FILLRECT + depends on (FB = y) && DIO select FB_CFB_IMAGEBLIT default y diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c index e6492c1048bf29dcb367f696a7abaee9c6403055..05a328c11a8bf17b7bd6178841caf546644c1639 100644 --- a/drivers/video/amifb.c +++ b/drivers/video/amifb.c @@ -2261,7 +2261,7 @@ int __init amifb_init(void) amifb_setup(option); #endif if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(AMI_VIDEO)) - return -ENXIO; + return -ENODEV; /* * We request all registers starting from bplpt[0] @@ -2333,7 +2333,7 @@ default_chipset: strcat(fb_info.fix.id, "Unknown"); goto default_chipset; #else /* CONFIG_FB_AMIGA_OCS */ - err = -ENXIO; + err = -ENODEV; goto amifb_error; #endif /* CONFIG_FB_AMIGA_OCS */ break; diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index 8ffdf35787688084deced4c51cd8704bb92f4c19..b004036d40873aec5a5c8905a626722ab8b29533 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c @@ -441,14 +441,15 @@ static int atmel_lcdfb_set_par(struct fb_info *info) value = DIV_ROUND_UP(clk_value_khz, PICOS2KHZ(info->var.pixclock)); - value = (value / 2) - 1; - dev_dbg(info->device, " * programming CLKVAL = 0x%08lx\n", value); - - if (value <= 0) { + if (value < 2) { dev_notice(info->device, "Bypassing pixel clock divider\n"); lcdc_writel(sinfo, ATMEL_LCDC_LCDCON1, ATMEL_LCDC_BYPASS); } else { - lcdc_writel(sinfo, ATMEL_LCDC_LCDCON1, value << ATMEL_LCDC_CLKVAL_OFFSET); + value = (value / 2) - 1; + dev_dbg(info->device, " * programming CLKVAL = 0x%08lx\n", + value); + lcdc_writel(sinfo, ATMEL_LCDC_LCDCON1, + value << ATMEL_LCDC_CLKVAL_OFFSET); info->var.pixclock = KHZ2PICOS(clk_value_khz / (2 * (value + 1))); dev_dbg(info->device, " updated pixclk: %lu KHz\n", PICOS2KHZ(info->var.pixclock)); diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c index 275d9dab0c6108e2f56b73c6bb5d2da1d3fdedc2..e721644bad743c27313b4d78db17b3f87a10de94 100644 --- a/drivers/video/bw2.c +++ b/drivers/video/bw2.c @@ -17,11 +17,9 @@ #include #include #include +#include #include -#include -#include -#include #include #include "sbuslib.h" @@ -299,7 +297,7 @@ static int __devinit bw2_probe(struct of_device *op, const struct of_device_id * par->physbase = op->resource[0].start; par->which_io = op->resource[0].flags & IORESOURCE_BITS; - sbusfb_fill_var(&info->var, dp->node, 1); + sbusfb_fill_var(&info->var, dp, 1); linebytes = of_getintprop_default(dp, "linebytes", info->var.xres); @@ -329,7 +327,7 @@ static int __devinit bw2_probe(struct of_device *op, const struct of_device_id * if (!info->screen_base) goto out_unmap_regs; - bw2_blank(0, info); + bw2_blank(FB_BLANK_UNBLANK, info); bw2_init_fix(info, linebytes); diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c index 0db0fecba93b6718af12b5af3b053333c6783496..b17e746717795615dc71a710abb801e9920eef7b 100644 --- a/drivers/video/cg14.c +++ b/drivers/video/cg14.c @@ -17,10 +17,9 @@ #include #include #include +#include #include -#include -#include #include #include "sbuslib.h" @@ -482,7 +481,7 @@ static int __devinit cg14_probe(struct of_device *op, const struct of_device_id spin_lock_init(&par->lock); - sbusfb_fill_var(&info->var, dp->node, 8); + sbusfb_fill_var(&info->var, dp, 8); info->var.red.length = 8; info->var.green.length = 8; info->var.blue.length = 8; diff --git a/drivers/video/cg3.c b/drivers/video/cg3.c index 010ea53978f822cdc7cafd9dce2f85c7ec9054b5..3aa7b6cb0268591283b72f77425344be184d1420 100644 --- a/drivers/video/cg3.c +++ b/drivers/video/cg3.c @@ -17,11 +17,9 @@ #include #include #include +#include #include -#include -#include -#include #include #include "sbuslib.h" @@ -373,7 +371,7 @@ static int __devinit cg3_probe(struct of_device *op, par->physbase = op->resource[0].start; par->which_io = op->resource[0].flags & IORESOURCE_BITS; - sbusfb_fill_var(&info->var, dp->node, 8); + sbusfb_fill_var(&info->var, dp, 8); info->var.red.length = 8; info->var.green.length = 8; info->var.blue.length = 8; @@ -398,7 +396,7 @@ static int __devinit cg3_probe(struct of_device *op, if (!info->screen_base) goto out_unmap_regs; - cg3_blank(0, info); + cg3_blank(FB_BLANK_UNBLANK, info); if (!of_find_property(dp, "width", NULL)) { err = cg3_do_default_mode(par); diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c index fc90db6da65a94267e8e2e8f22865b5843abdabb..2f64bb3bd2540e7f5c77c03e7d5894578ddad572 100644 --- a/drivers/video/cg6.c +++ b/drivers/video/cg6.c @@ -17,9 +17,9 @@ #include #include #include +#include #include -#include #include #include "sbuslib.h" @@ -728,7 +728,7 @@ static int __devinit cg6_probe(struct of_device *op, par->physbase = op->resource[0].start; par->which_io = op->resource[0].flags & IORESOURCE_BITS; - sbusfb_fill_var(&info->var, dp->node, 8); + sbusfb_fill_var(&info->var, dp, 8); info->var.red.length = 8; info->var.green.length = 8; info->var.blue.length = 8; @@ -767,7 +767,7 @@ static int __devinit cg6_probe(struct of_device *op, cg6_bt_init(par); cg6_chip_init(info); - cg6_blank(0, info); + cg6_blank(FB_BLANK_UNBLANK, info); if (fb_alloc_cmap(&info->cmap, 256, 0)) goto out_unmap_regs; diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index ad31983b43eb6a169a100b2846e96f1554e32b1b..5fa8b76673cb5c07de0066c6f6577434e13b86fc 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -1853,6 +1853,8 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; struct display *p = &fb_display[vc->vc_num]; int scroll_partial = info->flags & FBINFO_PARTIAL_PAN_OK; + unsigned short saved_ec; + int ret; if (fbcon_is_inactive(vc, info)) return -EINVAL; @@ -1865,6 +1867,11 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, * whole screen (prevents flicker). */ + saved_ec = vc->vc_video_erase_char; + vc->vc_video_erase_char = vc->vc_scrl_erase_char; + + ret = 0; + switch (dir) { case SM_UP: if (count > vc->vc_rows) /* Maximum realistic size */ @@ -1883,7 +1890,7 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, (b - count)), vc->vc_scrl_erase_char, vc->vc_size_row * count); - return 1; + ret = 1; break; case SCROLL_WRAP_MOVE: @@ -1955,7 +1962,8 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, (b - count)), vc->vc_scrl_erase_char, vc->vc_size_row * count); - return 1; + ret = 1; + break; } break; @@ -1974,7 +1982,7 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, t), vc->vc_scrl_erase_char, vc->vc_size_row * count); - return 1; + ret = 1; break; case SCROLL_WRAP_MOVE: @@ -2044,10 +2052,13 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, t), vc->vc_scrl_erase_char, vc->vc_size_row * count); - return 1; + ret = 1; + break; } + break; } - return 0; + vc->vc_video_erase_char = saved_ec; + return ret; } @@ -2507,6 +2518,9 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, c = vc->vc_video_erase_char; vc->vc_video_erase_char = ((c & 0xfe00) >> 1) | (c & 0xff); + c = vc->vc_def_color; + vc->vc_scrl_erase_char = + ((c & 0xFE00) >> 1) | (c & 0xFF); vc->vc_attr >>= 1; } } else if (!vc->vc_hi_font_mask && cnt == 512) { @@ -2537,9 +2551,14 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, if (vc->vc_can_do_color) { vc->vc_video_erase_char = ((c & 0xff00) << 1) | (c & 0xff); + c = vc->vc_def_color; + vc->vc_scrl_erase_char = + ((c & 0xFF00) << 1) | (c & 0xFF); vc->vc_attr <<= 1; - } else + } else { vc->vc_video_erase_char = c & ~0x100; + vc->vc_scrl_erase_char = c & ~0x100; + } } } diff --git a/drivers/video/dnfb.c b/drivers/video/dnfb.c index b083ea7e9c69e6c1ea45e0ce84f34c75958678ab..606da043f4b479cd46c31f1778a7a1272dc4d872 100644 --- a/drivers/video/dnfb.c +++ b/drivers/video/dnfb.c @@ -284,6 +284,9 @@ int __init dnfb_init(void) { int ret; + if (!MACH_IS_APOLLO) + return -ENODEV; + if (fb_get_options("dnfb", NULL)) return -ENODEV; diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c index 93dca3e2aa502d7537aca3fbae7069af80b4f6eb..7992b13ee68fcac9a60840b0e17a9a3581e6713c 100644 --- a/drivers/video/ffb.c +++ b/drivers/video/ffb.c @@ -16,11 +16,10 @@ #include #include #include +#include #include #include -#include -#include #include #include "sbuslib.h" @@ -941,7 +940,7 @@ static int __devinit ffb_probe(struct of_device *op, info->screen_base = (char *) par->physbase + FFB_DFB24_POFF; info->pseudo_palette = par->pseudo_palette; - sbusfb_fill_var(&info->var, dp->node, 32); + sbusfb_fill_var(&info->var, dp, 32); par->fbsize = PAGE_ALIGN(info->var.xres * info->var.yres * 4); ffb_fixup_var_rgb(&info->var); @@ -987,7 +986,7 @@ static int __devinit ffb_probe(struct of_device *op, * chosen console, it will have video outputs off in * the DAC. */ - ffb_blank(0, info); + ffb_blank(FB_BLANK_UNBLANK, info); if (fb_alloc_cmap(&info->cmap, 256, 0)) goto out_unmap_dac; diff --git a/drivers/video/geode/lxfb_ops.c b/drivers/video/geode/lxfb_ops.c index cd9d4cc269549932008ac90ee9a37a744312941d..aaef9165ec9bf09f8dcb00dc71a61b29b47a647f 100644 --- a/drivers/video/geode/lxfb_ops.c +++ b/drivers/video/geode/lxfb_ops.c @@ -63,54 +63,32 @@ static const struct { { 0x00014284, 19688 }, { 0x00011104, 20400 }, { 0x00016363, 23625 }, - { 0x00015303, 24380 }, { 0x000031AC, 24923 }, { 0x0000215D, 25175 }, { 0x00001087, 27000 }, { 0x0000216C, 28322 }, { 0x0000218D, 28560 }, - { 0x00010041, 29913 }, { 0x000010C9, 31200 }, { 0x00003147, 31500 }, - { 0x000141A1, 32400 }, { 0x000010A7, 33032 }, - { 0x00012182, 33375 }, - { 0x000141B1, 33750 }, { 0x00002159, 35112 }, { 0x00004249, 35500 }, { 0x00000057, 36000 }, - { 0x000141E1, 37125 }, { 0x0000219A, 37889 }, { 0x00002158, 39168 }, { 0x00000045, 40000 }, - { 0x000131A1, 40500 }, - { 0x00010061, 42301 }, { 0x00000089, 43163 }, - { 0x00012151, 43875 }, { 0x000010E7, 44900 }, { 0x00002136, 45720 }, - { 0x000152E1, 47250 }, - { 0x00010071, 48000 }, { 0x00003207, 49500 }, { 0x00002187, 50000 }, - { 0x00014291, 50625 }, - { 0x00011101, 51188 }, - { 0x00017481, 54563 }, { 0x00004286, 56250 }, - { 0x00014170, 57375 }, - { 0x00016210, 58500 }, { 0x000010E5, 60065 }, - { 0x00013140, 62796 }, { 0x00004214, 65000 }, - { 0x00016250, 65250 }, { 0x00001105, 68179 }, - { 0x000141C0, 69600 }, - { 0x00015220, 70160 }, - { 0x00010050, 72000 }, { 0x000031E4, 74250 }, { 0x00003183, 75000 }, { 0x00004284, 78750 }, - { 0x00012130, 80052 }, { 0x00001104, 81600 }, { 0x00006363, 94500 }, { 0x00005303, 97520 }, diff --git a/drivers/video/hpfb.c b/drivers/video/hpfb.c index 2eb4fb15908404e8926d6342b88faed3d64d180b..b8ebff1e8493e2290b21530ad5086b5d55172089 100644 --- a/drivers/video/hpfb.c +++ b/drivers/video/hpfb.c @@ -382,7 +382,7 @@ int __init hpfb_init(void) #define INTFBPADDR 0x560000 if (!MACH_IS_HP300) - return -ENXIO; + return -ENODEV; if (fb_get_options("hpfb", NULL)) return -ENODEV; diff --git a/drivers/video/leo.c b/drivers/video/leo.c index f3160fc29795354a680e13d5a576876f70b42af7..8bc46e9303402da0b78211d433f38949d4d687e1 100644 --- a/drivers/video/leo.c +++ b/drivers/video/leo.c @@ -16,10 +16,9 @@ #include #include #include +#include #include -#include -#include #include #include "sbuslib.h" @@ -562,7 +561,7 @@ static int __devinit leo_probe(struct of_device *op, const struct of_device_id * par->physbase = op->resource[0].start; par->which_io = op->resource[0].flags & IORESOURCE_BITS; - sbusfb_fill_var(&info->var, dp->node, 32); + sbusfb_fill_var(&info->var, dp, 32); leo_fixup_var_rgb(&info->var); linebytes = of_getintprop_default(dp, "linebytes", @@ -601,7 +600,7 @@ static int __devinit leo_probe(struct of_device *op, const struct of_device_id * leo_init_wids(info); leo_init_hw(info); - leo_blank(0, info); + leo_blank(FB_BLANK_UNBLANK, info); if (fb_alloc_cmap(&info->cmap, 256, 0)) goto out_unmap_regs; diff --git a/drivers/video/logo/Kconfig b/drivers/video/logo/Kconfig index 9de1c114f8092f095832ab520f01c48ce058f2ec..39ac49e0682ced1eef75c5e0b31426e4efe26975 100644 --- a/drivers/video/logo/Kconfig +++ b/drivers/video/logo/Kconfig @@ -27,6 +27,16 @@ config LOGO_LINUX_CLUT224 bool "Standard 224-color Linux logo" default y +config LOGO_BLACKFIN_VGA16 + bool "16-colour Blackfin Processor Linux logo" + depends on BLACKFIN + default y + +config LOGO_BLACKFIN_CLUT224 + bool "224-colour Blackfin Processor Linux logo" + depends on BLACKFIN + default y + config LOGO_DEC_CLUT224 bool "224-color Digital Equipment Corporation Linux logo" depends on MACH_DECSTATION || ALPHA diff --git a/drivers/video/logo/Makefile b/drivers/video/logo/Makefile index a5fc4edf84e6abc506ea099d3d635c90c6b27c9e..b91251d1fe41c9e254ebfb51320545754d45c305 100644 --- a/drivers/video/logo/Makefile +++ b/drivers/video/logo/Makefile @@ -4,6 +4,8 @@ obj-$(CONFIG_LOGO) += logo.o obj-$(CONFIG_LOGO_LINUX_MONO) += logo_linux_mono.o obj-$(CONFIG_LOGO_LINUX_VGA16) += logo_linux_vga16.o obj-$(CONFIG_LOGO_LINUX_CLUT224) += logo_linux_clut224.o +obj-$(CONFIG_LOGO_BLACKFIN_CLUT224) += logo_blackfin_clut224.o +obj-$(CONFIG_LOGO_BLACKFIN_VGA16) += logo_blackfin_vga16.o obj-$(CONFIG_LOGO_DEC_CLUT224) += logo_dec_clut224.o obj-$(CONFIG_LOGO_MAC_CLUT224) += logo_mac_clut224.o obj-$(CONFIG_LOGO_PARISC_CLUT224) += logo_parisc_clut224.o diff --git a/drivers/video/logo/logo.c b/drivers/video/logo/logo.c index fc72684aae5aae4328e67db391dcb2b62bdd4e8f..2e85a2b52d05feada5f9c7a056d8c2575f5c9ba1 100644 --- a/drivers/video/logo/logo.c +++ b/drivers/video/logo/logo.c @@ -24,6 +24,8 @@ extern const struct linux_logo logo_linux_mono; extern const struct linux_logo logo_linux_vga16; extern const struct linux_logo logo_linux_clut224; +extern const struct linux_logo logo_blackfin_vga16; +extern const struct linux_logo logo_blackfin_clut224; extern const struct linux_logo logo_dec_clut224; extern const struct linux_logo logo_mac_clut224; extern const struct linux_logo logo_parisc_clut224; @@ -65,6 +67,10 @@ const struct linux_logo * __init_refok fb_find_logo(int depth) /* Generic Linux logo */ logo = &logo_linux_vga16; #endif +#ifdef CONFIG_LOGO_BLACKFIN_VGA16 + /* Blackfin processor logo */ + logo = &logo_blackfin_vga16; +#endif #ifdef CONFIG_LOGO_SUPERH_VGA16 /* SuperH Linux logo */ logo = &logo_superh_vga16; @@ -76,6 +82,10 @@ const struct linux_logo * __init_refok fb_find_logo(int depth) /* Generic Linux logo */ logo = &logo_linux_clut224; #endif +#ifdef CONFIG_LOGO_BLACKFIN_CLUT224 + /* Blackfin Linux logo */ + logo = &logo_blackfin_clut224; +#endif #ifdef CONFIG_LOGO_DEC_CLUT224 /* DEC Linux logo on MIPS/MIPS64 or ALPHA */ logo = &logo_dec_clut224; diff --git a/drivers/video/logo/logo_blackfin_clut224.ppm b/drivers/video/logo/logo_blackfin_clut224.ppm new file mode 100644 index 0000000000000000000000000000000000000000..dc9a50a1447701a1c55368e5031669292beb5159 --- /dev/null +++ b/drivers/video/logo/logo_blackfin_clut224.ppm @@ -0,0 +1,1127 @@ +P3 +# This was generated by the GIMP & Netpbm tools +# gimp linux_bf.svg (create 80x80 save as linux_bf.ppm) +# pnmquant 224 linux_bf.ppm | pnmnoraw > logo_blackfin_clut224.ppm +# +80 80 +255 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +1 1 1 3 3 3 4 6 6 6 6 6 4 6 6 3 3 3 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 2 2 2 10 10 10 26 26 27 +44 44 45 66 66 66 78 81 81 78 81 81 75 75 76 60 60 60 +39 39 39 20 20 20 6 6 6 1 1 1 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 2 2 2 14 14 14 47 47 47 84 84 84 75 75 76 +47 47 47 12 12 12 0 0 0 0 0 0 0 0 0 20 20 20 +53 54 54 81 81 82 74 74 74 31 31 31 6 6 6 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +4 4 4 34 34 35 84 84 84 60 60 60 4 4 4 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 17 18 18 75 75 76 66 66 66 17 18 18 +1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 3 3 +42 42 43 84 84 84 8 8 8 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 3 3 36 40 40 10 16 16 0 0 0 31 31 31 84 84 84 +29 29 30 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 26 27 27 +84 84 84 3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +15 19 19 114 115 115 110 114 114 44 46 46 0 0 0 12 12 12 +90 87 86 24 24 24 1 1 1 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 8 8 8 75 75 76 +14 14 14 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +30 40 40 133 133 133 129 130 130 78 85 85 23 31 30 0 0 0 +19 19 19 78 81 81 13 13 13 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 26 27 27 81 81 82 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +36 40 40 89 90 91 55 63 63 23 31 30 4 6 6 0 0 0 +0 0 0 60 60 60 47 47 47 2 2 2 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 2 2 2 53 54 54 34 34 35 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +4 10 10 7 9 9 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 1 1 1 84 84 84 13 13 13 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 4 6 6 78 81 81 2 2 2 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 65 64 64 36 36 36 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 10 11 11 81 81 82 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 12 12 12 67 70 70 4 4 4 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 16 16 16 81 81 82 0 0 0 +0 0 0 0 0 0 4 10 10 44 50 50 18 21 21 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 1 1 78 85 85 120 121 122 7 9 9 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 82 82 81 12 12 12 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 19 19 19 81 81 82 0 0 0 +0 0 0 2 2 2 8 8 8 55 63 63 108 110 110 52 58 58 +0 0 0 0 0 0 0 0 0 0 0 0 42 42 43 129 130 130 +140 142 143 114 115 115 110 114 114 129 130 130 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 75 75 76 24 24 24 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 19 19 19 74 74 74 0 0 0 +4 6 6 167 168 167 196 196 197 196 196 197 61 65 66 78 85 85 +0 0 0 0 0 0 0 0 0 118 118 118 202 202 203 219 219 219 +219 219 219 214 214 215 187 187 188 78 85 85 29 33 34 0 0 0 +0 0 0 0 0 0 0 0 0 60 60 60 39 39 39 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 19 19 19 72 71 71 0 0 0 +185 185 184 244 245 245 250 251 252 251 251 252 247 248 249 36 36 36 +0 0 0 0 0 0 13 13 13 243 243 241 252 252 252 253 253 253 +253 253 253 252 252 252 247 247 246 193 193 194 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 42 42 43 50 51 51 1 1 1 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 19 19 19 78 81 81 0 0 0 +247 247 246 193 193 194 95 97 97 193 193 194 255 255 255 237 237 238 +0 0 0 0 0 0 202 202 203 255 255 255 247 247 246 108 107 107 +82 85 86 167 168 167 255 255 255 248 248 249 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 34 34 35 56 56 56 2 2 2 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 19 19 19 78 81 81 0 0 0 +250 250 251 50 51 51 153 154 155 150 151 151 244 245 245 244 245 245 +44 50 50 84 89 89 153 154 155 255 255 255 140 142 143 0 0 0 +149 149 150 156 155 156 237 237 238 254 254 254 67 70 70 0 0 0 +0 0 0 0 0 0 0 0 0 39 39 39 47 47 47 1 1 1 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 19 19 19 81 81 82 0 0 0 +248 248 249 34 34 35 72 71 71 165 165 165 202 202 203 244 245 245 +10 16 16 82 85 86 89 90 91 255 255 255 95 97 97 0 0 0 +0 0 0 53 54 54 177 177 174 255 255 255 127 127 126 0 0 0 +0 0 0 0 0 0 0 0 0 39 39 39 36 36 36 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 14 14 14 78 81 81 0 0 0 +243 243 243 89 90 91 0 0 0 36 40 40 201 147 55 241 205 27 +241 205 27 241 205 27 241 205 27 238 192 33 108 110 110 0 0 0 +0 0 0 0 0 0 191 190 190 254 254 254 34 34 35 0 0 0 +0 0 0 0 0 0 0 0 0 42 42 43 42 42 43 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 10 10 10 75 75 76 0 0 0 +202 202 203 218 217 217 21 19 17 230 165 41 199 129 48 213 157 40 +244 212 23 243 206 27 180 121 62 243 206 27 244 209 25 226 179 40 +15 10 7 103 103 103 254 254 254 251 251 252 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 17 18 18 58 58 58 2 2 2 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 9 9 9 84 84 84 0 0 0 +0 0 0 226 226 219 213 157 40 244 209 25 245 211 23 245 211 23 +245 214 38 245 214 38 245 211 23 245 211 23 245 211 23 244 212 23 +244 212 23 241 205 27 226 179 40 196 196 197 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 74 74 74 4 6 6 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 7 7 7 84 84 84 0 0 0 +54 42 32 213 157 40 243 206 27 245 211 23 245 211 23 245 211 23 +245 215 41 245 214 35 245 211 23 245 211 23 245 214 35 245 215 41 +245 214 35 245 211 23 245 211 23 238 204 29 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 81 81 82 12 12 12 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 4 6 6 74 74 74 0 0 0 +201 147 55 241 205 27 245 211 23 245 211 23 245 211 23 245 213 29 +245 214 38 245 211 23 245 211 23 245 214 35 245 215 41 245 215 41 +245 213 29 142 83 36 142 83 36 244 209 25 1 1 1 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 74 74 74 25 25 26 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 4 4 4 72 71 71 6 6 6 +213 157 40 244 209 25 245 211 23 245 211 23 245 211 23 245 213 29 +244 212 23 245 211 23 245 214 35 245 215 41 245 215 41 245 213 29 +142 83 36 142 83 36 238 192 33 241 205 27 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 44 44 44 49 50 50 +2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 3 3 3 65 64 64 17 18 18 +199 129 48 199 129 48 245 211 23 245 211 23 245 211 23 245 211 23 +245 211 23 244 212 23 245 214 38 245 214 38 142 83 36 142 83 36 +142 83 36 245 211 23 244 210 23 230 165 41 0 0 0 0 0 0 +78 81 81 114 115 115 73 79 79 0 0 0 3 3 3 81 81 82 +9 9 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 1 1 1 49 50 50 29 29 30 +90 87 86 199 129 48 173 101 51 173 101 51 245 211 23 245 211 23 +245 211 23 230 165 41 142 83 36 142 83 36 142 83 36 245 211 23 +244 210 23 241 205 27 230 165 41 175 173 165 3 3 3 0 0 0 +44 46 46 118 118 118 118 118 118 108 110 110 0 0 0 75 75 76 +28 28 28 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 1 1 1 52 53 53 26 26 27 +118 118 118 175 173 165 199 129 48 173 101 51 173 101 51 173 101 51 +173 101 51 142 83 36 173 101 51 245 211 23 244 209 25 238 204 29 +213 157 40 214 196 166 227 227 227 214 214 215 120 121 122 0 0 0 +0 0 0 108 110 110 118 118 118 118 118 118 0 0 0 23 23 23 +66 66 66 4 6 6 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 7 7 7 75 75 76 4 4 4 +127 127 126 205 205 205 181 181 181 199 129 48 226 179 40 244 209 25 +244 209 25 244 209 25 243 206 27 238 192 33 213 157 40 187 166 103 +234 234 234 248 248 249 251 252 252 248 248 249 214 214 215 0 0 0 +0 0 0 0 0 0 103 103 103 100 103 103 0 0 0 0 0 0 +78 81 81 24 24 24 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 26 27 27 82 82 81 0 0 0 +146 146 147 234 234 234 222 221 221 178 178 179 180 121 62 213 157 40 +213 157 40 213 157 40 201 147 55 180 121 62 219 219 219 243 243 241 +253 253 253 255 255 255 255 255 255 255 255 255 250 250 251 120 121 122 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +20 20 20 72 71 71 8 8 8 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 10 10 10 75 75 76 22 22 22 0 0 0 +205 205 205 253 253 253 247 248 249 212 211 212 178 178 179 161 161 162 +165 165 165 181 181 181 205 205 205 227 227 227 244 245 245 254 254 254 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 239 239 240 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 67 70 70 39 39 39 2 2 2 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 4 4 4 50 51 51 60 60 60 0 0 0 16 16 16 +249 250 251 255 255 255 255 255 255 240 240 240 209 210 210 193 193 194 +200 200 197 212 211 212 231 231 231 246 247 248 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 253 253 253 +153 154 155 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 3 3 3 84 84 84 20 20 20 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +2 2 2 33 33 34 81 81 82 0 0 0 0 0 0 231 231 231 +255 255 255 255 255 255 255 255 255 253 253 253 234 234 234 222 221 221 +227 227 227 237 237 238 250 250 251 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +240 240 240 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 26 27 27 72 71 71 8 8 8 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 +21 21 22 84 84 84 7 7 7 0 0 0 150 151 151 252 252 252 +255 255 255 255 255 255 255 255 255 255 255 255 252 252 252 244 245 245 +246 247 248 253 253 253 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +251 251 252 9 9 9 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 65 64 64 47 47 47 3 3 3 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 12 12 +75 75 76 26 26 27 0 0 0 1 1 1 239 239 240 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 202 202 203 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 84 84 84 28 28 29 +1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 4 4 4 55 55 55 +60 60 60 0 0 0 0 0 0 95 97 97 248 248 249 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 244 245 245 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 14 14 14 82 82 81 +15 15 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 1 1 1 29 29 30 84 84 84 +0 0 0 0 0 0 0 0 0 156 155 156 247 247 246 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 247 247 246 240 240 240 232 232 233 232 232 233 +243 243 243 253 253 253 53 54 54 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 44 44 44 +60 60 60 6 6 6 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 10 10 10 81 81 82 14 14 14 +0 0 0 0 0 0 6 6 6 150 151 151 214 214 215 250 251 252 +255 255 255 255 255 255 255 255 255 246 247 248 218 217 217 214 214 215 +218 217 217 244 245 245 255 255 255 255 255 255 255 255 255 250 248 249 +232 232 233 214 214 215 196 196 197 182 183 184 181 181 181 181 181 181 +187 187 188 240 240 240 232 232 233 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +78 81 81 34 34 35 1 1 1 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 1 1 1 39 39 39 74 74 74 0 0 0 +0 0 0 0 0 0 60 60 60 161 161 162 200 200 197 229 229 230 +251 251 252 255 255 255 255 255 255 255 255 255 243 243 241 214 214 215 +248 248 249 255 255 255 255 255 255 255 255 255 255 255 255 254 254 254 +239 239 240 214 214 215 193 193 194 182 183 184 178 178 179 176 177 177 +176 177 177 182 183 184 248 248 249 14 14 14 0 0 0 61 65 66 +10 16 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +10 10 10 84 84 84 13 13 13 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 10 11 11 82 82 81 7 7 7 0 0 0 +0 0 0 0 0 0 165 165 165 229 229 230 249 250 251 254 254 254 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 253 253 253 240 240 240 227 227 227 205 205 205 +181 181 181 176 177 177 191 190 190 227 227 227 0 0 0 44 50 50 +84 89 89 61 65 66 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 58 58 58 49 50 50 3 3 3 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 1 1 1 36 36 36 66 66 66 0 0 0 29 33 34 +0 3 3 26 27 27 234 234 234 254 254 254 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +254 254 254 253 253 254 252 253 253 253 253 254 253 254 254 253 254 254 +254 254 254 255 255 255 255 255 255 255 255 255 255 255 255 251 251 252 +227 227 227 187 187 188 176 177 177 222 221 221 13 13 13 0 0 0 +12 15 14 73 79 79 36 40 40 0 0 0 0 0 0 0 0 0 +0 0 0 1 1 1 90 87 86 17 18 18 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 7 7 7 78 81 81 12 12 12 23 31 30 52 58 58 +0 0 0 209 210 210 253 253 253 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 254 254 254 +251 251 252 150 151 151 103 103 103 129 130 130 196 196 197 250 250 251 +252 252 253 254 254 254 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 240 240 240 193 193 194 196 196 197 229 229 230 0 0 0 +0 0 0 4 10 10 30 40 40 0 3 3 0 0 0 0 0 0 +0 0 0 0 0 0 47 47 47 53 54 54 3 3 3 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 23 23 23 81 81 82 0 0 0 52 58 58 36 40 40 +42 42 43 250 250 251 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 254 254 254 +227 227 227 7 7 7 7 7 7 7 7 7 7 7 7 44 44 45 +156 155 156 249 250 251 253 253 253 254 254 254 255 255 255 255 255 255 +255 255 255 255 255 255 247 247 246 222 221 221 239 239 240 0 0 0 +30 40 40 44 50 50 23 31 30 29 33 34 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 90 87 86 16 16 16 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +2 2 2 50 51 51 42 42 43 29 33 34 52 58 58 0 0 0 +232 232 233 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 254 254 254 +250 251 252 44 44 44 7 7 7 7 7 7 7 7 7 7 7 7 +7 7 7 56 56 56 209 210 210 252 252 253 254 254 254 255 255 255 +255 255 255 255 255 255 255 255 255 254 253 253 249 250 251 146 146 147 +36 40 40 44 50 50 36 40 40 67 70 70 61 65 66 0 0 0 +0 0 0 0 0 0 0 0 0 55 55 55 44 44 45 1 1 1 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +10 10 10 81 81 82 1 1 1 52 58 58 44 50 50 52 53 53 +251 251 252 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 254 254 254 +253 253 253 187 187 188 8 8 8 7 7 7 7 7 7 7 7 7 +7 7 7 7 7 7 19 19 19 178 178 179 252 252 253 254 254 254 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 237 237 238 +10 16 16 30 40 40 0 3 3 23 31 30 84 89 89 0 0 0 +0 0 0 0 0 0 0 0 0 3 3 3 81 81 82 9 9 9 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +29 29 30 72 71 71 10 16 16 52 58 58 0 0 0 222 221 221 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +254 254 254 251 251 252 95 97 97 7 7 7 7 7 7 7 7 7 +7 7 7 7 7 7 7 7 7 10 10 10 161 161 162 251 252 252 +254 254 254 255 255 255 255 255 255 255 255 255 255 255 255 248 248 249 +0 0 0 0 0 0 0 0 0 0 0 0 84 89 89 0 3 3 +0 0 0 0 0 0 0 0 0 0 0 0 74 74 74 26 27 27 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 4 +65 64 64 20 20 20 20 25 25 30 40 40 0 0 0 247 247 246 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 253 253 254 222 221 221 9 9 9 7 7 7 7 7 7 +7 7 7 7 7 7 7 7 7 7 7 7 8 8 8 149 149 150 +252 252 253 254 254 254 255 255 255 255 255 255 255 255 255 252 252 252 +0 0 0 0 0 0 0 0 0 0 0 0 73 79 79 12 15 14 +0 0 0 0 0 0 0 0 0 0 0 0 36 36 36 58 58 58 +3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 20 20 20 +74 74 74 0 0 0 4 10 10 4 10 10 36 36 36 252 252 252 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 227 227 227 253 253 253 255 255 255 +255 255 255 254 254 254 250 251 252 65 64 64 7 7 7 7 7 7 +7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 8 8 8 +146 146 147 251 252 252 254 254 254 255 255 255 255 255 255 253 254 254 +0 0 0 0 0 0 0 0 0 0 0 0 52 58 58 10 16 16 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 82 82 81 +9 9 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 4 6 6 65 64 64 +25 25 25 0 3 3 30 40 40 0 0 0 187 187 188 254 254 254 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 193 193 194 253 252 252 255 255 255 +255 255 255 255 255 255 252 253 253 129 130 130 7 7 7 7 7 7 +7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 +8 8 8 149 149 150 252 252 253 254 254 254 255 255 255 254 254 254 +52 53 53 0 0 0 0 0 0 0 0 0 20 25 25 2 5 4 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 81 81 82 +20 20 20 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 26 26 27 81 81 82 +0 0 0 18 21 21 73 79 79 0 0 0 237 237 238 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 182 183 184 255 255 255 255 255 255 +255 255 255 255 255 255 253 253 253 176 177 177 7 7 7 7 7 7 +7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 +7 7 7 8 8 8 153 154 155 251 252 252 254 254 254 255 255 255 +150 151 151 0 0 0 0 0 0 0 0 0 20 25 25 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 65 64 64 +33 33 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 6 6 6 67 70 70 20 20 20 +0 0 0 23 31 30 82 85 86 0 0 0 247 247 246 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 182 183 184 255 255 255 255 255 255 +255 255 255 255 255 255 253 254 254 214 214 215 7 7 7 7 7 7 +7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 +7 7 7 7 7 7 8 8 8 156 155 156 252 252 253 254 254 254 +167 168 167 0 0 0 0 0 0 0 0 0 67 70 70 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 47 47 47 +44 44 44 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 21 21 22 75 75 76 0 0 0 +0 0 0 29 33 34 84 89 89 0 0 0 248 248 249 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 248 248 249 181 181 181 255 255 255 255 255 255 +255 255 255 255 255 255 254 254 254 240 240 240 7 7 7 7 7 7 +7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 +7 7 7 7 7 7 7 7 7 8 8 8 161 161 162 251 252 252 +185 185 184 4 4 4 0 0 0 10 11 11 100 103 103 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 36 36 36 +55 55 55 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 33 33 34 50 51 51 0 0 0 +0 0 0 9 11 11 82 85 86 10 16 16 248 248 249 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 245 244 245 179 180 181 255 255 255 255 255 255 +255 255 255 255 255 255 254 254 254 251 252 252 20 20 20 7 7 7 +7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 +7 7 7 7 7 7 7 7 7 7 7 7 10 10 10 161 161 162 +205 205 205 17 18 18 0 0 0 95 97 97 78 81 81 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 36 36 36 +53 54 54 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 31 31 31 58 58 58 0 0 0 +0 0 0 0 0 0 67 70 70 78 81 81 248 248 249 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 234 234 234 179 180 181 255 255 255 255 255 255 +255 255 255 255 255 255 254 254 254 251 252 252 23 23 23 7 7 7 +7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 +10 11 11 84 84 84 161 161 162 209 210 210 229 229 230 237 237 238 +202 202 203 26 26 27 9 11 11 44 50 50 0 0 0 4 6 6 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 52 53 53 +39 39 39 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 23 23 23 78 81 81 213 157 40 +243 206 27 243 206 27 54 42 32 73 79 79 222 221 221 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 238 238 236 178 178 179 255 255 255 255 255 255 +255 255 255 255 255 255 254 254 254 251 252 253 36 36 36 7 7 7 +7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 84 84 84 +222 221 221 251 252 252 252 253 253 253 253 253 253 254 254 252 252 253 +146 146 147 140 142 143 156 155 156 110 114 114 26 27 27 82 85 86 +84 89 89 95 97 97 36 40 40 0 0 0 0 0 0 74 74 74 +23 23 23 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 14 14 14 +24 24 24 26 26 27 26 26 27 26 26 27 25 25 26 21 21 22 +7 7 7 0 0 0 1 1 1 34 34 35 238 192 33 244 210 23 +244 212 23 244 212 23 244 210 23 88 79 47 200 200 197 254 254 254 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 244 245 245 179 180 181 255 255 255 255 255 255 +255 255 255 255 255 255 254 254 254 252 252 253 36 36 36 7 7 7 +7 7 7 7 7 7 7 7 7 8 8 8 149 149 150 251 251 252 +252 252 253 253 253 253 253 253 253 250 248 249 239 223 156 239 223 156 +120 121 122 182 183 184 176 177 177 120 121 122 33 33 34 3 3 3 +0 0 0 67 70 70 146 146 147 20 25 25 1 1 1 82 82 81 +9 9 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 19 19 19 89 90 91 +146 146 147 150 151 151 150 151 151 150 151 151 150 151 151 129 130 130 +58 58 58 6 6 6 14 14 14 201 147 55 245 211 23 245 213 29 +245 214 35 245 215 41 245 213 29 244 210 23 142 83 36 232 232 233 +254 254 254 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 185 185 184 255 255 255 255 255 255 +255 255 255 255 255 255 254 254 254 251 252 252 50 51 51 7 7 7 +7 7 7 7 7 7 7 7 7 146 146 147 251 252 252 252 253 253 +251 252 253 239 239 240 171 168 154 129 130 130 137 136 134 175 173 165 +221 218 200 65 64 64 22 22 22 186 186 187 114 115 115 26 26 27 +2 2 2 0 0 0 61 65 66 31 33 27 238 192 33 108 96 91 +9 9 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 2 2 2 52 53 53 178 178 179 +21 21 22 7 7 7 7 7 7 7 7 7 7 7 7 118 118 118 +137 136 134 36 36 36 65 64 64 243 206 27 244 212 23 245 215 41 +245 215 41 245 215 41 245 215 41 244 209 25 244 209 25 1 1 1 +219 219 219 253 253 253 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 214 214 215 255 255 255 255 255 255 +255 255 255 255 255 255 254 254 254 252 252 253 50 51 51 7 7 7 +7 7 7 7 7 7 84 84 84 250 251 252 252 253 253 251 251 252 +167 168 167 22 22 22 7 7 7 7 7 7 7 7 7 7 7 7 +7 7 7 7 7 7 7 7 7 34 34 35 187 187 188 103 103 103 +29 29 30 3 3 3 7 9 9 238 204 29 245 215 41 245 214 35 +28 28 28 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 7 7 7 90 87 86 178 178 179 +7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 16 16 16 +193 193 194 133 133 133 187 166 103 245 218 76 245 218 76 245 216 51 +245 216 51 245 218 76 246 224 96 245 218 76 245 218 76 245 218 76 +25 25 25 186 186 187 252 252 252 254 254 254 254 254 254 253 254 254 +254 254 254 254 254 254 254 254 254 246 247 248 254 254 254 253 254 254 +254 254 254 254 254 254 253 254 254 251 252 252 36 36 36 7 7 7 +7 7 7 20 20 20 229 229 230 253 253 253 252 253 253 178 178 179 +10 10 10 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 +7 7 7 7 7 7 7 7 7 7 7 7 42 42 43 196 196 197 +118 118 118 33 33 34 238 204 29 245 215 41 245 215 41 245 215 41 +49 50 50 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 17 18 18 120 121 122 137 136 134 +7 7 7 7 7 7 34 34 35 20 20 20 7 7 7 7 7 7 +202 202 203 209 206 202 193 187 162 193 187 162 248 234 156 245 218 76 +245 218 76 248 234 156 193 187 162 193 187 162 193 187 162 214 196 166 +240 219 129 95 97 97 196 196 197 186 186 187 187 187 188 196 196 197 +252 252 253 251 252 253 212 211 212 187 187 188 196 196 197 251 252 252 +218 217 217 187 187 188 191 190 190 250 251 252 24 24 24 7 7 7 +7 7 7 110 114 114 252 252 253 253 254 254 250 251 252 89 90 91 +89 90 91 129 130 130 127 127 126 44 44 44 7 7 7 7 7 7 +7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 49 50 50 +202 202 203 214 196 166 245 216 51 245 214 38 245 214 35 245 214 38 +58 58 58 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 31 31 31 156 155 156 82 82 81 +7 7 7 10 10 10 237 237 238 66 66 66 7 7 7 25 25 25 +247 248 249 81 81 82 7 7 7 31 31 31 247 237 174 245 218 76 +246 226 108 200 200 197 7 7 7 7 7 7 7 7 7 137 136 134 +247 237 174 193 193 194 72 71 71 7 7 7 7 7 7 8 8 8 +196 196 197 250 251 252 67 70 70 7 7 7 84 84 84 244 245 245 +47 47 47 7 7 7 118 118 118 249 250 251 12 12 12 7 7 7 +9 9 9 218 217 217 253 253 253 254 254 254 252 253 253 251 251 252 +249 250 251 237 237 238 95 97 97 9 9 9 15 15 15 95 97 97 +47 47 47 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 +66 66 66 240 230 197 246 226 108 245 214 38 245 211 23 244 212 23 +65 64 64 3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 2 2 2 52 53 53 185 185 184 25 25 25 +7 7 7 60 60 60 240 240 240 14 14 14 7 7 7 84 84 84 +247 248 249 23 23 23 7 7 7 94 91 88 248 234 156 245 218 76 +248 234 156 127 127 126 7 7 7 7 7 7 7 7 7 167 168 167 +251 248 240 65 64 64 7 7 7 7 7 7 7 7 7 7 7 7 +84 84 84 243 243 243 15 15 15 7 7 7 140 142 143 146 146 147 +7 7 7 33 33 34 237 237 238 243 243 243 21 21 22 120 121 122 +218 217 217 252 252 253 254 254 254 253 253 254 252 253 253 251 252 252 +247 248 249 72 71 71 7 7 7 58 58 58 222 221 221 248 248 249 +75 75 76 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 +7 7 7 82 82 81 246 239 193 246 226 108 245 216 51 245 214 38 +238 192 33 21 21 22 1 1 1 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 8 8 8 90 87 86 182 183 184 7 7 7 +7 7 7 120 121 122 187 187 188 7 7 7 7 7 7 146 146 147 +205 205 205 7 7 7 7 7 7 153 153 148 240 219 129 246 224 96 +246 239 193 39 39 39 60 60 60 108 110 110 7 7 7 202 202 203 +227 227 227 7 7 7 7 7 7 205 205 205 89 90 91 7 7 7 +120 121 122 193 193 194 7 7 7 7 7 7 186 186 187 25 25 25 +7 7 7 167 168 167 251 251 252 243 243 243 214 214 215 250 251 252 +251 252 253 254 254 254 253 253 253 219 219 219 140 140 139 140 140 139 +118 118 118 7 7 7 52 53 53 237 237 238 247 247 246 176 177 177 +8 8 8 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 +7 7 7 7 7 7 95 97 97 246 239 193 246 226 108 245 216 51 +245 214 38 201 147 55 31 31 31 103 103 103 103 103 103 72 71 71 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 17 18 18 127 127 126 140 140 139 7 7 7 +7 7 7 17 18 18 17 18 18 7 7 7 95 97 97 244 245 245 +146 146 147 7 7 7 7 7 7 200 200 197 246 226 108 240 219 129 +194 194 184 7 7 7 140 140 139 89 90 91 7 7 7 232 232 233 +165 165 165 7 7 7 31 31 31 249 250 251 39 39 39 7 7 7 +176 177 177 133 133 133 7 7 7 22 22 22 108 110 110 7 7 7 +72 71 71 251 252 252 252 253 253 250 251 252 247 248 249 205 205 205 +251 252 253 254 254 254 252 252 253 84 84 84 7 7 7 7 7 7 +7 7 7 7 7 7 140 142 143 247 248 249 140 140 139 14 14 14 +7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 16 16 16 +14 14 14 7 7 7 7 7 7 114 115 115 246 239 193 246 224 96 +245 216 51 245 216 51 243 235 220 176 177 177 185 185 184 229 229 230 +47 47 47 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 31 31 31 156 155 156 90 87 86 7 7 7 +7 7 7 7 7 7 7 7 7 31 31 31 243 243 241 247 247 246 +84 84 84 7 7 7 26 27 27 246 239 193 246 226 108 248 234 156 +108 110 110 7 7 7 212 211 212 44 44 44 22 22 22 249 250 251 +108 107 107 7 7 7 89 90 91 238 238 236 114 115 115 118 118 118 +231 231 231 75 75 76 7 7 7 34 34 35 10 11 11 12 12 12 +214 214 215 253 253 253 253 253 253 200 200 197 31 31 31 103 103 103 +252 252 253 252 253 253 218 217 217 9 9 9 7 7 7 7 7 7 +7 7 7 7 7 7 25 25 25 39 39 39 7 7 7 7 7 7 +7 7 7 7 7 7 7 7 7 7 7 7 103 103 103 234 234 234 +181 181 181 7 7 7 7 7 7 7 7 7 133 133 133 247 237 174 +246 224 96 246 226 108 185 185 184 177 177 174 153 154 155 181 181 181 +140 140 139 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 1 1 1 49 50 50 186 186 187 28 28 28 7 7 7 +12 12 12 22 22 22 7 7 7 7 7 7 108 107 107 247 247 246 +25 25 25 7 7 7 90 87 86 247 237 174 246 226 108 246 239 193 +28 28 28 44 44 44 237 237 238 9 9 9 53 54 54 249 250 251 +49 50 50 7 7 7 153 153 148 249 241 199 214 196 166 185 185 184 +229 229 230 19 19 19 7 7 7 7 7 7 7 7 7 103 103 103 +251 252 253 254 254 254 253 253 253 150 151 151 7 7 7 187 187 188 +252 252 253 251 251 252 103 103 103 7 7 7 7 7 7 7 7 7 +7 7 7 23 23 23 17 18 18 7 7 7 7 7 7 7 7 7 +7 7 7 7 7 7 12 12 12 153 153 148 246 239 193 249 241 199 +161 161 162 9 9 9 84 84 84 108 110 110 25 25 25 153 153 148 +247 237 174 246 224 96 218 217 217 165 165 165 182 183 184 193 193 194 +114 115 115 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 4 4 4 74 74 74 181 181 181 7 7 7 7 7 7 +110 114 114 200 200 197 7 7 7 7 7 7 60 60 60 209 210 210 +7 7 7 7 7 7 146 146 147 248 234 156 248 234 156 177 177 174 +7 7 7 118 118 118 193 193 194 7 7 7 84 84 84 232 232 233 +8 8 8 7 7 7 209 210 210 221 218 200 193 187 162 219 219 219 +200 200 197 7 7 7 7 7 7 7 7 7 7 7 7 95 97 97 +251 252 252 254 254 254 252 253 253 118 118 118 29 29 30 247 248 249 +252 252 253 227 227 227 16 16 16 7 7 7 7 7 7 7 7 7 +100 103 103 218 217 217 219 218 214 7 7 7 7 7 7 7 7 7 +7 7 7 21 21 22 185 185 184 246 239 193 248 234 156 240 230 197 +60 60 60 194 194 184 246 239 193 249 241 199 137 136 134 10 10 10 +171 168 154 248 234 156 248 234 156 226 226 219 209 210 210 249 241 199 +28 28 28 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 13 13 13 108 110 110 146 146 147 7 7 7 7 7 7 +167 168 167 140 140 139 7 7 7 7 7 7 120 121 122 146 146 147 +7 7 7 7 7 7 194 194 184 240 219 129 247 237 174 95 97 97 +7 7 7 95 97 97 90 87 86 7 7 7 118 118 118 176 177 177 +7 7 7 28 28 28 248 248 249 44 44 45 7 7 7 167 168 167 +140 140 139 7 7 7 36 36 36 74 74 74 7 7 7 65 64 64 +251 252 253 254 254 254 251 252 252 81 81 82 108 110 110 251 252 252 +251 251 252 127 127 126 7 7 7 7 7 7 8 8 8 140 140 139 +181 181 181 140 140 139 221 218 200 7 7 7 7 7 7 7 7 7 +34 34 35 209 210 210 231 231 231 246 239 193 247 237 174 194 194 184 +227 227 227 249 241 199 240 219 129 248 234 156 153 153 148 7 7 7 +13 13 13 185 185 184 248 234 156 245 218 76 245 216 51 245 214 38 +31 31 31 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 31 31 31 153 154 155 89 90 91 7 7 7 8 8 8 +232 232 233 82 82 81 7 7 7 7 7 7 179 180 181 89 90 91 +7 7 7 24 24 24 243 235 220 248 234 156 240 230 197 20 20 20 +7 7 7 7 7 7 7 7 7 7 7 7 149 149 150 118 118 118 +7 7 7 90 87 86 229 229 230 7 7 7 7 7 7 229 229 230 +82 82 81 7 7 7 95 97 97 100 103 103 7 7 7 34 34 35 +251 252 252 253 253 254 251 251 252 47 47 47 193 193 194 251 252 252 +239 239 240 23 23 23 7 7 7 13 13 13 165 165 165 234 234 234 +149 149 150 146 114 101 200 200 197 7 7 7 7 7 7 52 53 53 +227 227 227 167 168 167 16 16 16 214 196 166 248 234 156 243 235 220 +219 219 219 156 155 156 247 237 174 246 239 193 75 75 76 7 7 7 +60 60 60 227 227 227 243 235 220 240 219 129 245 218 76 245 213 29 +16 16 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +1 1 1 49 50 50 185 185 184 33 33 34 7 7 7 10 11 11 +56 56 56 16 16 16 7 7 7 10 10 10 237 237 238 26 27 27 +7 7 7 55 55 55 185 185 184 221 218 200 167 168 167 7 7 7 +20 20 20 39 39 39 10 11 11 7 7 7 181 181 181 58 58 58 +7 7 7 103 103 103 133 133 133 7 7 7 44 44 44 247 248 249 +24 24 24 7 7 7 156 155 156 129 130 130 7 7 7 9 9 9 +244 245 245 252 253 253 237 237 238 34 34 35 248 248 249 251 251 252 +161 161 162 7 7 7 24 24 24 187 187 188 212 211 212 67 70 70 +187 187 188 173 170 143 209 206 202 10 10 10 95 97 97 237 237 238 +129 130 130 8 8 8 89 90 91 246 239 193 247 237 174 177 177 174 +17 18 18 137 136 134 249 241 199 219 218 214 10 10 10 95 97 97 +243 243 243 150 151 151 31 31 31 221 218 200 240 219 129 53 54 54 +3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +4 4 4 72 71 71 182 183 184 7 7 7 7 7 7 7 7 7 +7 7 7 7 7 7 12 12 12 161 161 162 209 210 210 7 7 7 +7 7 7 7 7 7 7 7 7 187 187 188 82 82 81 7 7 7 +146 146 147 247 248 249 17 18 18 7 7 7 212 211 212 47 47 47 +7 7 7 7 7 7 7 7 7 8 8 8 146 146 147 205 205 205 +7 7 7 7 7 7 214 214 215 156 155 156 7 7 7 7 7 7 +218 217 217 251 252 252 186 186 187 110 114 114 249 250 251 248 248 249 +75 75 76 34 34 35 205 205 205 129 130 130 16 16 16 7 7 7 +156 155 156 214 196 166 240 230 197 243 243 241 227 227 227 74 74 74 +7 7 7 29 29 30 226 226 219 249 241 199 175 173 165 14 14 14 +9 9 9 221 218 200 246 239 193 153 153 148 146 146 147 246 247 248 +110 114 114 7 7 7 7 7 7 42 42 43 193 193 194 95 97 97 +19 19 19 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +6 6 6 84 84 84 140 142 143 7 7 7 7 7 7 7 7 7 +7 7 7 20 20 20 177 177 174 249 241 199 149 149 150 7 7 7 +7 7 7 7 7 7 10 11 11 226 226 219 13 13 13 8 8 8 +219 218 214 219 218 214 7 7 7 8 8 8 238 238 236 200 200 197 +13 13 13 7 7 7 13 13 13 161 161 162 243 235 220 146 146 147 +7 7 7 29 29 30 232 232 233 176 177 177 7 7 7 7 7 7 +182 183 184 237 237 238 129 130 130 167 168 167 176 177 177 202 202 203 +10 11 11 95 97 97 44 44 45 7 7 7 7 7 7 7 7 7 +75 75 76 226 226 219 243 235 220 156 155 156 24 24 24 7 7 7 +7 7 7 176 177 177 247 247 246 200 200 197 17 18 18 7 7 7 +49 50 50 246 239 193 248 234 156 251 248 240 239 239 240 84 84 84 +7 7 7 7 7 7 7 7 7 7 7 7 60 60 60 187 187 188 +84 84 84 14 14 14 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +4 4 4 53 54 54 137 136 134 156 155 156 161 161 162 161 161 162 +167 168 167 239 223 156 240 219 129 246 226 108 239 223 156 239 223 156 +239 223 156 239 223 156 214 196 166 239 223 156 193 187 162 193 187 162 +248 234 156 239 223 156 193 187 162 193 187 162 248 234 156 248 234 156 +214 196 166 193 187 162 214 196 166 248 234 156 240 219 129 214 196 166 +193 187 162 193 187 162 171 168 154 146 146 147 137 136 134 137 136 134 +161 161 162 209 210 210 65 64 64 202 202 203 179 180 181 140 140 139 +7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 +7 7 7 60 60 60 39 39 39 7 7 7 7 7 7 7 7 7 +66 66 66 249 250 251 202 202 203 16 16 16 7 7 7 7 7 7 +23 23 23 243 235 220 246 239 193 226 226 219 52 53 53 7 7 7 +7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 75 75 76 +176 177 177 66 66 66 9 9 9 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 10 10 10 28 28 29 34 34 35 36 36 36 36 36 36 +44 44 45 146 114 101 241 207 50 241 207 50 241 207 50 241 211 63 +241 211 63 241 211 63 241 211 63 241 211 63 241 211 63 245 216 51 +245 216 51 245 216 51 241 211 63 241 211 63 245 216 51 241 211 63 +245 218 76 245 218 76 245 216 51 245 215 41 245 214 38 241 207 50 +241 211 63 201 147 55 88 79 47 29 29 30 34 34 35 42 42 43 +103 103 103 191 190 190 75 75 76 196 196 197 200 200 197 65 64 64 +7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 +7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 +90 87 86 146 146 147 19 19 19 7 7 7 7 7 7 7 7 7 +7 7 7 90 87 86 140 140 139 31 31 31 7 7 7 7 7 7 +7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 +103 103 103 161 161 162 53 54 54 7 7 7 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 12 12 12 50 51 51 146 114 101 180 121 62 199 129 48 +201 147 55 213 157 40 213 157 40 230 165 41 226 179 40 226 179 40 +238 192 33 241 205 27 244 209 25 244 210 23 244 212 23 245 211 23 +245 211 23 245 211 23 245 211 23 244 209 25 238 204 29 226 179 40 +213 157 40 199 129 48 54 42 32 0 0 0 4 6 6 44 44 45 +150 151 151 129 130 130 137 136 134 205 205 205 202 202 203 8 8 8 +7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 +7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 +7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 +7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 +7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 +7 7 7 129 130 130 146 146 147 47 47 47 4 4 4 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 2 2 2 12 12 12 28 28 29 49 50 50 +74 74 74 108 96 91 180 121 62 180 121 62 199 129 48 201 147 55 +213 157 40 230 165 41 226 179 40 238 192 33 241 205 27 241 205 27 +243 206 27 243 206 27 241 205 27 238 204 29 226 179 40 213 157 40 +199 129 48 199 129 48 21 19 17 65 64 64 103 103 103 167 168 167 +202 202 203 24 24 24 193 193 194 229 229 230 140 140 139 7 7 7 +7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 +7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 +7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 +7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 +7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 +7 7 7 8 8 8 156 155 156 133 133 133 36 36 36 3 3 3 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 +4 4 4 10 11 11 21 21 22 39 39 39 60 60 60 108 96 91 +180 121 62 199 129 48 199 129 48 213 157 40 230 165 41 226 179 40 +226 179 40 226 179 40 226 179 40 226 179 40 213 157 40 199 129 48 +180 121 62 99 91 79 72 71 71 56 56 56 129 130 130 167 168 167 +21 21 22 17 18 18 231 231 231 229 229 230 52 53 53 7 7 7 +7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 +7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 +7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 +7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 +7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 +7 7 7 7 7 7 13 13 13 176 177 177 120 121 122 33 33 34 +2 2 2 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 8 8 8 +21 21 22 47 47 47 99 91 79 180 121 62 199 129 48 199 129 48 +201 147 55 213 157 40 213 157 40 201 147 55 199 129 48 180 121 62 +99 91 79 26 26 27 9 9 9 60 60 60 186 186 187 31 31 31 +7 7 7 60 60 60 243 243 243 209 210 210 7 7 7 7 7 7 +7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 +7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 +7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 +7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 +7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 +7 7 7 7 7 7 7 7 7 26 27 27 193 193 194 108 110 110 +22 22 22 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 1 1 1 8 8 8 24 24 24 58 58 58 108 96 91 +180 121 62 180 121 62 180 121 62 180 121 62 180 121 62 72 71 71 +15 15 15 0 0 0 4 6 6 75 75 76 156 155 156 24 24 24 +24 24 24 108 107 107 232 232 233 137 136 134 24 24 24 24 24 24 +24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 +24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 +24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 +24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 +24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 +24 24 24 24 24 24 24 24 24 24 24 24 58 58 58 176 177 177 +60 60 60 3 3 3 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 12 12 12 +26 27 27 44 44 44 55 55 55 50 51 51 29 29 30 8 8 8 +0 0 0 0 0 0 3 3 3 47 47 47 127 127 126 150 151 151 +150 151 151 140 142 143 129 130 130 140 142 143 150 151 151 150 151 151 +150 151 151 150 151 151 150 151 151 150 151 151 150 151 151 150 151 151 +150 151 151 150 151 151 153 154 155 161 161 162 165 165 165 167 168 167 +177 177 174 167 168 167 161 161 162 156 155 156 150 151 151 150 151 151 +150 151 151 150 151 151 150 151 151 150 151 151 150 151 151 150 151 151 +150 151 151 150 151 151 150 151 151 150 151 151 150 151 151 150 151 151 +150 151 151 150 151 151 150 151 151 150 151 151 149 149 150 127 127 126 +44 44 45 2 2 2 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 2 2 2 1 1 1 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 7 7 7 21 21 22 25 25 26 +25 25 26 24 24 24 20 20 20 23 23 24 25 25 26 26 26 27 +26 26 27 26 26 27 26 26 27 26 26 27 26 26 27 26 26 27 +26 26 27 26 26 27 26 26 27 26 26 27 26 26 27 26 27 27 +28 28 29 26 27 27 26 26 27 26 26 27 26 26 27 26 26 27 +26 26 27 26 26 27 26 26 27 26 26 27 26 26 27 26 26 27 +26 26 27 26 26 27 26 26 27 26 26 27 26 26 27 26 26 27 +26 26 27 26 26 27 26 26 27 26 26 27 25 25 26 21 21 22 +7 7 7 0 0 0 diff --git a/drivers/video/logo/logo_blackfin_vga16.ppm b/drivers/video/logo/logo_blackfin_vga16.ppm new file mode 100644 index 0000000000000000000000000000000000000000..1352b02a9d932d0b5d1a112ffedcd21157c9ff04 --- /dev/null +++ b/drivers/video/logo/logo_blackfin_vga16.ppm @@ -0,0 +1,1127 @@ +P3 +# This was generated by the GIMP & Netpbm tools +# gimp linux_bf.svg (create 80x80 save as linux_bf.ppm) +# ppmquant -mapfile clut_vga16.ppm linux_bf.ppm | pnmnoraw > logo_blackfin_vga16.ppm +# +80 80 +255 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 +85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +85 85 85 85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 85 85 85 85 85 85 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 85 85 85 85 85 85 85 85 85 0 0 0 0 0 0 +85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 170 170 170 170 170 170 85 85 85 0 0 0 0 0 0 +0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 +0 0 0 85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 170 170 170 +170 170 170 85 85 85 85 85 85 170 170 170 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +0 0 0 170 170 170 170 170 170 170 170 170 85 85 85 85 85 85 +0 0 0 0 0 0 0 0 0 85 85 85 170 170 170 255 255 255 +255 255 255 255 255 255 170 170 170 85 85 85 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +170 170 170 255 255 255 255 255 255 255 255 255 255 255 255 0 0 0 +0 0 0 0 0 0 0 0 0 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 170 170 170 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +255 255 255 170 170 170 85 85 85 170 170 170 255 255 255 255 255 255 +0 0 0 0 0 0 170 170 170 255 255 255 255 255 255 85 85 85 +85 85 85 170 170 170 255 255 255 255 255 255 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +255 255 255 85 85 85 170 170 170 170 170 170 255 255 255 255 255 255 +85 85 85 85 85 85 170 170 170 255 255 255 170 170 170 0 0 0 +170 170 170 170 170 170 255 255 255 255 255 255 85 85 85 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +255 255 255 0 0 0 85 85 85 170 170 170 170 170 170 255 255 255 +0 0 0 85 85 85 85 85 85 255 255 255 85 85 85 0 0 0 +0 0 0 85 85 85 170 170 170 255 255 255 85 85 85 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +255 255 255 85 85 85 0 0 0 0 0 0 255 85 85 255 255 85 +255 255 85 255 255 85 255 255 85 255 255 85 85 85 85 0 0 0 +0 0 0 0 0 0 170 170 170 255 255 255 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +170 170 170 255 255 255 0 0 0 255 85 85 170 85 0 170 85 0 +255 255 85 255 255 85 170 85 0 255 255 85 255 255 85 255 255 85 +0 0 0 85 85 85 255 255 255 255 255 255 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +0 0 0 255 255 255 255 85 85 255 255 85 255 255 85 255 255 85 +255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 +255 255 85 255 255 85 255 255 85 170 170 170 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +0 0 0 255 85 85 255 255 85 255 255 85 255 255 85 255 255 85 +255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 +255 255 85 255 255 85 255 255 85 255 255 85 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +170 85 0 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 +255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 +255 255 85 170 85 0 85 85 85 255 255 85 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +255 85 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 +255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 +170 85 0 85 85 85 255 255 85 255 255 85 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +170 85 0 170 85 0 255 255 85 255 255 85 255 255 85 255 255 85 +255 255 85 255 255 85 255 255 85 255 255 85 170 85 0 170 85 0 +170 85 0 255 255 85 255 255 85 255 85 85 0 0 0 0 0 0 +85 85 85 85 85 85 85 85 85 0 0 0 0 0 0 85 85 85 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +85 85 85 170 85 0 170 85 0 170 85 0 255 255 85 255 255 85 +255 255 85 255 85 85 170 85 0 170 85 0 170 85 0 255 255 85 +255 255 85 255 255 85 255 85 85 170 170 170 0 0 0 0 0 0 +85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 85 85 85 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +85 85 85 170 170 170 170 85 0 170 85 0 170 85 0 170 85 0 +170 85 0 170 85 0 170 85 0 255 255 85 255 255 85 255 255 85 +255 85 85 170 170 170 255 255 255 255 255 255 85 85 85 0 0 0 +0 0 0 85 85 85 85 85 85 85 85 85 0 0 0 0 0 0 +85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +170 170 170 170 170 170 170 170 170 170 85 0 255 255 85 255 255 85 +255 255 85 255 255 85 255 255 85 255 255 85 255 85 85 170 170 170 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 0 0 0 +0 0 0 0 0 0 85 85 85 85 85 85 0 0 0 0 0 0 +85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +170 170 170 255 255 255 255 255 255 170 170 170 170 85 0 255 85 85 +255 85 85 255 85 85 255 85 85 255 85 85 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 85 85 85 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +170 170 170 255 255 255 255 255 255 170 170 170 170 170 170 170 170 170 +170 170 170 170 170 170 170 170 170 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 85 85 85 85 85 85 0 0 0 0 0 0 +255 255 255 255 255 255 255 255 255 255 255 255 170 170 170 170 170 170 +170 170 170 170 170 170 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 85 85 85 0 0 0 0 0 0 170 170 170 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +85 85 85 0 0 0 0 0 0 0 0 0 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +85 85 85 0 0 0 0 0 0 85 85 85 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +0 0 0 0 0 0 0 0 0 170 170 170 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 85 85 85 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +0 0 0 0 0 0 0 0 0 170 170 170 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 170 170 170 170 170 170 170 170 170 170 170 170 +170 170 170 255 255 255 255 255 255 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +0 0 0 0 0 0 85 85 85 170 170 170 170 170 170 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 170 170 170 170 170 170 170 170 170 170 170 170 +170 170 170 170 170 170 255 255 255 0 0 0 0 0 0 85 85 85 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +0 0 0 0 0 0 170 170 170 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 170 170 170 +170 170 170 170 170 170 170 170 170 255 255 255 0 0 0 85 85 85 +85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +0 0 0 0 0 0 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 170 170 170 170 170 170 255 255 255 0 0 0 0 0 0 +0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 +0 0 0 170 170 170 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 170 170 170 85 85 85 170 170 170 170 170 170 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 170 170 170 170 170 170 255 255 255 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 85 85 85 85 85 85 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 +0 0 0 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +170 170 170 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 0 0 0 +0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 85 85 85 170 170 170 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 170 170 170 +0 0 0 85 85 85 0 0 0 85 85 85 85 85 85 0 0 0 +0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 85 85 85 0 0 0 85 85 85 85 85 85 85 85 85 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 170 170 170 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 85 85 85 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 170 170 170 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 170 170 170 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 85 85 85 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +170 170 170 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +0 0 0 0 0 0 0 0 0 0 0 0 170 170 170 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 170 170 170 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 170 170 170 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 170 170 170 255 255 255 255 255 255 255 255 255 255 255 255 +85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +0 0 0 0 0 0 85 85 85 0 0 0 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 170 170 170 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 170 170 170 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 170 170 170 255 255 255 255 255 255 255 255 255 +170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +0 0 0 0 0 0 85 85 85 0 0 0 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 170 170 170 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 170 170 170 255 255 255 255 255 255 +170 170 170 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +0 0 0 0 0 0 85 85 85 0 0 0 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 170 170 170 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 170 170 170 255 255 255 +170 170 170 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +0 0 0 0 0 0 85 85 85 0 0 0 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 170 170 170 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 170 170 170 +170 170 170 0 0 0 0 0 0 85 85 85 85 85 85 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +0 0 0 0 0 0 85 85 85 85 85 85 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 170 170 170 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 85 85 85 170 170 170 170 170 170 255 255 255 255 255 255 +170 170 170 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 170 85 0 +255 255 85 255 255 85 0 0 0 85 85 85 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 170 170 170 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +170 170 170 170 170 170 170 170 170 85 85 85 0 0 0 85 85 85 +85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 255 255 85 255 255 85 +255 255 85 255 255 85 255 255 85 85 85 85 170 170 170 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 170 170 170 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 170 170 170 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 85 170 170 170 +85 85 85 170 170 170 170 170 170 85 85 85 0 0 0 0 0 0 +0 0 0 85 85 85 170 170 170 0 0 0 0 0 0 85 85 85 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 +85 85 85 0 0 0 0 0 0 170 85 0 255 255 85 255 255 85 +255 255 85 255 255 85 255 255 85 255 255 85 170 85 0 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 170 170 170 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 85 85 85 0 0 0 +0 0 0 0 0 0 0 0 0 170 170 170 255 255 255 255 255 255 +255 255 255 255 255 255 170 170 170 170 170 170 170 170 170 170 170 170 +255 255 255 85 85 85 0 0 0 170 170 170 85 85 85 0 0 0 +0 0 0 0 0 0 85 85 85 0 0 0 255 255 85 85 85 85 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 170 170 170 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +170 170 170 0 0 0 85 85 85 255 255 85 255 255 85 255 255 85 +255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 0 0 0 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 85 85 85 0 0 0 +0 0 0 0 0 0 85 85 85 255 255 255 255 255 255 255 255 255 +170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 170 170 170 85 85 85 +0 0 0 0 0 0 0 0 0 255 255 85 255 255 85 255 255 85 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 170 170 170 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +170 170 170 170 170 170 255 255 85 255 255 85 255 255 85 255 255 85 +255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 +0 0 0 170 170 170 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 0 0 0 0 0 0 +0 0 0 0 0 0 255 255 255 255 255 255 255 255 255 170 170 170 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 170 170 170 +85 85 85 0 0 0 255 255 85 255 255 85 255 255 85 255 255 85 +85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 170 170 170 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +170 170 170 170 170 170 170 170 170 170 170 170 255 255 85 255 255 85 +255 255 85 255 255 85 170 170 170 170 170 170 170 170 170 170 170 170 +255 255 85 85 85 85 170 170 170 170 170 170 170 170 170 170 170 170 +255 255 255 255 255 255 170 170 170 170 170 170 170 170 170 255 255 255 +255 255 255 170 170 170 170 170 170 255 255 255 0 0 0 0 0 0 +0 0 0 85 85 85 255 255 255 255 255 255 255 255 255 85 85 85 +85 85 85 170 170 170 170 170 170 85 85 85 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +170 170 170 170 170 170 255 255 85 255 255 85 255 255 85 255 255 85 +85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 170 170 170 85 85 85 +0 0 0 0 0 0 255 255 255 85 85 85 0 0 0 0 0 0 +255 255 255 85 85 85 0 0 0 0 0 0 255 255 255 255 255 85 +255 255 85 170 170 170 0 0 0 0 0 0 0 0 0 170 170 170 +255 255 255 170 170 170 85 85 85 0 0 0 0 0 0 0 0 0 +170 170 170 255 255 255 85 85 85 0 0 0 85 85 85 255 255 255 +85 85 85 0 0 0 85 85 85 255 255 255 0 0 0 0 0 0 +0 0 0 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 85 85 85 0 0 0 0 0 0 85 85 85 +85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +85 85 85 255 255 255 255 255 85 255 255 85 255 255 85 255 255 85 +85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 85 85 85 170 170 170 0 0 0 +0 0 0 85 85 85 255 255 255 0 0 0 0 0 0 85 85 85 +255 255 255 0 0 0 0 0 0 85 85 85 255 255 85 255 255 85 +255 255 85 85 85 85 0 0 0 0 0 0 0 0 0 170 170 170 +255 255 255 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +85 85 85 255 255 255 0 0 0 0 0 0 170 170 170 170 170 170 +0 0 0 0 0 0 255 255 255 255 255 255 0 0 0 85 85 85 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 85 85 85 0 0 0 85 85 85 255 255 255 255 255 255 +85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 85 85 85 255 255 255 255 255 85 255 255 85 255 255 85 +255 255 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 85 85 85 170 170 170 0 0 0 +0 0 0 85 85 85 170 170 170 0 0 0 0 0 0 170 170 170 +170 170 170 0 0 0 0 0 0 170 170 170 255 255 85 255 255 85 +255 255 255 0 0 0 85 85 85 85 85 85 0 0 0 170 170 170 +255 255 255 0 0 0 0 0 0 170 170 170 85 85 85 0 0 0 +85 85 85 170 170 170 0 0 0 0 0 0 170 170 170 0 0 0 +0 0 0 170 170 170 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 170 170 170 170 170 170 +85 85 85 0 0 0 85 85 85 255 255 255 255 255 255 170 170 170 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 85 85 85 255 255 255 255 255 85 255 255 85 +255 255 85 170 85 0 0 0 0 85 85 85 85 85 85 85 85 85 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 85 85 85 170 170 170 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 255 255 255 +170 170 170 0 0 0 0 0 0 170 170 170 255 255 85 255 255 85 +170 170 170 0 0 0 170 170 170 85 85 85 0 0 0 255 255 255 +170 170 170 0 0 0 0 0 0 255 255 255 0 0 0 0 0 0 +170 170 170 170 170 170 0 0 0 0 0 0 85 85 85 0 0 0 +85 85 85 255 255 255 255 255 255 255 255 255 255 255 255 170 170 170 +255 255 255 255 255 255 255 255 255 85 85 85 0 0 0 0 0 0 +0 0 0 0 0 0 170 170 170 255 255 255 170 170 170 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 85 85 85 255 255 255 255 255 85 +255 255 85 255 255 85 255 255 255 170 170 170 170 170 170 255 255 255 +85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 170 170 170 85 85 85 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 255 255 255 255 255 255 +85 85 85 0 0 0 0 0 0 255 255 255 255 255 85 255 255 85 +85 85 85 0 0 0 255 255 255 85 85 85 0 0 0 255 255 255 +85 85 85 0 0 0 85 85 85 255 255 255 85 85 85 85 85 85 +255 255 255 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +255 255 255 255 255 255 255 255 255 170 170 170 0 0 0 85 85 85 +255 255 255 255 255 255 255 255 255 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 255 255 255 +170 170 170 0 0 0 0 0 0 0 0 0 170 170 170 255 255 255 +255 255 85 255 255 85 170 170 170 170 170 170 170 170 170 170 170 170 +170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 85 85 85 170 170 170 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 255 255 255 +0 0 0 0 0 0 85 85 85 255 255 85 255 255 85 255 255 255 +0 0 0 85 85 85 255 255 255 0 0 0 85 85 85 255 255 255 +85 85 85 0 0 0 170 170 170 255 255 255 170 170 170 170 170 170 +255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +255 255 255 255 255 255 255 255 255 170 170 170 0 0 0 170 170 170 +255 255 255 255 255 255 85 85 85 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 170 170 170 255 255 255 255 255 255 +170 170 170 0 0 0 85 85 85 85 85 85 0 0 0 170 170 170 +255 255 85 255 255 85 255 255 255 170 170 170 170 170 170 170 170 170 +85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 85 85 85 170 170 170 0 0 0 0 0 0 +85 85 85 170 170 170 0 0 0 0 0 0 85 85 85 170 170 170 +0 0 0 0 0 0 170 170 170 255 255 85 255 255 85 170 170 170 +0 0 0 85 85 85 170 170 170 0 0 0 85 85 85 255 255 255 +0 0 0 0 0 0 170 170 170 170 170 170 170 170 170 255 255 255 +170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +255 255 255 255 255 255 255 255 255 85 85 85 0 0 0 255 255 255 +255 255 255 255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 +85 85 85 255 255 255 255 255 255 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 170 170 170 255 255 255 255 255 85 255 255 255 +85 85 85 170 170 170 255 255 255 255 255 255 170 170 170 0 0 0 +170 170 170 255 255 85 255 255 85 255 255 255 170 170 170 255 255 255 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 85 85 85 170 170 170 0 0 0 0 0 0 +170 170 170 170 170 170 0 0 0 0 0 0 85 85 85 170 170 170 +0 0 0 0 0 0 170 170 170 255 255 85 255 255 255 85 85 85 +0 0 0 85 85 85 85 85 85 0 0 0 85 85 85 170 170 170 +0 0 0 0 0 0 255 255 255 85 85 85 0 0 0 170 170 170 +170 170 170 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 +255 255 255 255 255 255 255 255 255 85 85 85 85 85 85 255 255 255 +255 255 255 85 85 85 0 0 0 0 0 0 0 0 0 170 170 170 +170 170 170 170 170 170 255 255 255 0 0 0 0 0 0 0 0 0 +0 0 0 170 170 170 255 255 255 255 255 255 255 255 85 170 170 170 +255 255 255 255 255 255 255 255 85 255 255 85 170 170 170 0 0 0 +0 0 0 170 170 170 255 255 85 255 255 85 255 255 85 255 255 85 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 170 170 170 85 85 85 0 0 0 0 0 0 +255 255 255 85 85 85 0 0 0 0 0 0 170 170 170 85 85 85 +0 0 0 0 0 0 255 255 255 255 255 85 255 255 255 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 170 170 170 85 85 85 +0 0 0 85 85 85 255 255 255 0 0 0 0 0 0 255 255 255 +85 85 85 0 0 0 85 85 85 85 85 85 0 0 0 0 0 0 +255 255 255 255 255 255 255 255 255 85 85 85 170 170 170 255 255 255 +255 255 255 0 0 0 0 0 0 0 0 0 170 170 170 255 255 255 +170 170 170 85 85 85 170 170 170 0 0 0 0 0 0 85 85 85 +255 255 255 170 170 170 0 0 0 170 170 170 255 255 85 255 255 255 +255 255 255 170 170 170 255 255 255 255 255 255 85 85 85 0 0 0 +85 85 85 255 255 255 255 255 255 255 255 85 255 255 85 255 255 85 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 85 85 85 170 170 170 0 0 0 0 0 0 0 0 0 +85 85 85 0 0 0 0 0 0 0 0 0 255 255 255 0 0 0 +0 0 0 85 85 85 170 170 170 255 255 255 170 170 170 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 170 170 170 85 85 85 +0 0 0 85 85 85 170 170 170 0 0 0 85 85 85 255 255 255 +0 0 0 0 0 0 170 170 170 170 170 170 0 0 0 0 0 0 +255 255 255 255 255 255 255 255 255 0 0 0 255 255 255 255 255 255 +170 170 170 0 0 0 0 0 0 170 170 170 255 255 255 85 85 85 +170 170 170 170 170 170 170 170 170 0 0 0 85 85 85 255 255 255 +170 170 170 0 0 0 85 85 85 255 255 255 255 255 85 170 170 170 +0 0 0 170 170 170 255 255 255 255 255 255 0 0 0 85 85 85 +255 255 255 170 170 170 0 0 0 170 170 170 255 255 85 85 85 85 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 85 85 85 170 170 170 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 170 170 170 170 170 170 0 0 0 +0 0 0 0 0 0 0 0 0 170 170 170 85 85 85 0 0 0 +170 170 170 255 255 255 0 0 0 0 0 0 170 170 170 85 85 85 +0 0 0 0 0 0 0 0 0 0 0 0 170 170 170 170 170 170 +0 0 0 0 0 0 255 255 255 170 170 170 0 0 0 0 0 0 +255 255 255 255 255 255 170 170 170 85 85 85 255 255 255 255 255 255 +85 85 85 0 0 0 170 170 170 170 170 170 0 0 0 0 0 0 +170 170 170 170 170 170 255 255 255 255 255 255 255 255 255 85 85 85 +0 0 0 0 0 0 255 255 255 255 255 255 170 170 170 0 0 0 +0 0 0 170 170 170 255 255 255 170 170 170 170 170 170 255 255 255 +85 85 85 0 0 0 0 0 0 0 0 0 170 170 170 85 85 85 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 85 85 85 170 170 170 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 170 170 170 255 255 255 170 170 170 0 0 0 +0 0 0 0 0 0 0 0 0 255 255 255 0 0 0 0 0 0 +255 255 255 255 255 255 0 0 0 0 0 0 255 255 255 170 170 170 +0 0 0 0 0 0 0 0 0 170 170 170 255 255 255 170 170 170 +0 0 0 0 0 0 255 255 255 170 170 170 0 0 0 0 0 0 +170 170 170 255 255 255 170 170 170 170 170 170 170 170 170 170 170 170 +0 0 0 85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 +85 85 85 255 255 255 255 255 255 170 170 170 0 0 0 0 0 0 +0 0 0 170 170 170 255 255 255 170 170 170 0 0 0 0 0 0 +85 85 85 255 255 255 255 255 85 255 255 255 255 255 255 85 85 85 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 170 170 170 +85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 85 85 85 170 170 170 170 170 170 170 170 170 170 170 170 +170 170 170 170 170 170 255 255 85 255 255 85 255 255 85 170 170 170 +170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 +255 255 85 170 170 170 170 170 170 170 170 170 255 255 85 255 255 85 +170 170 170 170 170 170 170 170 170 255 255 85 255 255 85 170 170 170 +170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 +170 170 170 170 170 170 85 85 85 170 170 170 170 170 170 170 170 170 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +85 85 85 255 255 255 170 170 170 0 0 0 0 0 0 0 0 0 +0 0 0 255 255 255 255 255 255 255 255 255 85 85 85 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +170 170 170 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +85 85 85 85 85 85 255 255 85 255 255 85 255 255 85 255 255 85 +255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 +255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 +255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 +255 255 85 255 85 85 85 85 85 0 0 0 0 0 0 0 0 0 +85 85 85 170 170 170 85 85 85 170 170 170 170 170 170 85 85 85 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +85 85 85 170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 85 85 85 170 170 170 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +85 85 85 170 170 170 85 85 85 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 85 85 85 85 85 85 170 85 0 170 85 0 +170 85 0 255 85 85 255 85 85 255 85 85 255 255 85 255 255 85 +255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 +255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 +255 85 85 170 85 0 85 85 85 0 0 0 0 0 0 85 85 85 +170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 170 170 170 170 170 170 85 85 85 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +85 85 85 85 85 85 170 85 0 170 85 0 170 85 0 170 85 0 +255 85 85 255 85 85 255 255 85 255 255 85 255 255 85 255 255 85 +255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 85 85 +170 85 0 170 85 0 0 0 0 85 85 85 85 85 85 170 170 170 +170 170 170 0 0 0 170 170 170 255 255 255 170 170 170 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 170 170 170 170 170 170 0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 +170 85 0 170 85 0 170 85 0 255 85 85 255 85 85 255 255 85 +255 255 85 255 255 85 255 255 85 255 255 85 255 85 85 170 85 0 +170 85 0 85 85 85 85 85 85 85 85 85 170 170 170 170 170 170 +0 0 0 0 0 0 255 255 255 255 255 255 85 85 85 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 170 170 170 85 85 85 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 85 85 85 85 85 85 170 85 0 170 85 0 170 85 0 +170 85 0 255 85 85 255 85 85 255 85 85 170 85 0 170 85 0 +85 85 85 0 0 0 0 0 0 85 85 85 170 170 170 0 0 0 +0 0 0 85 85 85 255 255 255 170 170 170 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 170 170 170 85 85 85 +0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 +170 85 0 170 85 0 170 85 0 170 85 0 170 85 0 85 85 85 +0 0 0 0 0 0 0 0 0 85 85 85 170 170 170 0 0 0 +0 0 0 85 85 85 255 255 255 170 170 170 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 170 170 170 +85 85 85 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 85 85 85 85 85 85 85 85 85 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 170 170 170 +170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 +170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 +170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 +170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 +170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 +170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 +170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 85 85 85 +85 85 85 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 diff --git a/drivers/video/p9100.c b/drivers/video/p9100.c index c95874fe9076579de587a7c1f87c9ded194ff7b5..9e903454ffc138b053c4ad32f7b12dd3636e8f94 100644 --- a/drivers/video/p9100.c +++ b/drivers/video/p9100.c @@ -15,10 +15,9 @@ #include #include #include +#include #include -#include -#include #include #include "sbuslib.h" @@ -275,7 +274,7 @@ static int __devinit p9100_probe(struct of_device *op, const struct of_device_id par->physbase = op->resource[2].start; par->which_io = op->resource[2].flags & IORESOURCE_BITS; - sbusfb_fill_var(&info->var, dp->node, 8); + sbusfb_fill_var(&info->var, dp, 8); info->var.red.length = 8; info->var.green.length = 8; info->var.blue.length = 8; @@ -295,7 +294,7 @@ static int __devinit p9100_probe(struct of_device *op, const struct of_device_id if (!info->screen_base) goto out_unmap_regs; - p9100_blank(0, info); + p9100_blank(FB_BLANK_UNBLANK, info); if (fb_alloc_cmap(&info->cmap, 256, 0)) goto out_unmap_screen; diff --git a/drivers/video/pnx4008/pnxrgbfb.c b/drivers/video/pnx4008/pnxrgbfb.c index 685761a0732c2d4196b727875af516627e9ae2a8..4db6b48a87155b1f7316ad6f5145d37922edec8f 100644 --- a/drivers/video/pnx4008/pnxrgbfb.c +++ b/drivers/video/pnx4008/pnxrgbfb.c @@ -100,7 +100,6 @@ static int rgbfb_remove(struct platform_device *pdev) fb_dealloc_cmap(&info->cmap); framebuffer_release(info); platform_set_drvdata(pdev, NULL); - kfree(info); } pnx4008_free_dum_channel(channel_owned, pdev->id); @@ -168,23 +167,21 @@ static int __devinit rgbfb_probe(struct platform_device *pdev) ret = fb_alloc_cmap(&info->cmap, 256, 0); if (ret < 0) - goto err2; + goto err1; ret = register_framebuffer(info); if (ret < 0) - goto err3; + goto err2; platform_set_drvdata(pdev, info); return 0; -err3: - fb_dealloc_cmap(&info->cmap); err2: - framebuffer_release(info); + fb_dealloc_cmap(&info->cmap); err1: pnx4008_free_dum_channel(channel_owned, pdev->id); err0: - kfree(info); + framebuffer_release(info); err: return ret; } diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 3ab6e3d973a1670bef82cc28fa89cf1ba8e46d8f..3ee314beacc1a7c6be88fc854ca4b0b69aff4c91 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c @@ -355,9 +355,8 @@ static int pxafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) } #ifdef CONFIG_CPU_FREQ - pr_debug("pxafb: dma period = %d ps, clock = %d kHz\n", - pxafb_display_dma_period(var), - get_clk_frequency_khz(0)); + pr_debug("pxafb: dma period = %d ps\n", + pxafb_display_dma_period(var)); #endif return 0; @@ -1301,8 +1300,8 @@ static void pxafb_decode_mode_info(struct pxafb_info *fbi, } } -static int pxafb_decode_mach_info(struct pxafb_info *fbi, - struct pxafb_mach_info *inf) +static void pxafb_decode_mach_info(struct pxafb_info *fbi, + struct pxafb_mach_info *inf) { unsigned int lcd_conn = inf->lcd_conn; @@ -1333,7 +1332,7 @@ static int pxafb_decode_mach_info(struct pxafb_info *fbi, fbi->lccr0 = inf->lccr0; fbi->lccr3 = inf->lccr3; fbi->lccr4 = inf->lccr4; - return -EINVAL; + goto decode_mode; } if (lcd_conn == LCD_MONO_STN_8BPP) @@ -1343,8 +1342,8 @@ static int pxafb_decode_mach_info(struct pxafb_info *fbi, fbi->lccr3 |= (lcd_conn & LCD_BIAS_ACTIVE_LOW) ? LCCR3_OEP : 0; fbi->lccr3 |= (lcd_conn & LCD_PCLK_EDGE_FALL) ? LCCR3_PCP : 0; +decode_mode: pxafb_decode_mode_info(fbi, inf->modes, inf->num_modes); - return 0; } static struct pxafb_info * __init pxafb_init_fbinfo(struct device *dev) diff --git a/drivers/video/sbuslib.c b/drivers/video/sbuslib.c index 4deaac05b9380b6dc74a0ce4baf24db9ef4c1ef0..37d764ad56b052a8249dc8d9062c7af07a09d167 100644 --- a/drivers/video/sbuslib.c +++ b/drivers/video/sbuslib.c @@ -10,18 +10,19 @@ #include #include #include +#include -#include #include #include "sbuslib.h" -void sbusfb_fill_var(struct fb_var_screeninfo *var, int prom_node, int bpp) +void sbusfb_fill_var(struct fb_var_screeninfo *var, struct device_node *dp, + int bpp) { memset(var, 0, sizeof(*var)); - var->xres = prom_getintdefault(prom_node, "width", 1152); - var->yres = prom_getintdefault(prom_node, "height", 900); + var->xres = of_getintprop_default(dp, "width", 1152); + var->yres = of_getintprop_default(dp, "height", 900); var->xres_virtual = var->xres; var->yres_virtual = var->yres; var->bits_per_pixel = bpp; diff --git a/drivers/video/sbuslib.h b/drivers/video/sbuslib.h index 492828c3fe8fcf4c8a3d9992bea57ef51a44a89f..7ba3250236bd7a453f32c8942c447922b03345a3 100644 --- a/drivers/video/sbuslib.h +++ b/drivers/video/sbuslib.h @@ -11,7 +11,8 @@ struct sbus_mmap_map { #define SBUS_MMAP_FBSIZE(n) (-n) #define SBUS_MMAP_EMPTY 0x80000000 -extern void sbusfb_fill_var(struct fb_var_screeninfo *var, int prom_node, int bpp); +extern void sbusfb_fill_var(struct fb_var_screeninfo *var, + struct device_node *dp, int bpp); struct vm_area_struct; extern int sbusfb_mmap_helper(struct sbus_mmap_map *map, unsigned long physbase, unsigned long fbsize, @@ -21,6 +22,6 @@ int sbusfb_ioctl_helper(unsigned long cmd, unsigned long arg, struct fb_info *info, int type, int fb_depth, unsigned long fb_size); int sbusfb_compat_ioctl(struct fb_info *info, unsigned int cmd, - unsigned long arg); + unsigned long arg); #endif /* _SBUSLIB_H */ diff --git a/drivers/video/sunxvr2500.c b/drivers/video/sunxvr2500.c index c3869a96ab5877162ea6e72960f7d0fdf73e9cd1..b1dde09e70156d31c8cfcd7a5345b241155875d7 100644 --- a/drivers/video/sunxvr2500.c +++ b/drivers/video/sunxvr2500.c @@ -9,10 +9,9 @@ #include #include #include +#include #include -#include -#include struct s3d_info { struct fb_info *info; diff --git a/drivers/video/sunxvr500.c b/drivers/video/sunxvr500.c index 71bf3f1f00bcf1b9f2aa018281494a9a2a6b0e72..c2ba51b7ea18af54dd9be3d0a6b25b90cf93edae 100644 --- a/drivers/video/sunxvr500.c +++ b/drivers/video/sunxvr500.c @@ -9,10 +9,9 @@ #include #include #include +#include #include -#include -#include /* XXX This device has a 'dev-comm' property which aparently is * XXX a pointer into the openfirmware's address space which is diff --git a/drivers/video/tcx.c b/drivers/video/tcx.c index a71774305772bb8d60270f216b53bd6a996906e5..2a03f78bbb0d53f60db6eaba3be24d09e31d4cdd 100644 --- a/drivers/video/tcx.c +++ b/drivers/video/tcx.c @@ -17,10 +17,9 @@ #include #include #include +#include #include -#include -#include #include #include "sbuslib.h" @@ -84,7 +83,7 @@ struct tcx_tec { struct tcx_thc { u32 thc_rev; - u32 thc_pad0[511]; + u32 thc_pad0[511]; u32 thc_hs; /* hsync timing */ u32 thc_hsdvs; u32 thc_hd; @@ -126,10 +125,10 @@ struct tcx_par { }; /* Reset control plane so that WID is 8-bit plane. */ -static void __tcx_set_control_plane (struct tcx_par *par) +static void __tcx_set_control_plane(struct tcx_par *par) { u32 __iomem *p, *pend; - + if (par->lowdepth) return; @@ -143,8 +142,8 @@ static void __tcx_set_control_plane (struct tcx_par *par) sbus_writel(tmp, p); } } - -static void tcx_reset (struct fb_info *info) + +static void tcx_reset(struct fb_info *info) { struct tcx_par *par = (struct tcx_par *) info->par; unsigned long flags; @@ -365,7 +364,8 @@ static void tcx_unmap_regs(struct of_device *op, struct fb_info *info, info->screen_base, par->fbsize); } -static int __devinit tcx_init_one(struct of_device *op) +static int __devinit tcx_probe(struct of_device *op, + const struct of_device_id *match) { struct device_node *dp = op->node; struct fb_info *info; @@ -384,7 +384,7 @@ static int __devinit tcx_init_one(struct of_device *op) par->lowdepth = (of_find_property(dp, "tcx-8-bit", NULL) != NULL); - sbusfb_fill_var(&info->var, dp->node, 8); + sbusfb_fill_var(&info->var, dp, 8); info->var.red.length = 8; info->var.green.length = 8; info->var.blue.length = 8; @@ -488,13 +488,6 @@ out_err: return err; } -static int __devinit tcx_probe(struct of_device *dev, const struct of_device_id *match) -{ - struct of_device *op = to_of_device(&dev->dev); - - return tcx_init_one(op); -} - static int __devexit tcx_remove(struct of_device *op) { struct fb_info *info = dev_get_drvdata(&op->dev); diff --git a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c index bd54cd0de39af13fc4170665878ed63ac1af4acb..beefab2992c042834fff60ad45a6ee92680ffcb0 100644 --- a/drivers/video/tridentfb.c +++ b/drivers/video/tridentfb.c @@ -27,7 +27,6 @@ #define VERSION "0.7.8-NEWAPI" struct tridentfb_par { - int vclk; /* in MHz */ void __iomem *io_virt; /* iospace virtual memory address */ }; @@ -669,27 +668,26 @@ static void set_screen_start(int base) (read3X4(CRTHiOrd) & 0xF8) | ((base & 0xE0000) >> 17)); } -/* Use 20.12 fixed-point for NTSC value and frequency calculation */ -#define calc_freq(n, m, k) ( ((unsigned long)0xE517 * (n + 8) / ((m + 2) * (1 << k))) >> 12 ) - /* Set dotclock frequency */ -static void set_vclk(int freq) +static void set_vclk(unsigned long freq) { int m, n, k; - int f, fi, d, di; + unsigned long f, fi, d, di; unsigned char lo = 0, hi = 0; - d = 20; + d = 20000; for (k = 2; k >= 0; k--) for (m = 0; m < 63; m++) for (n = 0; n < 128; n++) { - fi = calc_freq(n, m, k); + fi = ((14318l * (n + 8)) / (m + 2)) >> k; if ((di = abs(fi - freq)) < d) { d = di; f = fi; lo = n; hi = (k << 6) | m; } + if (fi > freq) + break; } if (chip3D) { write3C4(ClockHigh, hi); @@ -888,6 +886,8 @@ static int tridentfb_set_par(struct fb_info *info) struct fb_var_screeninfo *var = &info->var; int bpp = var->bits_per_pixel; unsigned char tmp; + unsigned long vclk; + debug("enter\n"); hdispend = var->xres / 8 - 1; hsyncstart = (var->xres + var->right_margin) / 8; @@ -905,7 +905,6 @@ static int tridentfb_set_par(struct fb_info *info) vblankstart = var->yres; vblankend = vtotal + 2; - enable_mmio(); crtc_unlock(); write3CE(CyberControl, 8); @@ -1015,11 +1014,11 @@ static int tridentfb_set_par(struct fb_info *info) write3X4(Performance, 0x92); write3X4(PCIReg, 0x07); /* MMIO & PCI read and write burst enable */ - /* convert from picoseconds to MHz */ - par->vclk = 1000000 / info->var.pixclock; + /* convert from picoseconds to kHz */ + vclk = PICOS2KHZ(info->var.pixclock); if (bpp == 32) - par->vclk *= 2; - set_vclk(par->vclk); + vclk *= 2; + set_vclk(vclk); write3C4(0, 3); write3C4(1, 1); /* set char clock 8 dots wide */ diff --git a/fs/9p/fid.h b/fs/9p/fid.h index 26e07df783b9e76ec7fa6fa4e932428ad9fa989d..c3bbd6af996dbb88a1aaeb5b20e5e167ff6589a1 100644 --- a/fs/9p/fid.h +++ b/fs/9p/fid.h @@ -22,6 +22,21 @@ #include +/** + * struct v9fs_dentry - 9p private data stored in dentry d_fsdata + * @lock: protects the fidlist + * @fidlist: list of FIDs currently associated with this dentry + * + * This structure defines the 9p private data associated with + * a particular dentry. In particular, this private data is used + * to lookup which 9P FID handle should be used for a particular VFS + * operation. FID handles are associated with dentries instead of + * inodes in order to more closely map functionality to the Plan 9 + * expected behavior for FID reclaimation and tracking. + * + * See Also: Mapping FIDs to Linux VFS model in + * Design and Implementation of the Linux 9P File System documentation + */ struct v9fs_dentry { spinlock_t lock; /* protect fidlist */ struct list_head fidlist; diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index 9b0f0222e8bbed0947f19f0baebdef0f52aabe56..047c791427aa573069a39fb9060d53c59c9d8308 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c @@ -71,19 +71,19 @@ static match_table_t tokens = { /** * v9fs_parse_options - parse mount options into session structure - * @options: options string passed from mount * @v9ses: existing v9fs session information * + * Return 0 upon success, -ERRNO upon failure. */ -static void v9fs_parse_options(struct v9fs_session_info *v9ses) +static int v9fs_parse_options(struct v9fs_session_info *v9ses) { char *options; substring_t args[MAX_OPT_ARGS]; char *p; int option = 0; char *s, *e; - int ret; + int ret = 0; /* setup defaults */ v9ses->afid = ~0; @@ -91,19 +91,26 @@ static void v9fs_parse_options(struct v9fs_session_info *v9ses) v9ses->cache = 0; if (!v9ses->options) - return; + return 0; options = kstrdup(v9ses->options, GFP_KERNEL); + if (!options) { + P9_DPRINTK(P9_DEBUG_ERROR, + "failed to allocate copy of option string\n"); + return -ENOMEM; + } + while ((p = strsep(&options, ",")) != NULL) { int token; if (!*p) continue; token = match_token(p, tokens, args); if (token < Opt_uname) { - ret = match_int(&args[0], &option); - if (ret < 0) { + int r = match_int(&args[0], &option); + if (r < 0) { P9_DPRINTK(P9_DEBUG_ERROR, "integer field, but no integer?\n"); + ret = r; continue; } } @@ -125,10 +132,10 @@ static void v9fs_parse_options(struct v9fs_session_info *v9ses) v9ses->afid = option; break; case Opt_uname: - match_strcpy(v9ses->uname, &args[0]); + match_strlcpy(v9ses->uname, &args[0], PATH_MAX); break; case Opt_remotename: - match_strcpy(v9ses->aname, &args[0]); + match_strlcpy(v9ses->aname, &args[0], PATH_MAX); break; case Opt_nodevmap: v9ses->nodev = 1; @@ -139,6 +146,13 @@ static void v9fs_parse_options(struct v9fs_session_info *v9ses) case Opt_access: s = match_strdup(&args[0]); + if (!s) { + P9_DPRINTK(P9_DEBUG_ERROR, + "failed to allocate copy" + " of option argument\n"); + ret = -ENOMEM; + break; + } v9ses->flags &= ~V9FS_ACCESS_MASK; if (strcmp(s, "user") == 0) v9ses->flags |= V9FS_ACCESS_USER; @@ -158,6 +172,7 @@ static void v9fs_parse_options(struct v9fs_session_info *v9ses) } } kfree(options); + return ret; } /** @@ -173,6 +188,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, { int retval = -EINVAL; struct p9_fid *fid; + int rc; v9ses->uname = __getname(); if (!v9ses->uname) @@ -190,8 +206,21 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, v9ses->uid = ~0; v9ses->dfltuid = V9FS_DEFUID; v9ses->dfltgid = V9FS_DEFGID; - v9ses->options = kstrdup(data, GFP_KERNEL); - v9fs_parse_options(v9ses); + if (data) { + v9ses->options = kstrdup(data, GFP_KERNEL); + if (!v9ses->options) { + P9_DPRINTK(P9_DEBUG_ERROR, + "failed to allocate copy of option string\n"); + retval = -ENOMEM; + goto error; + } + } + + rc = v9fs_parse_options(v9ses); + if (rc < 0) { + retval = rc; + goto error; + } v9ses->clnt = p9_client_create(dev_name, v9ses->options); @@ -233,7 +262,6 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, return fid; error: - v9fs_session_close(v9ses); return ERR_PTR(retval); } @@ -256,9 +284,12 @@ void v9fs_session_close(struct v9fs_session_info *v9ses) } /** - * v9fs_session_cancel - mark transport as disconnected - * and cancel all pending requests. + * v9fs_session_cancel - terminate a session + * @v9ses: session to terminate + * + * mark transport as disconnected and cancel all pending requests. */ + void v9fs_session_cancel(struct v9fs_session_info *v9ses) { P9_DPRINTK(P9_DEBUG_ERROR, "cancel session %p\n", v9ses); p9_client_disconnect(v9ses->clnt); diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h index 7d3a1018db5215ec9a410b2d789b1ea5d3e8aab5..a7d567192998e97cb292fdf313b25bea5f84fe81 100644 --- a/fs/9p/v9fs.h +++ b/fs/9p/v9fs.h @@ -21,18 +21,69 @@ * */ -/* - * Session structure provides information for an opened session - * - */ +/** + * enum p9_session_flags - option flags for each 9P session + * @V9FS_EXTENDED: whether or not to use 9P2000.u extensions + * @V9FS_ACCESS_SINGLE: only the mounting user can access the hierarchy + * @V9FS_ACCESS_USER: a new attach will be issued for every user (default) + * @V9FS_ACCESS_ANY: use a single attach for all users + * @V9FS_ACCESS_MASK: bit mask of different ACCESS options + * + * Session flags reflect options selected by users at mount time + */ +enum p9_session_flags { + V9FS_EXTENDED = 0x01, + V9FS_ACCESS_SINGLE = 0x02, + V9FS_ACCESS_USER = 0x04, + V9FS_ACCESS_ANY = 0x06, + V9FS_ACCESS_MASK = 0x06, +}; + +/* possible values of ->cache */ +/** + * enum p9_cache_modes - user specified cache preferences + * @CACHE_NONE: do not cache data, dentries, or directory contents (default) + * @CACHE_LOOSE: cache data, dentries, and directory contents w/no consistency + * + * eventually support loose, tight, time, session, default always none + */ + +enum p9_cache_modes { + CACHE_NONE, + CACHE_LOOSE, +}; + +/** + * struct v9fs_session_info - per-instance session information + * @flags: session options of type &p9_session_flags + * @nodev: set to 1 to disable device mapping + * @debug: debug level + * @afid: authentication handle + * @cache: cache mode of type &p9_cache_modes + * @options: copy of options string given by user + * @uname: string user name to mount hierarchy as + * @aname: mount specifier for remote hierarchy + * @maxdata: maximum data to be sent/recvd per protocol message + * @dfltuid: default numeric userid to mount hierarchy as + * @dfltgid: default numeric groupid to mount hierarchy as + * @uid: if %V9FS_ACCESS_SINGLE, the numeric uid which mounted the hierarchy + * @clnt: reference to 9P network client instantiated for this session + * @debugfs_dir: reference to debugfs_dir which can be used for add'l debug + * + * This structure holds state for each session instance established during + * a sys_mount() . + * + * Bugs: there seems to be a lot of state which could be condensed and/or + * removed. + */ struct v9fs_session_info { /* options */ - unsigned char flags; /* session flags */ - unsigned char nodev; /* set to 1 if no disable device mapping */ - unsigned short debug; /* debug level */ - unsigned int afid; /* authentication fid */ - unsigned int cache; /* cache mode */ + unsigned char flags; + unsigned char nodev; + unsigned short debug; + unsigned int afid; + unsigned int cache; char *options; /* copy of mount options */ char *uname; /* user name to mount as */ @@ -45,22 +96,6 @@ struct v9fs_session_info { struct dentry *debugfs_dir; }; -/* session flags */ -enum { - V9FS_EXTENDED = 0x01, /* 9P2000.u */ - V9FS_ACCESS_MASK = 0x06, /* access mask */ - V9FS_ACCESS_SINGLE = 0x02, /* only one user can access the files */ - V9FS_ACCESS_USER = 0x04, /* attache per user */ - V9FS_ACCESS_ANY = 0x06, /* use the same attach for all users */ -}; - -/* possible values of ->cache */ -/* eventually support loose, tight, time, session, default always none */ -enum { - CACHE_NONE, /* default */ - CACHE_LOOSE, /* no consistency */ -}; - extern struct dentry *v9fs_debugfs_root; struct p9_fid *v9fs_session_init(struct v9fs_session_info *, const char *, diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c index 6248f0e727a395fc1a03bfe6bb9d3aea7924f49f..97d3aed57983905f7caa660ce9474b7dc734d8e6 100644 --- a/fs/9p/vfs_addr.c +++ b/fs/9p/vfs_addr.c @@ -43,7 +43,7 @@ /** * v9fs_vfs_readpage - read an entire page in from 9P * - * @file: file being read + * @filp: file being read * @page: structure to page * */ diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c index 0924d4477da32dde44b15b2d0f5ad6896df66e59..88e3787c6ea9957081fa9fcdd05fd008b0f82472 100644 --- a/fs/9p/vfs_dir.c +++ b/fs/9p/vfs_dir.c @@ -60,7 +60,7 @@ static inline int dt_type(struct p9_stat *mistat) /** * v9fs_dir_readdir - read a directory - * @filep: opened file structure + * @filp: opened file structure * @dirent: directory structure ??? * @filldir: function to populate directory structure ??? * diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index a616fff8906d8e803c928981a8cb346f46db7d76..0d55affe37d4452124471365797ffb472e1ebe52 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c @@ -90,10 +90,11 @@ int v9fs_file_open(struct inode *inode, struct file *file) /** * v9fs_file_lock - lock a file (or directory) - * @inode: inode to be opened - * @file: file being opened + * @filp: file to be locked + * @cmd: lock command + * @fl: file lock structure * - * XXX - this looks like a local only lock, we should extend into 9P + * Bugs: this looks like a local only lock, we should extend into 9P * by using open exclusive */ @@ -118,7 +119,7 @@ static int v9fs_file_lock(struct file *filp, int cmd, struct file_lock *fl) /** * v9fs_file_read - read from a file - * @filep: file pointer to read + * @filp: file pointer to read * @data: data buffer to read data into * @count: size of buffer * @offset: offset at which to read data @@ -142,7 +143,7 @@ v9fs_file_read(struct file *filp, char __user * data, size_t count, /** * v9fs_file_write - write to a file - * @filep: file pointer to write + * @filp: file pointer to write * @data: data buffer to write data from * @count: size of buffer * @offset: offset at which to write data diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 6a28842052eac1ccf3c600817b3722c344036e7d..40fa807bd92928793ff2c66eb82024ea274e4899 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -129,6 +129,12 @@ static int p9mode2unixmode(struct v9fs_session_info *v9ses, int mode) return res; } +/** + * v9fs_uflags2omode- convert posix open flags to plan 9 mode bits + * @uflags: flags to convert + * + */ + int v9fs_uflags2omode(int uflags) { int ret; @@ -312,6 +318,14 @@ error: } */ +/** + * v9fs_inode_from_fid - populate an inode by issuing a attribute request + * @v9ses: session information + * @fid: fid to issue attribute request for + * @sb: superblock on which to create inode + * + */ + static struct inode * v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid, struct super_block *sb) @@ -384,9 +398,12 @@ v9fs_open_created(struct inode *inode, struct file *file) /** * v9fs_create - Create a file + * @v9ses: session information + * @dir: directory that dentry is being created in * @dentry: dentry that is being created * @perm: create permissions * @mode: open mode + * @extension: 9p2000.u extension string to support devices, etc. * */ static struct p9_fid * @@ -461,7 +478,7 @@ error: /** * v9fs_vfs_create - VFS hook to create files - * @inode: directory inode that is being created + * @dir: directory inode that is being created * @dentry: dentry that is being deleted * @mode: create permissions * @nd: path information @@ -519,7 +536,7 @@ error: /** * v9fs_vfs_mkdir - VFS mkdir hook to create a directory - * @inode: inode that is being unlinked + * @dir: inode that is being unlinked * @dentry: dentry that is being unlinked * @mode: mode for new directory * @@ -703,9 +720,9 @@ done: /** * v9fs_vfs_getattr - retrieve file metadata - * @mnt - mount information - * @dentry - file to get attributes on - * @stat - metadata structure to populate + * @mnt: mount information + * @dentry: file to get attributes on + * @stat: metadata structure to populate * */ @@ -928,7 +945,7 @@ done: /** * v9fs_vfs_readlink - read a symlink's location * @dentry: dentry for symlink - * @buf: buffer to load symlink location into + * @buffer: buffer to load symlink location into * @buflen: length of buffer * */ @@ -996,10 +1013,12 @@ static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd) * v9fs_vfs_put_link - release a symlink path * @dentry: dentry for symlink * @nd: nameidata + * @p: unused * */ -static void v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p) +static void +v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p) { char *s = nd_get_link(nd); @@ -1008,6 +1027,15 @@ static void v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void __putname(s); } +/** + * v9fs_vfs_mkspecial - create a special file + * @dir: inode to create special file in + * @dentry: dentry to create + * @mode: mode to create special file + * @extension: 9p2000.u format extension string representing special file + * + */ + static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry, int mode, const char *extension) { @@ -1037,7 +1065,7 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry, * @dentry: dentry for symlink * @symname: symlink data * - * See 9P2000.u RFC for more information + * See Also: 9P2000.u RFC for more information * */ @@ -1058,10 +1086,6 @@ v9fs_vfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) * */ -/* XXX - lots of code dup'd from symlink and creates, - * figure out a better reuse strategy - */ - static int v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry) @@ -1098,7 +1122,7 @@ clunk_fid: * @dir: inode destination for new link * @dentry: dentry for file * @mode: mode for creation - * @dev_t: device associated with special file + * @rdev: device associated with special file * */ diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index a452ac67fc947cc4268f17dfb77605688e1ba188..bf59c3960494c76a91bb3b0809be897166725852 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c @@ -75,6 +75,7 @@ static int v9fs_set_super(struct super_block *s, void *data) * v9fs_fill_super - populate superblock with info * @sb: superblock * @v9ses: session information + * @flags: flags propagated from v9fs_get_sb() * */ @@ -127,29 +128,26 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags, fid = v9fs_session_init(v9ses, dev_name, data); if (IS_ERR(fid)) { retval = PTR_ERR(fid); - fid = NULL; - kfree(v9ses); - v9ses = NULL; - goto error; + goto close_session; } st = p9_client_stat(fid); if (IS_ERR(st)) { retval = PTR_ERR(st); - goto error; + goto clunk_fid; } sb = sget(fs_type, NULL, v9fs_set_super, v9ses); if (IS_ERR(sb)) { retval = PTR_ERR(sb); - goto error; + goto free_stat; } v9fs_fill_super(sb, v9ses, flags); inode = v9fs_get_inode(sb, S_IFDIR | mode); if (IS_ERR(inode)) { retval = PTR_ERR(inode); - goto error; + goto release_sb; } inode->i_uid = uid; @@ -158,7 +156,7 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags, root = d_alloc_root(inode); if (!root) { retval = -ENOMEM; - goto error; + goto release_sb; } sb->s_root = root; @@ -169,21 +167,22 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags, return simple_set_mnt(mnt, sb); -error: - kfree(st); - if (fid) - p9_client_clunk(fid); - - if (v9ses) { - v9fs_session_close(v9ses); - kfree(v9ses); - } - +release_sb: if (sb) { up_write(&sb->s_umount); deactivate_super(sb); } +free_stat: + kfree(st); + +clunk_fid: + p9_client_clunk(fid); + +close_session: + v9fs_session_close(v9ses); + kfree(v9ses); + return retval; } diff --git a/fs/affs/affs.h b/fs/affs/affs.h index d5bd497ab9cbd5154ade0781ed3bffbe3d83aeb7..223b1917093ea357ffe68440199cddd7abdd0489 100644 --- a/fs/affs/affs.h +++ b/fs/affs/affs.h @@ -48,7 +48,7 @@ struct affs_ext_key { * affs fs inode data in memory */ struct affs_inode_info { - u32 i_opencnt; + atomic_t i_opencnt; struct semaphore i_link_lock; /* Protects internal inode access. */ struct semaphore i_ext_lock; /* Protects internal inode access. */ #define i_hash_lock i_ext_lock @@ -170,8 +170,6 @@ extern int affs_rename(struct inode *old_dir, struct dentry *old_dentry, extern unsigned long affs_parent_ino(struct inode *dir); extern struct inode *affs_new_inode(struct inode *dir); extern int affs_notify_change(struct dentry *dentry, struct iattr *attr); -extern void affs_put_inode(struct inode *inode); -extern void affs_drop_inode(struct inode *inode); extern void affs_delete_inode(struct inode *inode); extern void affs_clear_inode(struct inode *inode); extern struct inode *affs_iget(struct super_block *sb, diff --git a/fs/affs/file.c b/fs/affs/file.c index 1a4f092f24efdb2ab13efa4bebb85bd38e7d2678..6eac7bdeec94dc320924d7be0892fb89a23cde72 100644 --- a/fs/affs/file.c +++ b/fs/affs/file.c @@ -48,8 +48,9 @@ affs_file_open(struct inode *inode, struct file *filp) { if (atomic_read(&filp->f_count) != 1) return 0; - pr_debug("AFFS: open(%d)\n", AFFS_I(inode)->i_opencnt); - AFFS_I(inode)->i_opencnt++; + pr_debug("AFFS: open(%lu,%d)\n", + inode->i_ino, atomic_read(&AFFS_I(inode)->i_opencnt)); + atomic_inc(&AFFS_I(inode)->i_opencnt); return 0; } @@ -58,10 +59,16 @@ affs_file_release(struct inode *inode, struct file *filp) { if (atomic_read(&filp->f_count) != 0) return 0; - pr_debug("AFFS: release(%d)\n", AFFS_I(inode)->i_opencnt); - AFFS_I(inode)->i_opencnt--; - if (!AFFS_I(inode)->i_opencnt) + pr_debug("AFFS: release(%lu, %d)\n", + inode->i_ino, atomic_read(&AFFS_I(inode)->i_opencnt)); + + if (atomic_dec_and_test(&AFFS_I(inode)->i_opencnt)) { + mutex_lock(&inode->i_mutex); + if (inode->i_size != AFFS_I(inode)->mmu_private) + affs_truncate(inode); affs_free_prealloc(inode); + mutex_unlock(&inode->i_mutex); + } return 0; } @@ -180,7 +187,7 @@ affs_get_extblock(struct inode *inode, u32 ext) /* inline the simplest case: same extended block as last time */ struct buffer_head *bh = AFFS_I(inode)->i_ext_bh; if (ext == AFFS_I(inode)->i_ext_last) - atomic_inc(&bh->b_count); + get_bh(bh); else /* we have to do more (not inlined) */ bh = affs_get_extblock_slow(inode, ext); @@ -306,7 +313,7 @@ store_ext: affs_brelse(AFFS_I(inode)->i_ext_bh); AFFS_I(inode)->i_ext_last = ext; AFFS_I(inode)->i_ext_bh = bh; - atomic_inc(&bh->b_count); + get_bh(bh); return bh; @@ -324,7 +331,6 @@ affs_get_block(struct inode *inode, sector_t block, struct buffer_head *bh_resul pr_debug("AFFS: get_block(%u, %lu)\n", (u32)inode->i_ino, (unsigned long)block); - BUG_ON(block > (sector_t)0x7fffffffUL); if (block >= AFFS_I(inode)->i_blkcnt) { @@ -827,6 +833,8 @@ affs_truncate(struct inode *inode) res = mapping->a_ops->write_begin(NULL, mapping, size, 0, 0, &page, &fsdata); if (!res) res = mapping->a_ops->write_end(NULL, mapping, size, 0, 0, page, fsdata); + else + inode->i_size = AFFS_I(inode)->mmu_private; mark_inode_dirty(inode); return; } else if (inode->i_size == AFFS_I(inode)->mmu_private) @@ -862,6 +870,7 @@ affs_truncate(struct inode *inode) blk++; } else AFFS_HEAD(ext_bh)->first_data = 0; + AFFS_HEAD(ext_bh)->block_count = cpu_to_be32(i); size = AFFS_SB(sb)->s_hashsize; if (size > blkcnt - blk + i) size = blkcnt - blk + i; diff --git a/fs/affs/inode.c b/fs/affs/inode.c index 27fe6cbe43ae84bc1582f8e86131cebb1566eb1e..a13b334a391029a60de7426ae1f4684f1fd1f5a3 100644 --- a/fs/affs/inode.c +++ b/fs/affs/inode.c @@ -58,7 +58,7 @@ struct inode *affs_iget(struct super_block *sb, unsigned long ino) AFFS_I(inode)->i_extcnt = 1; AFFS_I(inode)->i_ext_last = ~1; AFFS_I(inode)->i_protect = prot; - AFFS_I(inode)->i_opencnt = 0; + atomic_set(&AFFS_I(inode)->i_opencnt, 0); AFFS_I(inode)->i_blkcnt = 0; AFFS_I(inode)->i_lc = NULL; AFFS_I(inode)->i_lc_size = 0; @@ -108,8 +108,6 @@ struct inode *affs_iget(struct super_block *sb, unsigned long ino) inode->i_mode |= S_IFDIR; } else inode->i_mode = S_IRUGO | S_IXUGO | S_IWUSR | S_IFDIR; - if (tail->link_chain) - inode->i_nlink = 2; /* Maybe it should be controlled by mount parameter? */ //inode->i_mode |= S_ISVTX; inode->i_op = &affs_dir_inode_operations; @@ -244,32 +242,13 @@ out: return error; } -void -affs_put_inode(struct inode *inode) -{ - pr_debug("AFFS: put_inode(ino=%lu, nlink=%u)\n", inode->i_ino, inode->i_nlink); - affs_free_prealloc(inode); -} - -void -affs_drop_inode(struct inode *inode) -{ - mutex_lock(&inode->i_mutex); - if (inode->i_size != AFFS_I(inode)->mmu_private) - affs_truncate(inode); - mutex_unlock(&inode->i_mutex); - - generic_drop_inode(inode); -} - void affs_delete_inode(struct inode *inode) { pr_debug("AFFS: delete_inode(ino=%lu, nlink=%u)\n", inode->i_ino, inode->i_nlink); truncate_inode_pages(&inode->i_data, 0); inode->i_size = 0; - if (S_ISREG(inode->i_mode)) - affs_truncate(inode); + affs_truncate(inode); clear_inode(inode); affs_free_block(inode->i_sb, inode->i_ino); } @@ -277,9 +256,12 @@ affs_delete_inode(struct inode *inode) void affs_clear_inode(struct inode *inode) { - unsigned long cache_page = (unsigned long) AFFS_I(inode)->i_lc; + unsigned long cache_page; pr_debug("AFFS: clear_inode(ino=%lu, nlink=%u)\n", inode->i_ino, inode->i_nlink); + + affs_free_prealloc(inode); + cache_page = (unsigned long)AFFS_I(inode)->i_lc; if (cache_page) { pr_debug("AFFS: freeing ext cache\n"); AFFS_I(inode)->i_lc = NULL; @@ -316,7 +298,7 @@ affs_new_inode(struct inode *dir) inode->i_ino = block; inode->i_nlink = 1; inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; - AFFS_I(inode)->i_opencnt = 0; + atomic_set(&AFFS_I(inode)->i_opencnt, 0); AFFS_I(inode)->i_blkcnt = 0; AFFS_I(inode)->i_lc = NULL; AFFS_I(inode)->i_lc_size = 0; @@ -369,12 +351,12 @@ affs_add_entry(struct inode *dir, struct inode *inode, struct dentry *dentry, s3 switch (type) { case ST_LINKFILE: case ST_LINKDIR: - inode_bh = bh; retval = -ENOSPC; block = affs_alloc_block(dir, dir->i_ino); if (!block) goto err; retval = -EIO; + inode_bh = bh; bh = affs_getzeroblk(sb, block); if (!bh) goto err; diff --git a/fs/affs/namei.c b/fs/affs/namei.c index 2218f1ee71ce1c2cc146ccd876d614c78fce94cd..cfcf1b6cf82be05dbd9001e494c55cfa26b4b790 100644 --- a/fs/affs/namei.c +++ b/fs/affs/namei.c @@ -234,7 +234,8 @@ affs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) int affs_unlink(struct inode *dir, struct dentry *dentry) { - pr_debug("AFFS: unlink(dir=%d, \"%.*s\")\n", (u32)dir->i_ino, + pr_debug("AFFS: unlink(dir=%d, %lu \"%.*s\")\n", (u32)dir->i_ino, + dentry->d_inode->i_ino, (int)dentry->d_name.len, dentry->d_name.name); return affs_remove_header(dentry); @@ -302,7 +303,8 @@ affs_mkdir(struct inode *dir, struct dentry *dentry, int mode) int affs_rmdir(struct inode *dir, struct dentry *dentry) { - pr_debug("AFFS: rmdir(dir=%u, \"%.*s\")\n", (u32)dir->i_ino, + pr_debug("AFFS: rmdir(dir=%u, %lu \"%.*s\")\n", (u32)dir->i_ino, + dentry->d_inode->i_ino, (int)dentry->d_name.len, dentry->d_name.name); return affs_remove_header(dentry); diff --git a/fs/affs/super.c b/fs/affs/super.c index 01d25d532541bc3d698f5321923a87cf9900cfe4..d214837d5e42a868009d75084e27716f7937e0b2 100644 --- a/fs/affs/super.c +++ b/fs/affs/super.c @@ -71,12 +71,18 @@ static struct kmem_cache * affs_inode_cachep; static struct inode *affs_alloc_inode(struct super_block *sb) { - struct affs_inode_info *ei; - ei = (struct affs_inode_info *)kmem_cache_alloc(affs_inode_cachep, GFP_KERNEL); - if (!ei) + struct affs_inode_info *i; + + i = kmem_cache_alloc(affs_inode_cachep, GFP_KERNEL); + if (!i) return NULL; - ei->vfs_inode.i_version = 1; - return &ei->vfs_inode; + + i->vfs_inode.i_version = 1; + i->i_lc = NULL; + i->i_ext_bh = NULL; + i->i_pa_cnt = 0; + + return &i->vfs_inode; } static void affs_destroy_inode(struct inode *inode) @@ -114,8 +120,6 @@ static const struct super_operations affs_sops = { .alloc_inode = affs_alloc_inode, .destroy_inode = affs_destroy_inode, .write_inode = affs_write_inode, - .put_inode = affs_put_inode, - .drop_inode = affs_drop_inode, .delete_inode = affs_delete_inode, .clear_inode = affs_clear_inode, .put_super = affs_put_super, diff --git a/fs/befs/endian.h b/fs/befs/endian.h index e254a20869f4084bca2fd850af876919fd935ccb..6cb84d896d050f5184b86e46655d27d21f78cbd6 100644 --- a/fs/befs/endian.h +++ b/fs/befs/endian.h @@ -9,7 +9,7 @@ #ifndef LINUX_BEFS_ENDIAN #define LINUX_BEFS_ENDIAN -#include +#include static inline u64 fs64_to_cpu(const struct super_block *sb, fs64 n) diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index b25707fee2ccad4598146224a5b5c5abcf3c2f99..0fa95b198e6e9c89f5f4166b45666bdf6171c730 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -256,7 +256,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, return -EFAULT; len = strnlen_user((void __user *)p, MAX_ARG_STRLEN); if (!len || len > MAX_ARG_STRLEN) - return 0; + return -EINVAL; p += len; } if (__put_user(0, argv)) @@ -268,7 +268,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, return -EFAULT; len = strnlen_user((void __user *)p, MAX_ARG_STRLEN); if (!len || len > MAX_ARG_STRLEN) - return 0; + return -EINVAL; p += len; } if (__put_user(0, envp)) @@ -1900,7 +1900,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file, un /* alloc memory for large data structures: too large to be on stack */ elf = kmalloc(sizeof(*elf), GFP_KERNEL); if (!elf) - goto cleanup; + goto out; segs = current->mm->map_count; #ifdef ELF_CORE_EXTRA_PHDRS @@ -2034,8 +2034,9 @@ end_coredump: set_fs(fs); cleanup: - kfree(elf); free_note_info(&info); + kfree(elf); +out: return has_dumped; } diff --git a/fs/bio.c b/fs/bio.c index 799f86deff243213256103ee76ff7560098fe965..78562574cb524d87b06883bce5002542b77b5865 100644 --- a/fs/bio.c +++ b/fs/bio.c @@ -158,7 +158,7 @@ struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs) bio_init(bio); if (likely(nr_iovecs)) { - unsigned long idx = 0; /* shut up gcc */ + unsigned long uninitialized_var(idx); bvl = bvec_alloc_bs(gfp_mask, nr_iovecs, &idx, bs); if (unlikely(!bvl)) { @@ -963,6 +963,7 @@ static void bio_copy_kern_endio(struct bio *bio, int err) * @data: pointer to buffer to copy * @len: length in bytes * @gfp_mask: allocation flags for bio and page allocation + * @reading: data direction is READ * * copy the kernel address into a bio suitable for io to a block * device. Returns an error pointer in case of error. diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 05c9da6181c3793cd540c803053fc2bd21e08bbc..8355e918fddf3e43d83d6fb6ac13e72bcb06c210 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES @@ -1,3 +1,6 @@ +Version 1.53 +------------ + Version 1.52 ------------ Fix oops on second mount to server when null auth is used. diff --git a/fs/cifs/asn1.c b/fs/cifs/asn1.c index bcda2c6b6a048db68697246a61040e41f6b35da6..cb52cbbe45ff4704790ec4ffbf0a985e3423f492 100644 --- a/fs/cifs/asn1.c +++ b/fs/cifs/asn1.c @@ -460,8 +460,8 @@ decode_negTokenInit(unsigned char *security_blob, int length, unsigned char *sequence_end; unsigned long *oid = NULL; unsigned int cls, con, tag, oidlen, rc; - int use_ntlmssp = FALSE; - int use_kerberos = FALSE; + bool use_ntlmssp = false; + bool use_kerberos = false; *secType = NTLM; /* BB eventually make Kerberos or NLTMSSP the default*/ @@ -561,15 +561,15 @@ decode_negTokenInit(unsigned char *security_blob, int length, if (compare_oid(oid, oidlen, MSKRB5_OID, MSKRB5_OID_LEN)) - use_kerberos = TRUE; + use_kerberos = true; else if (compare_oid(oid, oidlen, KRB5_OID, KRB5_OID_LEN)) - use_kerberos = TRUE; + use_kerberos = true; else if (compare_oid(oid, oidlen, NTLMSSP_OID, NTLMSSP_OID_LEN)) - use_ntlmssp = TRUE; + use_ntlmssp = true; kfree(oid); } diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c index 95024c066d89d6422e7a1adb233a7fb38e76473a..f6fdecf6598c7dbe634e9515f3aa1926bc3d9b87 100644 --- a/fs/cifs/cifs_dfs_ref.c +++ b/fs/cifs/cifs_dfs_ref.c @@ -93,15 +93,11 @@ static char *cifs_get_share_name(const char *node_name) /* find sharename end */ pSep++; pSep = memchr(UNC+(pSep-UNC), '\\', len-(pSep-UNC)); - if (!pSep) { - cERROR(1, ("%s:2 cant find share name in node name: %s", - __func__, node_name)); - kfree(UNC); - return NULL; + if (pSep) { + /* trim path up to sharename end + * now we have share name in UNC */ + *pSep = 0; } - /* trim path up to sharename end - * * now we have share name in UNC */ - *pSep = 0; return UNC; } @@ -188,7 +184,7 @@ static char *compose_mount_options(const char *sb_mountdata, tkn_e = strchr(tkn_e+1, '\\'); if (tkn_e) { strcat(mountdata, ",prefixpath="); - strcat(mountdata, tkn_e); + strcat(mountdata, tkn_e+1); } } @@ -244,7 +240,8 @@ static char *build_full_dfs_path_from_dentry(struct dentry *dentry) return NULL; if (cifs_sb->tcon->Flags & SMB_SHARE_IS_IN_DFS) { - /* we should use full path name to correct working with DFS */ + int i; + /* we should use full path name for correct working with DFS */ l_max_len = strnlen(cifs_sb->tcon->treeName, MAX_TREE_SIZE+1) + strnlen(search_path, MAX_PATHCONF) + 1; tmp_path = kmalloc(l_max_len, GFP_KERNEL); @@ -253,8 +250,14 @@ static char *build_full_dfs_path_from_dentry(struct dentry *dentry) return NULL; } strncpy(tmp_path, cifs_sb->tcon->treeName, l_max_len); - strcat(tmp_path, search_path); tmp_path[l_max_len-1] = 0; + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) + for (i = 0; i < l_max_len; i++) { + if (tmp_path[i] == '\\') + tmp_path[i] = '/'; + } + strncat(tmp_path, search_path, l_max_len - strlen(tmp_path)); + full_path = tmp_path; kfree(search_path); } else { diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index e99d4faf5f022e5c3315dbd38b63e12e85ccf0e7..34902cff540059988efa9e014b76cc63a8b10d15 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c @@ -559,7 +559,7 @@ static struct cifs_ntsd *get_cifs_acl(u32 *pacllen, struct inode *inode, const char *path, const __u16 *pfid) { struct cifsFileInfo *open_file = NULL; - int unlock_file = FALSE; + bool unlock_file = false; int xid; int rc = -EIO; __u16 fid; @@ -586,10 +586,10 @@ static struct cifs_ntsd *get_cifs_acl(u32 *pacllen, struct inode *inode, cifs_sb = CIFS_SB(sb); if (open_file) { - unlock_file = TRUE; + unlock_file = true; fid = open_file->netfid; } else if (pfid == NULL) { - int oplock = FALSE; + int oplock = 0; /* open file */ rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN, READ_CONTROL, 0, &fid, &oplock, NULL, @@ -604,7 +604,7 @@ static struct cifs_ntsd *get_cifs_acl(u32 *pacllen, struct inode *inode, rc = CIFSSMBGetCIFSACL(xid, cifs_sb->tcon, fid, &pntsd, pacllen); cFYI(1, ("GetCIFSACL rc = %d ACL len %d", rc, *pacllen)); - if (unlock_file == TRUE) /* find_readable_file increments ref count */ + if (unlock_file == true) /* find_readable_file increments ref count */ atomic_dec(&open_file->wrtPending); else if (pfid == NULL) /* if opened above we have to close the handle */ CIFSSMBClose(xid, cifs_sb->tcon, fid); @@ -619,7 +619,7 @@ static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen, struct inode *inode, const char *path) { struct cifsFileInfo *open_file; - int unlock_file = FALSE; + bool unlock_file = false; int xid; int rc = -EIO; __u16 fid; @@ -640,10 +640,10 @@ static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen, open_file = find_readable_file(CIFS_I(inode)); if (open_file) { - unlock_file = TRUE; + unlock_file = true; fid = open_file->netfid; } else { - int oplock = FALSE; + int oplock = 0; /* open file */ rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN, WRITE_DAC, 0, &fid, &oplock, NULL, @@ -658,7 +658,7 @@ static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen, rc = CIFSSMBSetCIFSACL(xid, cifs_sb->tcon, fid, pnntsd, acllen); cFYI(DBG2, ("SetCIFSACL rc = %d", rc)); - if (unlock_file == TRUE) + if (unlock_file) atomic_dec(&open_file->wrtPending); else CIFSSMBClose(xid, cifs_sb->tcon, fid); diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 39c2cbdface7b52e27ef8f79820caa6e1d350eff..427a7c695896ff87c1d463d595e29126d5aa5a44 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -222,50 +222,50 @@ static int cifs_statfs(struct dentry *dentry, struct kstatfs *buf) { struct super_block *sb = dentry->d_sb; - int xid; + struct cifs_sb_info *cifs_sb = CIFS_SB(sb); + struct cifsTconInfo *tcon = cifs_sb->tcon; int rc = -EOPNOTSUPP; - struct cifs_sb_info *cifs_sb; - struct cifsTconInfo *pTcon; + int xid; xid = GetXid(); - cifs_sb = CIFS_SB(sb); - pTcon = cifs_sb->tcon; - buf->f_type = CIFS_MAGIC_NUMBER; - /* instead could get the real value via SMB_QUERY_FS_ATTRIBUTE_INFO */ - buf->f_namelen = PATH_MAX; /* PATH_MAX may be too long - it would - presumably be total path, but note - that some servers (includinng Samba 3) - have a shorter maximum path */ + /* + * PATH_MAX may be too long - it would presumably be total path, + * but note that some servers (includinng Samba 3) have a shorter + * maximum path. + * + * Instead could get the real value via SMB_QUERY_FS_ATTRIBUTE_INFO. + */ + buf->f_namelen = PATH_MAX; buf->f_files = 0; /* undefined */ buf->f_ffree = 0; /* unlimited */ -/* BB we could add a second check for a QFS Unix capability bit */ -/* BB FIXME check CIFS_POSIX_EXTENSIONS Unix cap first FIXME BB */ - if ((pTcon->ses->capabilities & CAP_UNIX) && (CIFS_POSIX_EXTENSIONS & - le64_to_cpu(pTcon->fsUnixInfo.Capability))) - rc = CIFSSMBQFSPosixInfo(xid, pTcon, buf); - - /* Only need to call the old QFSInfo if failed - on newer one */ - if (rc) - if (pTcon->ses->capabilities & CAP_NT_SMBS) - rc = CIFSSMBQFSInfo(xid, pTcon, buf); /* not supported by OS2 */ - - /* Some old Windows servers also do not support level 103, retry with - older level one if old server failed the previous call or we - bypassed it because we detected that this was an older LANMAN sess */ + /* + * We could add a second check for a QFS Unix capability bit + */ + if ((tcon->ses->capabilities & CAP_UNIX) && + (CIFS_POSIX_EXTENSIONS & le64_to_cpu(tcon->fsUnixInfo.Capability))) + rc = CIFSSMBQFSPosixInfo(xid, tcon, buf); + + /* + * Only need to call the old QFSInfo if failed on newer one, + * e.g. by OS/2. + **/ + if (rc && (tcon->ses->capabilities & CAP_NT_SMBS)) + rc = CIFSSMBQFSInfo(xid, tcon, buf); + + /* + * Some old Windows servers also do not support level 103, retry with + * older level one if old server failed the previous call or we + * bypassed it because we detected that this was an older LANMAN sess + */ if (rc) - rc = SMBOldQFSInfo(xid, pTcon, buf); - /* int f_type; - __fsid_t f_fsid; - int f_namelen; */ - /* BB get from info in tcon struct at mount time call to QFSAttrInfo */ + rc = SMBOldQFSInfo(xid, tcon, buf); + FreeXid(xid); - return 0; /* always return success? what if volume is no - longer available? */ + return 0; } static int cifs_permission(struct inode *inode, int mask, struct nameidata *nd) @@ -306,8 +306,8 @@ cifs_alloc_inode(struct super_block *sb) /* Until the file is open and we have gotten oplock info back from the server, can not assume caching of file data or metadata */ - cifs_inode->clientCanCacheRead = FALSE; - cifs_inode->clientCanCacheAll = FALSE; + cifs_inode->clientCanCacheRead = false; + cifs_inode->clientCanCacheAll = false; cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */ /* Can not set i_flags here - they get immediately overwritten @@ -940,7 +940,7 @@ static int cifs_oplock_thread(void *dummyarg) rc = CIFSSMBLock(0, pTcon, netfid, 0 /* len */ , 0 /* offset */, 0, 0, LOCKING_ANDX_OPLOCK_RELEASE, - 0 /* wait flag */); + false /* wait flag */); cFYI(1, ("Oplock release rc = %d", rc)); } } else diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index e1dd9f32e1d7600610ed084fa44548f7d153acb5..cd1301a09b3b5a3886d8a7ee1eee1923a8cd1027 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h @@ -24,14 +24,6 @@ #define ROOT_I 2 -#ifndef FALSE -#define FALSE 0 -#endif - -#ifndef TRUE -#define TRUE 1 -#endif - extern struct file_system_type cifs_fs_type; extern const struct address_space_operations cifs_addr_ops; extern const struct address_space_operations cifs_addr_ops_smallbuf; @@ -110,5 +102,5 @@ extern int cifs_ioctl(struct inode *inode, struct file *filep, extern const struct export_operations cifs_export_ops; #endif /* EXPERIMENTAL */ -#define CIFS_VERSION "1.52" +#define CIFS_VERSION "1.53" #endif /* _CIFSFS_H */ diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 69a2e1942542e1601e9e66078a1c052b86d51742..b7d9f698e63ec5e04ace67469025be11053b423f 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -57,14 +57,6 @@ #include "cifspdu.h" -#ifndef FALSE -#define FALSE 0 -#endif - -#ifndef TRUE -#define TRUE 1 -#endif - #ifndef XATTR_DOS_ATTRIB #define XATTR_DOS_ATTRIB "user.DOSATTRIB" #endif @@ -147,7 +139,7 @@ struct TCP_Server_Info { enum protocolEnum protocolType; char versionMajor; char versionMinor; - unsigned svlocal:1; /* local server or remote */ + bool svlocal:1; /* local server or remote */ atomic_t socketUseCount; /* number of open cifs sessions on socket */ atomic_t inFlight; /* number of requests on the wire to server */ #ifdef CONFIG_CIFS_STATS2 @@ -286,10 +278,10 @@ struct cifsTconInfo { FILE_SYSTEM_DEVICE_INFO fsDevInfo; FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* ok if fs name truncated */ FILE_SYSTEM_UNIX_INFO fsUnixInfo; - unsigned ipc:1; /* set if connection to IPC$ eg for RPC/PIPES */ - unsigned retry:1; - unsigned nocase:1; - unsigned unix_ext:1; /* if off disable Linux extensions to CIFS protocol + bool ipc:1; /* set if connection to IPC$ eg for RPC/PIPES */ + bool retry:1; + bool nocase:1; + bool unix_ext:1; /* if false disable Linux extensions to CIFS protocol for this mount even if server would support */ /* BB add field for back pointer to sb struct(s)? */ }; @@ -317,10 +309,10 @@ struct cifs_search_info { char *srch_entries_start; char *presume_name; unsigned int resume_name_len; - unsigned endOfSearch:1; - unsigned emptyDir:1; - unsigned unicode:1; - unsigned smallBuf:1; /* so we know which buf_release function to call */ + bool endOfSearch:1; + bool emptyDir:1; + bool unicode:1; + bool smallBuf:1; /* so we know which buf_release function to call */ }; struct cifsFileInfo { @@ -335,9 +327,9 @@ struct cifsFileInfo { struct inode *pInode; /* needed for oplock break */ struct mutex lock_mutex; struct list_head llist; /* list of byte range locks we have. */ - unsigned closePend:1; /* file is marked to close */ - unsigned invalidHandle:1; /* file closed via session abend */ - unsigned messageMode:1; /* for pipes: message vs byte mode */ + bool closePend:1; /* file is marked to close */ + bool invalidHandle:1; /* file closed via session abend */ + bool messageMode:1; /* for pipes: message vs byte mode */ atomic_t wrtPending; /* handle in use - defer close */ struct semaphore fh_sem; /* prevents reopen race after dead ses*/ char *search_resume_name; /* BB removeme BB */ @@ -356,9 +348,9 @@ struct cifsInodeInfo { __u32 cifsAttrs; /* e.g. DOS archive bit, sparse, compressed, system */ atomic_t inUse; /* num concurrent users (local openers cifs) of file*/ unsigned long time; /* jiffies of last update/check of inode */ - unsigned clientCanCacheRead:1; /* read oplock */ - unsigned clientCanCacheAll:1; /* read and writebehind oplock */ - unsigned oplockPending:1; + bool clientCanCacheRead:1; /* read oplock */ + bool clientCanCacheAll:1; /* read and writebehind oplock */ + bool oplockPending:1; struct inode vfs_inode; }; @@ -426,9 +418,9 @@ struct mid_q_entry { struct smb_hdr *resp_buf; /* response buffer */ int midState; /* wish this were enum but can not pass to wait_event */ __u8 command; /* smb command code */ - unsigned largeBuf:1; /* if valid response, is pointer to large buf */ - unsigned multiRsp:1; /* multiple trans2 responses for one request */ - unsigned multiEnd:1; /* both received */ + bool largeBuf:1; /* if valid response, is pointer to large buf */ + bool multiRsp:1; /* multiple trans2 responses for one request */ + bool multiEnd:1; /* both received */ }; struct oplock_q_entry { diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index 9f49c2f3582c03bfa6f217776548605370cd00a4..c43bf4b7a5563e0bb63cb03768b35a434658d1bd 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h @@ -340,6 +340,7 @@ #define OPEN_NO_RECALL 0x00400000 #define OPEN_FREE_SPACE_QUERY 0x00800000 /* should be zero */ #define CREATE_OPTIONS_MASK 0x007FFFFF +#define CREATE_OPTION_READONLY 0x10000000 #define CREATE_OPTION_SPECIAL 0x20000000 /* system. NB not sent over wire */ /* ImpersonationLevel flags */ @@ -2050,7 +2051,7 @@ typedef struct { to 0xFFFF00 */ #define CIFS_UNIX_LARGE_WRITE_CAP 0x00000080 #define CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP 0x00000100 /* can do SPNEGO crypt */ -#define CIFS_UNIX_TRANPSORT_ENCRYPTION_MANDATORY_CAP 0x00000200 /* must do */ +#define CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP 0x00000200 /* must do */ #define CIFS_UNIX_PROXY_CAP 0x00000400 /* Proxy cap: 0xACE ioctl and QFS PROXY call */ #ifdef CONFIG_CIFS_POSIX diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 50f9fdae19b3d7c97a5638120b56201af3630312..d481f6c5a2be9e5ba76b2ea9af2b3a7657fa772c 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -59,8 +59,9 @@ extern int SendReceiveBlockingLock(const unsigned int xid, struct smb_hdr *out_buf, int *bytes_returned); extern int checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length); -extern int is_valid_oplock_break(struct smb_hdr *smb, struct TCP_Server_Info *); -extern int is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof); +extern bool is_valid_oplock_break(struct smb_hdr *smb, + struct TCP_Server_Info *); +extern bool is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof); extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *); #ifdef CONFIG_CIFS_EXPERIMENTAL extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *); @@ -69,7 +70,7 @@ extern unsigned int smbCalcSize(struct smb_hdr *ptr); extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr); extern int decode_negTokenInit(unsigned char *security_blob, int length, enum securityEnum *secType); -extern int cifs_inet_pton(int, char *source, void *dst); +extern int cifs_inet_pton(const int, const char *source, void *dst); extern int map_smb_to_linux_error(struct smb_hdr *smb, int logErr); extern void header_assemble(struct smb_hdr *, char /* command */ , const struct cifsTconInfo *, int /* length of @@ -187,12 +188,12 @@ extern int CIFSSMBSetAttrLegacy(int xid, struct cifsTconInfo *tcon, #endif /* possibly unneeded function */ extern int CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon, const char *fileName, __u64 size, - int setAllocationSizeFlag, + bool setAllocationSizeFlag, const struct nls_table *nls_codepage, int remap_special_chars); extern int CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size, __u16 fileHandle, __u32 opener_pid, - int AllocSizeFlag); + bool AllocSizeFlag); extern int CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *pTcon, char *full_path, __u64 mode, __u64 uid, __u64 gid, dev_t dev, @@ -291,11 +292,11 @@ extern int CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, const __u16 netfid, const __u64 len, const __u64 offset, const __u32 numUnlock, const __u32 numLock, const __u8 lockType, - const int waitFlag); + const bool waitFlag); extern int CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, const __u16 smb_file_id, const int get_flag, const __u64 len, struct file_lock *, - const __u16 lock_type, const int waitFlag); + const __u16 lock_type, const bool waitFlag); extern int CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon); extern int CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses); diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 4728fa982a4ed965237427b7386b838266ec497b..95fbba4ea7d47213fd9de11536fb02c6bb0c5bfa 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -95,7 +95,7 @@ static void mark_open_files_invalid(struct cifsTconInfo *pTcon) list_for_each_safe(tmp, tmp1, &pTcon->openFileList) { open_file = list_entry(tmp, struct cifsFileInfo, tlist); if (open_file) - open_file->invalidHandle = TRUE; + open_file->invalidHandle = true; } write_unlock(&GlobalSMBSeslock); /* BB Add call to invalidate_inodes(sb) for all superblocks mounted @@ -141,7 +141,7 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, if (tcon->ses->server->tcpStatus == CifsNeedReconnect) { /* on "soft" mounts we wait once */ - if ((tcon->retry == FALSE) || + if (!tcon->retry || (tcon->ses->status == CifsExiting)) { cFYI(1, ("gave up waiting on " "reconnect in smb_init")); @@ -289,7 +289,7 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, if (tcon->ses->server->tcpStatus == CifsNeedReconnect) { /* on "soft" mounts we wait once */ - if ((tcon->retry == FALSE) || + if (!tcon->retry || (tcon->ses->status == CifsExiting)) { cFYI(1, ("gave up waiting on " "reconnect in smb_init")); @@ -1224,11 +1224,8 @@ OldOpenRetry: else /* BB FIXME BB */ pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/); - /* if ((omode & S_IWUGO) == 0) - pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);*/ - /* Above line causes problems due to vfs splitting create into two - pieces - need to set mode after file created not while it is - being created */ + if (create_options & CREATE_OPTION_READONLY) + pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY); /* BB FIXME BB */ /* pSMB->CreateOptions = cpu_to_le32(create_options & @@ -1331,17 +1328,16 @@ openRetry: pSMB->FileAttributes = cpu_to_le32(ATTR_SYSTEM); else pSMB->FileAttributes = cpu_to_le32(ATTR_NORMAL); + /* XP does not handle ATTR_POSIX_SEMANTICS */ /* but it helps speed up case sensitive checks for other servers such as Samba */ if (tcon->ses->capabilities & CAP_UNIX) pSMB->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS); - /* if ((omode & S_IWUGO) == 0) - pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);*/ - /* Above line causes problems due to vfs splitting create into two - pieces - need to set mode after file created not while it is - being created */ + if (create_options & CREATE_OPTION_READONLY) + pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY); + pSMB->ShareAccess = cpu_to_le32(FILE_SHARE_ALL); pSMB->CreateDisposition = cpu_to_le32(openDisposition); pSMB->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK); @@ -1686,7 +1682,7 @@ int CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, const __u16 smb_file_id, const __u64 len, const __u64 offset, const __u32 numUnlock, - const __u32 numLock, const __u8 lockType, const int waitFlag) + const __u32 numLock, const __u8 lockType, const bool waitFlag) { int rc = 0; LOCK_REQ *pSMB = NULL; @@ -1695,7 +1691,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, int timeout = 0; __u16 count; - cFYI(1, ("CIFSSMBLock timeout %d numLock %d", waitFlag, numLock)); + cFYI(1, ("CIFSSMBLock timeout %d numLock %d", (int)waitFlag, numLock)); rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB); if (rc) @@ -1706,7 +1702,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) { timeout = CIFS_ASYNC_OP; /* no response expected */ pSMB->Timeout = 0; - } else if (waitFlag == TRUE) { + } else if (waitFlag) { timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */ pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */ } else { @@ -1756,7 +1752,7 @@ int CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, const __u16 smb_file_id, const int get_flag, const __u64 len, struct file_lock *pLockData, const __u16 lock_type, - const int waitFlag) + const bool waitFlag) { struct smb_com_transaction2_sfi_req *pSMB = NULL; struct smb_com_transaction2_sfi_rsp *pSMBr = NULL; @@ -3581,9 +3577,9 @@ findFirstRetry: rc = validate_t2((struct smb_t2_rsp *)pSMBr); if (rc == 0) { if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) - psrch_inf->unicode = TRUE; + psrch_inf->unicode = true; else - psrch_inf->unicode = FALSE; + psrch_inf->unicode = false; psrch_inf->ntwrk_buf_start = (char *)pSMBr; psrch_inf->smallBuf = 0; @@ -3594,9 +3590,9 @@ findFirstRetry: le16_to_cpu(pSMBr->t2.ParameterOffset)); if (parms->EndofSearch) - psrch_inf->endOfSearch = TRUE; + psrch_inf->endOfSearch = true; else - psrch_inf->endOfSearch = FALSE; + psrch_inf->endOfSearch = false; psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount); @@ -3624,7 +3620,7 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon, cFYI(1, ("In FindNext")); - if (psrch_inf->endOfSearch == TRUE) + if (psrch_inf->endOfSearch) return -ENOENT; rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, @@ -3682,7 +3678,7 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon, cifs_stats_inc(&tcon->num_fnext); if (rc) { if (rc == -EBADF) { - psrch_inf->endOfSearch = TRUE; + psrch_inf->endOfSearch = true; rc = 0; /* search probably was closed at end of search*/ } else cFYI(1, ("FindNext returned = %d", rc)); @@ -3692,9 +3688,9 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon, if (rc == 0) { /* BB fixme add lock for file (srch_info) struct here */ if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) - psrch_inf->unicode = TRUE; + psrch_inf->unicode = true; else - psrch_inf->unicode = FALSE; + psrch_inf->unicode = false; response_data = (char *) &pSMBr->hdr.Protocol + le16_to_cpu(pSMBr->t2.ParameterOffset); parms = (T2_FNEXT_RSP_PARMS *)response_data; @@ -3709,9 +3705,9 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon, psrch_inf->ntwrk_buf_start = (char *)pSMB; psrch_inf->smallBuf = 0; if (parms->EndofSearch) - psrch_inf->endOfSearch = TRUE; + psrch_inf->endOfSearch = true; else - psrch_inf->endOfSearch = FALSE; + psrch_inf->endOfSearch = false; psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount); psrch_inf->index_of_last_entry += @@ -4586,7 +4582,7 @@ QFSPosixRetry: int CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon, const char *fileName, - __u64 size, int SetAllocation, + __u64 size, bool SetAllocation, const struct nls_table *nls_codepage, int remap) { struct smb_com_transaction2_spi_req *pSMB = NULL; @@ -4675,7 +4671,7 @@ SetEOFRetry: int CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size, - __u16 fid, __u32 pid_of_opener, int SetAllocation) + __u16 fid, __u32 pid_of_opener, bool SetAllocation) { struct smb_com_transaction2_sfi_req *pSMB = NULL; char *data_offset; diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index e171067301689dee90ed97de96fc2fcb7eb3f518..f428bf3bf1a96a3026754119fb4c40b0a37606a9 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -49,8 +49,6 @@ #define CIFS_PORT 445 #define RFC1001_PORT 139 -static DECLARE_COMPLETION(cifsd_complete); - extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24); @@ -71,23 +69,23 @@ struct smb_vol { mode_t file_mode; mode_t dir_mode; unsigned secFlg; - unsigned rw:1; - unsigned retry:1; - unsigned intr:1; - unsigned setuids:1; - unsigned override_uid:1; - unsigned override_gid:1; - unsigned noperm:1; - unsigned no_psx_acl:1; /* set if posix acl support should be disabled */ - unsigned cifs_acl:1; - unsigned no_xattr:1; /* set if xattr (EA) support should be disabled*/ - unsigned server_ino:1; /* use inode numbers from server ie UniqueId */ - unsigned direct_io:1; - unsigned remap:1; /* set to remap seven reserved chars in filenames */ - unsigned posix_paths:1; /* unset to not ask for posix pathnames. */ - unsigned no_linux_ext:1; - unsigned sfu_emul:1; - unsigned nullauth:1; /* attempt to authenticate with null user */ + bool rw:1; + bool retry:1; + bool intr:1; + bool setuids:1; + bool override_uid:1; + bool override_gid:1; + bool noperm:1; + bool no_psx_acl:1; /* set if posix acl support should be disabled */ + bool cifs_acl:1; + bool no_xattr:1; /* set if xattr (EA) support should be disabled*/ + bool server_ino:1; /* use inode numbers from server ie UniqueId */ + bool direct_io:1; + bool remap:1; /* set to remap seven reserved chars in filenames */ + bool posix_paths:1; /* unset to not ask for posix pathnames. */ + bool no_linux_ext:1; + bool sfu_emul:1; + bool nullauth:1; /* attempt to authenticate with null user */ unsigned nocase; /* request case insensitive filenames */ unsigned nobrl; /* disable sending byte range locks to srv */ unsigned int rsize; @@ -345,18 +343,16 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) struct task_struct *task_to_wake = NULL; struct mid_q_entry *mid_entry; char temp; - int isLargeBuf = FALSE; - int isMultiRsp; + bool isLargeBuf = false; + bool isMultiRsp; int reconnect; current->flags |= PF_MEMALLOC; - server->tsk = current; /* save process info to wake at shutdown */ cFYI(1, ("Demultiplex PID: %d", task_pid_nr(current))); write_lock(&GlobalSMBSeslock); atomic_inc(&tcpSesAllocCount); length = tcpSesAllocCount.counter; write_unlock(&GlobalSMBSeslock); - complete(&cifsd_complete); if (length > 1) mempool_resize(cifs_req_poolp, length + cifs_min_rcv, GFP_KERNEL); @@ -390,8 +386,8 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) } else /* if existing small buf clear beginning */ memset(smallbuf, 0, sizeof(struct smb_hdr)); - isLargeBuf = FALSE; - isMultiRsp = FALSE; + isLargeBuf = false; + isMultiRsp = false; smb_buffer = smallbuf; iov.iov_base = smb_buffer; iov.iov_len = 4; @@ -517,7 +513,7 @@ incomplete_rcv: reconnect = 0; if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) { - isLargeBuf = TRUE; + isLargeBuf = true; memcpy(bigbuf, smallbuf, 4); smb_buffer = bigbuf; } @@ -582,16 +578,18 @@ incomplete_rcv: (mid_entry->command == smb_buffer->Command)) { if (check2ndT2(smb_buffer,server->maxBuf) > 0) { /* We have a multipart transact2 resp */ - isMultiRsp = TRUE; + isMultiRsp = true; if (mid_entry->resp_buf) { /* merge response - fix up 1st*/ if (coalesce_t2(smb_buffer, mid_entry->resp_buf)) { - mid_entry->multiRsp = 1; + mid_entry->multiRsp = + true; break; } else { /* all parts received */ - mid_entry->multiEnd = 1; + mid_entry->multiEnd = + true; goto multi_t2_fnd; } } else { @@ -603,17 +601,15 @@ incomplete_rcv: /* Have first buffer */ mid_entry->resp_buf = smb_buffer; - mid_entry->largeBuf = 1; + mid_entry->largeBuf = + true; bigbuf = NULL; } } break; } mid_entry->resp_buf = smb_buffer; - if (isLargeBuf) - mid_entry->largeBuf = 1; - else - mid_entry->largeBuf = 0; + mid_entry->largeBuf = isLargeBuf; multi_t2_fnd: task_to_wake = mid_entry->tsk; mid_entry->midState = MID_RESPONSE_RECEIVED; @@ -638,8 +634,8 @@ multi_t2_fnd: smallbuf = NULL; } wake_up_process(task_to_wake); - } else if ((is_valid_oplock_break(smb_buffer, server) == FALSE) - && (isMultiRsp == FALSE)) { + } else if (!is_valid_oplock_break(smb_buffer, server) && + !isMultiRsp) { cERROR(1, ("No task to wake, unknown frame received! " "NumMids %d", midCount.counter)); cifs_dump_mem("Received Data is: ", (char *)smb_buffer, @@ -654,10 +650,20 @@ multi_t2_fnd: spin_lock(&GlobalMid_Lock); server->tcpStatus = CifsExiting; - server->tsk = NULL; + spin_unlock(&GlobalMid_Lock); + + /* don't exit until kthread_stop is called */ + set_current_state(TASK_UNINTERRUPTIBLE); + while (!kthread_should_stop()) { + schedule(); + set_current_state(TASK_UNINTERRUPTIBLE); + } + set_current_state(TASK_RUNNING); + /* check if we have blocked requests that need to free */ /* Note that cifs_max_pending is normally 50, but can be set at module install time to as little as two */ + spin_lock(&GlobalMid_Lock); if (atomic_read(&server->inFlight) >= cifs_max_pending) atomic_set(&server->inFlight, cifs_max_pending - 1); /* We do not want to set the max_pending too low or we @@ -825,7 +831,7 @@ cifs_parse_mount_options(char *options, const char *devname, vol->file_mode = (S_IRWXUGO | S_ISGID) & (~S_IXGRP); /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */ - vol->rw = TRUE; + vol->rw = true; /* default is always to request posix paths. */ vol->posix_paths = 1; @@ -1181,7 +1187,7 @@ cifs_parse_mount_options(char *options, const char *devname, } else if (strnicmp(data, "guest", 5) == 0) { /* ignore */ } else if (strnicmp(data, "rw", 2) == 0) { - vol->rw = TRUE; + vol->rw = true; } else if ((strnicmp(data, "suid", 4) == 0) || (strnicmp(data, "nosuid", 6) == 0) || (strnicmp(data, "exec", 4) == 0) || @@ -1197,7 +1203,7 @@ cifs_parse_mount_options(char *options, const char *devname, is ok to just ignore them */ continue; } else if (strnicmp(data, "ro", 2) == 0) { - vol->rw = FALSE; + vol->rw = false; } else if (strnicmp(data, "hard", 4) == 0) { vol->retry = 1; } else if (strnicmp(data, "soft", 4) == 0) { @@ -1305,6 +1311,9 @@ cifs_parse_mount_options(char *options, const char *devname, "begin with // or \\\\ \n"); return 1; } + value = strpbrk(vol->UNC+2, "/\\"); + if (value) + *value = '\\'; } else { printk(KERN_WARNING "CIFS: UNC name too long\n"); return 1; @@ -1318,42 +1327,43 @@ cifs_parse_mount_options(char *options, const char *devname, static struct cifsSesInfo * cifs_find_tcp_session(struct in_addr *target_ip_addr, - struct in6_addr *target_ip6_addr, - char *userName, struct TCP_Server_Info **psrvTcp) + struct in6_addr *target_ip6_addr, + char *userName, struct TCP_Server_Info **psrvTcp) { struct list_head *tmp; struct cifsSesInfo *ses; + *psrvTcp = NULL; - read_lock(&GlobalSMBSeslock); + read_lock(&GlobalSMBSeslock); list_for_each(tmp, &GlobalSMBSessionList) { ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList); - if (ses->server) { - if ((target_ip_addr && - (ses->server->addr.sockAddr.sin_addr.s_addr - == target_ip_addr->s_addr)) || (target_ip6_addr - && memcmp(&ses->server->addr.sockAddr6.sin6_addr, - target_ip6_addr, sizeof(*target_ip6_addr)))) { - /* BB lock server and tcp session and increment - use count here?? */ - - /* found a match on the TCP session */ - *psrvTcp = ses->server; - - /* BB check if reconnection needed */ - if (strncmp - (ses->userName, userName, - MAX_USERNAME_SIZE) == 0){ - read_unlock(&GlobalSMBSeslock); - /* Found exact match on both TCP and - SMB sessions */ - return ses; - } - } + if (!ses->server) + continue; + + if (target_ip_addr && + ses->server->addr.sockAddr.sin_addr.s_addr != target_ip_addr->s_addr) + continue; + else if (target_ip6_addr && + memcmp(&ses->server->addr.sockAddr6.sin6_addr, + target_ip6_addr, sizeof(*target_ip6_addr))) + continue; + /* BB lock server and tcp session; increment use count here?? */ + + /* found a match on the TCP session */ + *psrvTcp = ses->server; + + /* BB check if reconnection needed */ + if (strncmp(ses->userName, userName, MAX_USERNAME_SIZE) == 0) { + read_unlock(&GlobalSMBSeslock); + /* Found exact match on both TCP and + SMB sessions */ + return ses; } /* else tcp and smb sessions need reconnection */ } read_unlock(&GlobalSMBSeslock); + return NULL; } @@ -1362,45 +1372,43 @@ find_unc(__be32 new_target_ip_addr, char *uncName, char *userName) { struct list_head *tmp; struct cifsTconInfo *tcon; + __be32 old_ip; read_lock(&GlobalSMBSeslock); + list_for_each(tmp, &GlobalTreeConnectionList) { cFYI(1, ("Next tcon")); tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList); - if (tcon->ses) { - if (tcon->ses->server) { - cFYI(1, - ("old ip addr: %x == new ip %x ?", - tcon->ses->server->addr.sockAddr.sin_addr. - s_addr, new_target_ip_addr)); - if (tcon->ses->server->addr.sockAddr.sin_addr. - s_addr == new_target_ip_addr) { - /* BB lock tcon, server and tcp session and increment use count here? */ - /* found a match on the TCP session */ - /* BB check if reconnection needed */ - cFYI(1, - ("IP match, old UNC: %s new: %s", - tcon->treeName, uncName)); - if (strncmp - (tcon->treeName, uncName, - MAX_TREE_SIZE) == 0) { - cFYI(1, - ("and old usr: %s new: %s", - tcon->treeName, uncName)); - if (strncmp - (tcon->ses->userName, - userName, - MAX_USERNAME_SIZE) == 0) { - read_unlock(&GlobalSMBSeslock); - /* matched smb session - (user name */ - return tcon; - } - } - } - } - } + if (!tcon->ses || !tcon->ses->server) + continue; + + old_ip = tcon->ses->server->addr.sockAddr.sin_addr.s_addr; + cFYI(1, ("old ip addr: %x == new ip %x ?", + old_ip, new_target_ip_addr)); + + if (old_ip != new_target_ip_addr) + continue; + + /* BB lock tcon, server, tcp session and increment use count? */ + /* found a match on the TCP session */ + /* BB check if reconnection needed */ + cFYI(1, ("IP match, old UNC: %s new: %s", + tcon->treeName, uncName)); + + if (strncmp(tcon->treeName, uncName, MAX_TREE_SIZE)) + continue; + + cFYI(1, ("and old usr: %s new: %s", + tcon->treeName, uncName)); + + if (strncmp(tcon->ses->userName, userName, MAX_USERNAME_SIZE)) + continue; + + /* matched smb session (user name) */ + read_unlock(&GlobalSMBSeslock); + return tcon; } + read_unlock(&GlobalSMBSeslock); return NULL; } @@ -1982,7 +1990,6 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, kfree(srvTcp->hostname); goto out; } - wait_for_completion(&cifsd_complete); rc = 0; memcpy(srvTcp->workstation_RFC1001_name, volume_info.source_rfc1001_name, 16); @@ -2189,15 +2196,12 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, srvTcp->tcpStatus = CifsExiting; spin_unlock(&GlobalMid_Lock); if (srvTcp->tsk) { - struct task_struct *tsk; /* If we could verify that kthread_stop would always wake up processes blocked in tcp in recv_mesg then we could remove the send_sig call */ force_sig(SIGKILL, srvTcp->tsk); - tsk = srvTcp->tsk; - if (tsk) - kthread_stop(tsk); + kthread_stop(srvTcp->tsk); } } /* If find_unc succeeded then rc == 0 so we can not end */ @@ -2213,23 +2217,17 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, if ((temp_rc == -ESHUTDOWN) && (pSesInfo->server) && (pSesInfo->server->tsk)) { - struct task_struct *tsk; force_sig(SIGKILL, pSesInfo->server->tsk); - tsk = pSesInfo->server->tsk; - if (tsk) - kthread_stop(tsk); + kthread_stop(pSesInfo->server->tsk); } } else { cFYI(1, ("No session or bad tcon")); if ((pSesInfo->server) && (pSesInfo->server->tsk)) { - struct task_struct *tsk; force_sig(SIGKILL, pSesInfo->server->tsk); - tsk = pSesInfo->server->tsk; - if (tsk) - kthread_stop(tsk); + kthread_stop(pSesInfo->server->tsk); } } sesInfoFree(pSesInfo); @@ -2602,7 +2600,7 @@ sesssetup_nomem: /* do not return an error on nomem for the info strings, static int CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, - struct cifsSesInfo *ses, int *pNTLMv2_flag, + struct cifsSesInfo *ses, bool *pNTLMv2_flag, const struct nls_table *nls_codepage) { struct smb_hdr *smb_buffer; @@ -2625,7 +2623,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, if (ses == NULL) return -EINVAL; domain = ses->domainName; - *pNTLMv2_flag = FALSE; + *pNTLMv2_flag = false; smb_buffer = cifs_buf_get(); if (smb_buffer == NULL) { return -ENOMEM; @@ -2778,7 +2776,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, CIFS_CRYPTO_KEY_SIZE); if (SecurityBlob2->NegotiateFlags & cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2)) - *pNTLMv2_flag = TRUE; + *pNTLMv2_flag = true; if ((SecurityBlob2->NegotiateFlags & cpu_to_le32(NTLMSSP_NEGOTIATE_ALWAYS_SIGN)) @@ -2939,7 +2937,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, } static int CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, - char *ntlm_session_key, int ntlmv2_flag, + char *ntlm_session_key, bool ntlmv2_flag, const struct nls_table *nls_codepage) { struct smb_hdr *smb_buffer; @@ -3555,8 +3553,6 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb) cifs_sb->prepathlen = 0; cifs_sb->prepath = NULL; kfree(tmp); - if (ses) - schedule_timeout_interruptible(msecs_to_jiffies(500)); if (ses) sesInfoFree(ses); @@ -3569,7 +3565,7 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, { int rc = 0; char ntlm_session_key[CIFS_SESS_KEY_SIZE]; - int ntlmv2_flag = FALSE; + bool ntlmv2_flag = false; int first_time = 0; /* what if server changes its buffer size after dropping the session? */ diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 0f5c62ba403868048732d69a1d1f55c1e3e098f3..e4e0078a0526c90b9fed67f7a3c2128085902b57 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -119,6 +119,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, { int rc = -ENOENT; int xid; + int create_options = CREATE_NOT_DIR; int oplock = 0; int desiredAccess = GENERIC_READ | GENERIC_WRITE; __u16 fileHandle; @@ -130,7 +131,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, struct cifsFileInfo *pCifsFile = NULL; struct cifsInodeInfo *pCifsInode; int disposition = FILE_OVERWRITE_IF; - int write_only = FALSE; + bool write_only = false; xid = GetXid(); @@ -152,7 +153,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, if (oflags & FMODE_WRITE) { desiredAccess |= GENERIC_WRITE; if (!(oflags & FMODE_READ)) - write_only = TRUE; + write_only = true; } if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) @@ -176,9 +177,19 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, FreeXid(xid); return -ENOMEM; } + + mode &= ~current->fs->umask; + + /* + * if we're not using unix extensions, see if we need to set + * ATTR_READONLY on the create call + */ + if (!pTcon->unix_ext && (mode & S_IWUGO) == 0) + create_options |= CREATE_OPTION_READONLY; + if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS) rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, - desiredAccess, CREATE_NOT_DIR, + desiredAccess, create_options, &fileHandle, &oplock, buf, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); else @@ -187,7 +198,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, if (rc == -EIO) { /* old server, retry the open legacy style */ rc = SMBLegacyOpen(xid, pTcon, full_path, disposition, - desiredAccess, CREATE_NOT_DIR, + desiredAccess, create_options, &fileHandle, &oplock, buf, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); } @@ -197,7 +208,6 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, /* If Open reported that we actually created a file then we now have to set the mode if possible */ if ((pTcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) { - mode &= ~current->fs->umask; if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, (__u64)current->fsuid, @@ -254,7 +264,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, d_instantiate(direntry, newinode); } if ((nd == NULL /* nfsd case - nfs srv does not set nd */) || - ((nd->flags & LOOKUP_OPEN) == FALSE)) { + (!(nd->flags & LOOKUP_OPEN))) { /* mknod case - do not leave file open */ CIFSSMBClose(xid, pTcon, fileHandle); } else if (newinode) { @@ -266,8 +276,8 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, pCifsFile->netfid = fileHandle; pCifsFile->pid = current->tgid; pCifsFile->pInode = newinode; - pCifsFile->invalidHandle = FALSE; - pCifsFile->closePend = FALSE; + pCifsFile->invalidHandle = false; + pCifsFile->closePend = false; init_MUTEX(&pCifsFile->fh_sem); mutex_init(&pCifsFile->lock_mutex); INIT_LIST_HEAD(&pCifsFile->llist); @@ -280,7 +290,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, pCifsInode = CIFS_I(newinode); if (pCifsInode) { /* if readable file instance put first in list*/ - if (write_only == TRUE) { + if (write_only) { list_add_tail(&pCifsFile->flist, &pCifsInode->openFileList); } else { @@ -288,12 +298,12 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, &pCifsInode->openFileList); } if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { - pCifsInode->clientCanCacheAll = TRUE; - pCifsInode->clientCanCacheRead = TRUE; + pCifsInode->clientCanCacheAll = true; + pCifsInode->clientCanCacheRead = true; cFYI(1, ("Exclusive Oplock inode %p", newinode)); } else if ((oplock & 0xF) == OPLOCK_READ) - pCifsInode->clientCanCacheRead = TRUE; + pCifsInode->clientCanCacheRead = true; } write_unlock(&GlobalSMBSeslock); } diff --git a/fs/cifs/dns_resolve.c b/fs/cifs/dns_resolve.c index 7cc86c418182f261954dbcd18e8efd09b08df108..939e256f84975995341da88b38e2c60201e2aaa5 100644 --- a/fs/cifs/dns_resolve.c +++ b/fs/cifs/dns_resolve.c @@ -55,6 +55,32 @@ struct key_type key_type_dns_resolver = { .match = user_match, }; +/* Checks if supplied name is IP address + * returns: + * 1 - name is IP + * 0 - name is not IP + */ +static int is_ip(const char *name) +{ + int rc; + struct sockaddr_in sin_server; + struct sockaddr_in6 sin_server6; + + rc = cifs_inet_pton(AF_INET, name, + &sin_server.sin_addr.s_addr); + + if (rc <= 0) { + /* not ipv4 address, try ipv6 */ + rc = cifs_inet_pton(AF_INET6, name, + &sin_server6.sin6_addr.in6_u); + if (rc > 0) + return 1; + } else { + return 1; + } + /* we failed translating address */ + return 0; +} /* Resolves server name to ip address. * input: @@ -67,8 +93,9 @@ int dns_resolve_server_name_to_ip(const char *unc, char **ip_addr) { int rc = -EAGAIN; - struct key *rkey; + struct key *rkey = ERR_PTR(-EAGAIN); char *name; + char *data = NULL; int len; if (!ip_addr || !unc) @@ -97,26 +124,41 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr) memcpy(name, unc+2, len); name[len] = 0; + if (is_ip(name)) { + cFYI(1, ("%s: it is IP, skipping dns upcall: %s", + __func__, name)); + data = name; + goto skip_upcall; + } + rkey = request_key(&key_type_dns_resolver, name, ""); if (!IS_ERR(rkey)) { - len = strlen(rkey->payload.data); - *ip_addr = kmalloc(len+1, GFP_KERNEL); - if (*ip_addr) { - memcpy(*ip_addr, rkey->payload.data, len); - (*ip_addr)[len] = '\0'; - cFYI(1, ("%s: resolved: %s to %s", __func__, + data = rkey->payload.data; + cFYI(1, ("%s: resolved: %s to %s", __func__, rkey->description, *ip_addr )); + } else { + cERROR(1, ("%s: unable to resolve: %s", __func__, name)); + goto out; + } + +skip_upcall: + if (data) { + len = strlen(data); + *ip_addr = kmalloc(len+1, GFP_KERNEL); + if (*ip_addr) { + memcpy(*ip_addr, data, len); + (*ip_addr)[len] = '\0'; rc = 0; } else { rc = -ENOMEM; } - key_put(rkey); - } else { - cERROR(1, ("%s: unable to resolve: %s", __func__, name)); + if (!IS_ERR(rkey)) + key_put(rkey); } +out: kfree(name); return rc; } diff --git a/fs/cifs/fcntl.c b/fs/cifs/fcntl.c index 7d1d5aa4c430b6c904c08a5c65c8be32ba0a0298..5a57581eb4b2a6a803c5cdb01f98216d7d34c12a 100644 --- a/fs/cifs/fcntl.c +++ b/fs/cifs/fcntl.c @@ -68,7 +68,7 @@ int cifs_dir_notify(struct file *file, unsigned long arg) { int xid; int rc = -EINVAL; - int oplock = FALSE; + int oplock = 0; struct cifs_sb_info *cifs_sb; struct cifsTconInfo *pTcon; char *full_path = NULL; diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 40b690073fc1432f165c1c0dfb208b22a1863bde..31a0a33b9d95450ea0fe8d6461f2249bf68d0f88 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -51,8 +51,8 @@ static inline struct cifsFileInfo *cifs_init_private( INIT_LIST_HEAD(&private_data->llist); private_data->pfile = file; /* needed for writepage */ private_data->pInode = inode; - private_data->invalidHandle = FALSE; - private_data->closePend = FALSE; + private_data->invalidHandle = false; + private_data->closePend = false; /* we have to track num writers to the inode, since writepages does not tell us which handle the write is for so there can be a close (overlapping with write) of the filehandle that @@ -148,12 +148,12 @@ client_can_cache: full_path, buf, inode->i_sb, xid, NULL); if ((*oplock & 0xF) == OPLOCK_EXCLUSIVE) { - pCifsInode->clientCanCacheAll = TRUE; - pCifsInode->clientCanCacheRead = TRUE; + pCifsInode->clientCanCacheAll = true; + pCifsInode->clientCanCacheRead = true; cFYI(1, ("Exclusive Oplock granted on inode %p", file->f_path.dentry->d_inode)); } else if ((*oplock & 0xF) == OPLOCK_READ) - pCifsInode->clientCanCacheRead = TRUE; + pCifsInode->clientCanCacheRead = true; return rc; } @@ -247,7 +247,7 @@ int cifs_open(struct inode *inode, struct file *file) if (oplockEnabled) oplock = REQ_OPLOCK; else - oplock = FALSE; + oplock = 0; /* BB pass O_SYNC flag through on file attributes .. BB */ @@ -339,7 +339,7 @@ static int cifs_relock_file(struct cifsFileInfo *cifsFile) return rc; } -static int cifs_reopen_file(struct file *file, int can_flush) +static int cifs_reopen_file(struct file *file, bool can_flush) { int rc = -EACCES; int xid, oplock; @@ -360,7 +360,7 @@ static int cifs_reopen_file(struct file *file, int can_flush) xid = GetXid(); down(&pCifsFile->fh_sem); - if (pCifsFile->invalidHandle == FALSE) { + if (!pCifsFile->invalidHandle) { up(&pCifsFile->fh_sem); FreeXid(xid); return 0; @@ -404,7 +404,7 @@ reopen_error_exit: if (oplockEnabled) oplock = REQ_OPLOCK; else - oplock = FALSE; + oplock = 0; /* Can not refresh inode by passing in file_info buf to be returned by SMBOpen and then calling get_inode_info with returned buf @@ -422,7 +422,7 @@ reopen_error_exit: cFYI(1, ("oplock: %d", oplock)); } else { pCifsFile->netfid = netfid; - pCifsFile->invalidHandle = FALSE; + pCifsFile->invalidHandle = false; up(&pCifsFile->fh_sem); pCifsInode = CIFS_I(inode); if (pCifsInode) { @@ -432,8 +432,8 @@ reopen_error_exit: CIFS_I(inode)->write_behind_rc = rc; /* temporarily disable caching while we go to server to get inode info */ - pCifsInode->clientCanCacheAll = FALSE; - pCifsInode->clientCanCacheRead = FALSE; + pCifsInode->clientCanCacheAll = false; + pCifsInode->clientCanCacheRead = false; if (pTcon->unix_ext) rc = cifs_get_inode_info_unix(&inode, full_path, inode->i_sb, xid); @@ -448,16 +448,16 @@ reopen_error_exit: we can not go to the server to get the new inod info */ if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { - pCifsInode->clientCanCacheAll = TRUE; - pCifsInode->clientCanCacheRead = TRUE; + pCifsInode->clientCanCacheAll = true; + pCifsInode->clientCanCacheRead = true; cFYI(1, ("Exclusive Oplock granted on inode %p", file->f_path.dentry->d_inode)); } else if ((oplock & 0xF) == OPLOCK_READ) { - pCifsInode->clientCanCacheRead = TRUE; - pCifsInode->clientCanCacheAll = FALSE; + pCifsInode->clientCanCacheRead = true; + pCifsInode->clientCanCacheAll = false; } else { - pCifsInode->clientCanCacheRead = FALSE; - pCifsInode->clientCanCacheAll = FALSE; + pCifsInode->clientCanCacheRead = false; + pCifsInode->clientCanCacheAll = false; } cifs_relock_file(pCifsFile); } @@ -484,7 +484,7 @@ int cifs_close(struct inode *inode, struct file *file) if (pSMBFile) { struct cifsLockInfo *li, *tmp; - pSMBFile->closePend = TRUE; + pSMBFile->closePend = true; if (pTcon) { /* no sense reconnecting to close a file that is already closed */ @@ -553,8 +553,8 @@ int cifs_close(struct inode *inode, struct file *file) cFYI(1, ("closing last open instance for inode %p", inode)); /* if the file is not open we do not know if we can cache info on this inode, much less write behind and read ahead */ - CIFS_I(inode)->clientCanCacheRead = FALSE; - CIFS_I(inode)->clientCanCacheAll = FALSE; + CIFS_I(inode)->clientCanCacheRead = false; + CIFS_I(inode)->clientCanCacheAll = false; } read_unlock(&GlobalSMBSeslock); if ((rc == 0) && CIFS_I(inode)->write_behind_rc) @@ -583,9 +583,9 @@ int cifs_closedir(struct inode *inode, struct file *file) pTcon = cifs_sb->tcon; cFYI(1, ("Freeing private data in close dir")); - if ((pCFileStruct->srch_inf.endOfSearch == FALSE) && - (pCFileStruct->invalidHandle == FALSE)) { - pCFileStruct->invalidHandle = TRUE; + if (!pCFileStruct->srch_inf.endOfSearch && + !pCFileStruct->invalidHandle) { + pCFileStruct->invalidHandle = true; rc = CIFSFindClose(xid, pTcon, pCFileStruct->netfid); cFYI(1, ("Closing uncompleted readdir with rc %d", rc)); @@ -637,12 +637,12 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) __u32 numLock = 0; __u32 numUnlock = 0; __u64 length; - int wait_flag = FALSE; + bool wait_flag = false; struct cifs_sb_info *cifs_sb; struct cifsTconInfo *pTcon; __u16 netfid; __u8 lockType = LOCKING_ANDX_LARGE_FILES; - int posix_locking; + bool posix_locking; length = 1 + pfLock->fl_end - pfLock->fl_start; rc = -EACCES; @@ -659,7 +659,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) cFYI(1, ("Flock")); if (pfLock->fl_flags & FL_SLEEP) { cFYI(1, ("Blocking lock")); - wait_flag = TRUE; + wait_flag = true; } if (pfLock->fl_flags & FL_ACCESS) cFYI(1, ("Process suspended by mandatory locking - " @@ -794,7 +794,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) stored_rc = CIFSSMBLock(xid, pTcon, netfid, li->length, li->offset, - 1, 0, li->type, FALSE); + 1, 0, li->type, false); if (stored_rc) rc = stored_rc; @@ -866,7 +866,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data, filemap_fdatawait from here so tell reopen_file not to flush data to server now */ - rc = cifs_reopen_file(file, FALSE); + rc = cifs_reopen_file(file, false); if (rc != 0) break; } @@ -966,7 +966,7 @@ static ssize_t cifs_write(struct file *file, const char *write_data, filemap_fdatawait from here so tell reopen_file not to flush data to server now */ - rc = cifs_reopen_file(file, FALSE); + rc = cifs_reopen_file(file, false); if (rc != 0) break; } @@ -1093,7 +1093,7 @@ refind_writable: read_unlock(&GlobalSMBSeslock); /* Had to unlock since following call can block */ - rc = cifs_reopen_file(open_file->pfile, FALSE); + rc = cifs_reopen_file(open_file->pfile, false); if (!rc) { if (!open_file->closePend) return open_file; @@ -1608,7 +1608,7 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data, int buf_type = CIFS_NO_BUFFER; if ((open_file->invalidHandle) && (!open_file->closePend)) { - rc = cifs_reopen_file(file, TRUE); + rc = cifs_reopen_file(file, true); if (rc != 0) break; } @@ -1693,7 +1693,7 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size, while (rc == -EAGAIN) { if ((open_file->invalidHandle) && (!open_file->closePend)) { - rc = cifs_reopen_file(file, TRUE); + rc = cifs_reopen_file(file, true); if (rc != 0) break; } @@ -1850,7 +1850,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, while (rc == -EAGAIN) { if ((open_file->invalidHandle) && (!open_file->closePend)) { - rc = cifs_reopen_file(file, TRUE); + rc = cifs_reopen_file(file, true); if (rc != 0) break; } @@ -2009,10 +2009,10 @@ static int is_inode_writable(struct cifsInodeInfo *cifs_inode) refreshing the inode only on increases in the file size but this is tricky to do without racing with writebehind page caching in the current Linux kernel design */ -int is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file) +bool is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file) { if (!cifsInode) - return 1; + return true; if (is_inode_writable(cifsInode)) { /* This inode is open for write at least once */ @@ -2022,15 +2022,15 @@ int is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file) if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { /* since no page cache to corrupt on directio we can change size safely */ - return 1; + return true; } if (i_size_read(&cifsInode->vfs_inode) < end_of_file) - return 1; + return true; - return 0; + return false; } else - return 1; + return true; } static int cifs_prepare_write(struct file *file, struct page *page, diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index e1031b9e2c55ccfb13182e89c899ba6e49c89f7d..fcbdbb6ad7bfb45f9ea5606d9f5c7f078980d467 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -281,7 +281,7 @@ static int decode_sfu_inode(struct inode *inode, __u64 size, struct cifs_sb_info *cifs_sb, int xid) { int rc; - int oplock = FALSE; + int oplock = 0; __u16 netfid; struct cifsTconInfo *pTcon = cifs_sb->tcon; char buf[24]; @@ -389,7 +389,7 @@ int cifs_get_inode_info(struct inode **pinode, struct cifs_sb_info *cifs_sb = CIFS_SB(sb); const unsigned char *full_path = NULL; char *buf = NULL; - int adjustTZ = FALSE; + bool adjustTZ = false; bool is_dfs_referral = false; pTcon = cifs_sb->tcon; @@ -425,7 +425,7 @@ try_again_CIFSSMBQPathInfo: pfindData, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); - adjustTZ = TRUE; + adjustTZ = true; } } /* dump_mem("\nQPathInfo return data",&findData, sizeof(findData)); */ @@ -703,7 +703,7 @@ psx_del_no_retry: } else if (rc == -ENOENT) { d_drop(direntry); } else if (rc == -ETXTBSY) { - int oplock = FALSE; + int oplock = 0; __u16 netfid; rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, DELETE, @@ -736,7 +736,7 @@ psx_del_no_retry: rc = -EOPNOTSUPP; if (rc == -EOPNOTSUPP) { - int oplock = FALSE; + int oplock = 0; __u16 netfid; /* rc = CIFSSMBSetAttrLegacy(xid, pTcon, full_path, @@ -774,7 +774,7 @@ psx_del_no_retry: if (direntry->d_inode) drop_nlink(direntry->d_inode); } else if (rc == -ETXTBSY) { - int oplock = FALSE; + int oplock = 0; __u16 netfid; rc = CIFSSMBOpen(xid, pTcon, full_path, @@ -974,8 +974,8 @@ mkdir_get_info: * failed to get it from the server or was set bogus */ if ((direntry->d_inode) && (direntry->d_inode->i_nlink < 2)) direntry->d_inode->i_nlink = 2; + mode &= ~current->fs->umask; if (pTcon->unix_ext) { - mode &= ~current->fs->umask; if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, @@ -994,9 +994,16 @@ mkdir_get_info: CIFS_MOUNT_MAP_SPECIAL_CHR); } } else { - /* BB to be implemented via Windows secrty descriptors - eg CIFSSMBWinSetPerms(xid, pTcon, full_path, mode, - -1, -1, local_nls); */ + if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) && + (mode & S_IWUGO) == 0) { + FILE_BASIC_INFO pInfo; + memset(&pInfo, 0, sizeof(pInfo)); + pInfo.Attributes = cpu_to_le32(ATTR_READONLY); + CIFSSMBSetTimes(xid, pTcon, full_path, + &pInfo, cifs_sb->local_nls, + cifs_sb->mnt_cifs_flags & + CIFS_MOUNT_MAP_SPECIAL_CHR); + } if (direntry->d_inode) { direntry->d_inode->i_mode = mode; direntry->d_inode->i_mode |= S_IFDIR; @@ -1149,7 +1156,7 @@ int cifs_rename(struct inode *source_inode, struct dentry *source_direntry, cFYI(1, ("rename rc %d", rc)); if ((rc == -EIO) || (rc == -EEXIST)) { - int oplock = FALSE; + int oplock = 0; __u16 netfid; /* BB FIXME Is Generic Read correct for rename? */ @@ -1186,7 +1193,7 @@ int cifs_revalidate(struct dentry *direntry) struct cifsInodeInfo *cifsInode; loff_t local_size; struct timespec local_mtime; - int invalidate_inode = FALSE; + bool invalidate_inode = false; if (direntry->d_inode == NULL) return -ENOENT; @@ -1268,7 +1275,7 @@ int cifs_revalidate(struct dentry *direntry) only ones who could have modified the file and the server copy is staler than ours */ } else { - invalidate_inode = TRUE; + invalidate_inode = true; } } @@ -1402,24 +1409,25 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) int rc = -EACCES; struct cifsFileInfo *open_file = NULL; FILE_BASIC_INFO time_buf; - int set_time = FALSE; - int set_dosattr = FALSE; + bool set_time = false; + bool set_dosattr = false; __u64 mode = 0xFFFFFFFFFFFFFFFFULL; __u64 uid = 0xFFFFFFFFFFFFFFFFULL; __u64 gid = 0xFFFFFFFFFFFFFFFFULL; struct cifsInodeInfo *cifsInode; + struct inode *inode = direntry->d_inode; xid = GetXid(); cFYI(1, ("setattr on file %s attrs->iavalid 0x%x", direntry->d_name.name, attrs->ia_valid)); - cifs_sb = CIFS_SB(direntry->d_inode->i_sb); + cifs_sb = CIFS_SB(inode->i_sb); pTcon = cifs_sb->tcon; if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) { /* check if we have permission to change attrs */ - rc = inode_change_ok(direntry->d_inode, attrs); + rc = inode_change_ok(inode, attrs); if (rc < 0) { FreeXid(xid); return rc; @@ -1432,7 +1440,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) FreeXid(xid); return -ENOMEM; } - cifsInode = CIFS_I(direntry->d_inode); + cifsInode = CIFS_I(inode); if ((attrs->ia_valid & ATTR_MTIME) || (attrs->ia_valid & ATTR_SIZE)) { /* @@ -1443,9 +1451,9 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) will be truncated anyway? Also, should we error out here if the flush returns error? */ - rc = filemap_write_and_wait(direntry->d_inode->i_mapping); + rc = filemap_write_and_wait(inode->i_mapping); if (rc != 0) { - CIFS_I(direntry->d_inode)->write_behind_rc = rc; + cifsInode->write_behind_rc = rc; rc = 0; } } @@ -1464,7 +1472,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) __u16 nfid = open_file->netfid; __u32 npid = open_file->pid; rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, - nfid, npid, FALSE); + nfid, npid, false); atomic_dec(&open_file->wrtPending); cFYI(1, ("SetFSize for attrs rc = %d", rc)); if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { @@ -1484,14 +1492,14 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) it was found or because there was an error setting it by handle */ rc = CIFSSMBSetEOF(xid, pTcon, full_path, - attrs->ia_size, FALSE, + attrs->ia_size, false, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); cFYI(1, ("SetEOF by path (setattrs) rc = %d", rc)); if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { __u16 netfid; - int oplock = FALSE; + int oplock = 0; rc = SMBLegacyOpen(xid, pTcon, full_path, FILE_OPEN, @@ -1516,14 +1524,13 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) /* Server is ok setting allocation size implicitly - no need to call: - CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size, TRUE, + CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size, true, cifs_sb->local_nls); */ if (rc == 0) { - rc = cifs_vmtruncate(direntry->d_inode, attrs->ia_size); - cifs_truncate_page(direntry->d_inode->i_mapping, - direntry->d_inode->i_size); + rc = cifs_vmtruncate(inode, attrs->ia_size); + cifs_truncate_page(inode->i_mapping, inode->i_size); } else goto cifs_setattr_exit; } @@ -1557,14 +1564,14 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) rc = 0; #ifdef CONFIG_CIFS_EXPERIMENTAL if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) - rc = mode_to_acl(direntry->d_inode, full_path, mode); + rc = mode_to_acl(inode, full_path, mode); else if ((mode & S_IWUGO) == 0) { #else if ((mode & S_IWUGO) == 0) { #endif /* not writeable */ if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0) { - set_dosattr = TRUE; + set_dosattr = true; time_buf.Attributes = cpu_to_le32(cifsInode->cifsAttrs | ATTR_READONLY); @@ -1574,28 +1581,24 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) not be able to write to it - so if any write bit is enabled for user or group or other we need to at least try to remove r/o dos attr */ - set_dosattr = TRUE; + set_dosattr = true; time_buf.Attributes = cpu_to_le32(cifsInode->cifsAttrs & (~ATTR_READONLY)); /* Windows ignores set to zero */ if (time_buf.Attributes == 0) time_buf.Attributes |= cpu_to_le32(ATTR_NORMAL); } -#ifdef CONFIG_CIFS_EXPERIMENTAL - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) - mode_to_acl(direntry->d_inode, full_path, mode); -#endif } if (attrs->ia_valid & ATTR_ATIME) { - set_time = TRUE; + set_time = true; time_buf.LastAccessTime = cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_atime)); } else time_buf.LastAccessTime = 0; if (attrs->ia_valid & ATTR_MTIME) { - set_time = TRUE; + set_time = true; time_buf.LastWriteTime = cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_mtime)); } else @@ -1606,7 +1609,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) server times */ if (set_time && (attrs->ia_valid & ATTR_CTIME)) { - set_time = TRUE; + set_time = true; /* Although Samba throws this field away it may be useful to Windows - but we do not want to set ctime unless some other @@ -1630,7 +1633,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) rc = -EOPNOTSUPP; if (rc == -EOPNOTSUPP) { - int oplock = FALSE; + int oplock = 0; __u16 netfid; cFYI(1, ("calling SetFileInfo since SetPathInfo for " @@ -1669,7 +1672,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) /* do not need local check to inode_check_ok since the server does that */ if (!rc) - rc = inode_setattr(direntry->d_inode, attrs); + rc = inode_setattr(inode, attrs); cifs_setattr_exit: kfree(full_path); FreeXid(xid); diff --git a/fs/cifs/link.c b/fs/cifs/link.c index d4e7ec93285f1ab51b1727c60abcf9ddadab3bac..1c2c3ce5020b6ccc7d31eb90bfe2166da5555070 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c @@ -230,7 +230,7 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen) struct inode *inode = direntry->d_inode; int rc = -EACCES; int xid; - int oplock = FALSE; + int oplock = 0; struct cifs_sb_info *cifs_sb; struct cifsTconInfo *pTcon; char *full_path = NULL; diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 2a42d9fedbb266751f7f9e96dd4fb4a079d75b7e..1d69b8014e0bac116ab0f83220605db48e56ad20 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -496,7 +496,8 @@ checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length) } return 0; } -int + +bool is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv) { struct smb_com_lock_req *pSMB = (struct smb_com_lock_req *)buf; @@ -522,17 +523,17 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv) pnotify->Action)); /* BB removeme BB */ /* cifs_dump_mem("Rcvd notify Data: ",buf, sizeof(struct smb_hdr)+60); */ - return TRUE; + return true; } if (pSMBr->hdr.Status.CifsError) { cFYI(1, ("notify err 0x%d", pSMBr->hdr.Status.CifsError)); - return TRUE; + return true; } - return FALSE; + return false; } if (pSMB->hdr.Command != SMB_COM_LOCKING_ANDX) - return FALSE; + return false; if (pSMB->hdr.Flags & SMBFLG_RESPONSE) { /* no sense logging error on invalid handle on oplock break - harmless race between close request and oplock @@ -541,21 +542,21 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv) if ((NT_STATUS_INVALID_HANDLE) == le32_to_cpu(pSMB->hdr.Status.CifsError)) { cFYI(1, ("invalid handle on oplock break")); - return TRUE; + return true; } else if (ERRbadfid == le16_to_cpu(pSMB->hdr.Status.DosError.Error)) { - return TRUE; + return true; } else { - return FALSE; /* on valid oplock brk we get "request" */ + return false; /* on valid oplock brk we get "request" */ } } if (pSMB->hdr.WordCount != 8) - return FALSE; + return false; cFYI(1, ("oplock type 0x%d level 0x%d", pSMB->LockType, pSMB->OplockLevel)); if (!(pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE)) - return FALSE; + return false; /* look up tcon based on tid & uid */ read_lock(&GlobalSMBSeslock); @@ -573,11 +574,11 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv) ("file id match, oplock break")); pCifsInode = CIFS_I(netfile->pInode); - pCifsInode->clientCanCacheAll = FALSE; + pCifsInode->clientCanCacheAll = false; if (pSMB->OplockLevel == 0) pCifsInode->clientCanCacheRead - = FALSE; - pCifsInode->oplockPending = TRUE; + = false; + pCifsInode->oplockPending = true; AllocOplockQEntry(netfile->pInode, netfile->netfid, tcon); @@ -585,17 +586,17 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv) ("about to wake up oplock thread")); if (oplockThread) wake_up_process(oplockThread); - return TRUE; + return true; } } read_unlock(&GlobalSMBSeslock); cFYI(1, ("No matching file for oplock break")); - return TRUE; + return true; } } read_unlock(&GlobalSMBSeslock); cFYI(1, ("Can not process oplock break for non-existent connection")); - return TRUE; + return true; } void diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c index 3b5a5ce882b63083f492c34a3e1b007fe54be87f..00f4cff400b39c3f2fafbecbee5d5a74b65cba57 100644 --- a/fs/cifs/netmisc.c +++ b/fs/cifs/netmisc.c @@ -132,47 +132,17 @@ static const struct smb_to_posix_error mapping_table_ERRHRD[] = { {0, 0} }; - -/* if the mount helper is missing we need to reverse the 1st slash - from '/' to backslash in order to format the UNC properly for - ip address parsing and for tree connect (unless the user - remembered to put the UNC name in properly). Fortunately we do - not have to call this twice (we check for IPv4 addresses - first, so it is already converted by the time we - try IPv6 addresses */ -static int canonicalize_unc(char *cp) -{ - int i; - - for (i = 0; i <= 46 /* INET6_ADDRSTRLEN */ ; i++) { - if (cp[i] == 0) - break; - if (cp[i] == '\\') - break; - if (cp[i] == '/') { - cFYI(DBG2, ("change slash to \\ in malformed UNC")); - cp[i] = '\\'; - return 1; - } - } - return 0; -} - /* Convert string containing dotted ip address to binary form */ /* returns 0 if invalid address */ int -cifs_inet_pton(int address_family, char *cp, void *dst) +cifs_inet_pton(const int address_family, const char *cp, void *dst) { int ret = 0; /* calculate length by finding first slash or NULL */ if (address_family == AF_INET) { ret = in4_pton(cp, -1 /* len */, dst, '\\', NULL); - if (ret == 0) { - if (canonicalize_unc(cp)) - ret = in4_pton(cp, -1, dst, '\\', NULL); - } } else if (address_family == AF_INET6) { ret = in6_pton(cp, -1 /* len */, dst , '\\', NULL); } diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 32b445edc88282d2ce55ab1bd5a8f7bc2b9d7b3d..34ec32100c7242a68039533e0360985277edded8 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c @@ -447,8 +447,8 @@ static int initiate_cifs_search(const int xid, struct file *file) if (file->private_data == NULL) return -ENOMEM; cifsFile = file->private_data; - cifsFile->invalidHandle = TRUE; - cifsFile->srch_inf.endOfSearch = FALSE; + cifsFile->invalidHandle = true; + cifsFile->srch_inf.endOfSearch = false; cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); if (cifs_sb == NULL) @@ -485,7 +485,7 @@ ffirst_retry: cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR, CIFS_DIR_SEP(cifs_sb)); if (rc == 0) - cifsFile->invalidHandle = FALSE; + cifsFile->invalidHandle = false; if ((rc == -EOPNOTSUPP) && (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) { cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM; @@ -670,7 +670,7 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon, (index_to_find < first_entry_in_buffer)) { /* close and restart search */ cFYI(1, ("search backing up - close and restart search")); - cifsFile->invalidHandle = TRUE; + cifsFile->invalidHandle = true; CIFSFindClose(xid, pTcon, cifsFile->netfid); kfree(cifsFile->search_resume_name); cifsFile->search_resume_name = NULL; @@ -692,7 +692,7 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon, } while ((index_to_find >= cifsFile->srch_inf.index_of_last_entry) && - (rc == 0) && (cifsFile->srch_inf.endOfSearch == FALSE)) { + (rc == 0) && !cifsFile->srch_inf.endOfSearch) { cFYI(1, ("calling findnext2")); rc = CIFSFindNext(xid, pTcon, cifsFile->netfid, &cifsFile->srch_inf); @@ -1038,7 +1038,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir) break; } } /* else { - cifsFile->invalidHandle = TRUE; + cifsFile->invalidHandle = true; CIFSFindClose(xid, pTcon, cifsFile->netfid); } kfree(cifsFile->search_resume_name); diff --git a/fs/cifs/smbencrypt.c b/fs/cifs/smbencrypt.c index 58bbfd992cc0f4afe26f057752aeddfbd3da53ba..ff3232fa1015b4bebdcfeaa5d49a4bc365b21276 100644 --- a/fs/cifs/smbencrypt.c +++ b/fs/cifs/smbencrypt.c @@ -35,11 +35,11 @@ #include "cifs_debug.h" #include "cifsencrypt.h" -#ifndef FALSE -#define FALSE 0 +#ifndef false +#define false 0 #endif -#ifndef TRUE -#define TRUE 1 +#ifndef true +#define true 1 #endif /* following came from the other byteorder.h to avoid include conflicts */ diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c index 8cd6a445b017ae62c2028b083dce8593d5c894fc..e9527eedc6396f9afd8dd25720a78730142a14b5 100644 --- a/fs/cifs/xattr.c +++ b/fs/cifs/xattr.c @@ -264,7 +264,7 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name, #ifdef CONFIG_CIFS_EXPERIMENTAL else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { __u16 fid; - int oplock = FALSE; + int oplock = 0; struct cifs_ntsd *pacl = NULL; __u32 buflen = 0; if (experimEnabled) diff --git a/fs/compat.c b/fs/compat.c index 332a869d2c53e80a6bfb75c5e2bd3009802eca58..ed43e17a5dc68ad6663d28bc5abef135492c2e52 100644 --- a/fs/compat.c +++ b/fs/compat.c @@ -1405,7 +1405,7 @@ int compat_do_execve(char * filename, /* execve success */ security_bprm_free(bprm); acct_update_integrals(current); - kfree(bprm); + free_bprm(bprm); return retval; } @@ -1424,7 +1424,7 @@ out_file: } out_kfree: - kfree(bprm); + free_bprm(bprm); out_ret: return retval; diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c index 7c1e5e5cccd8ae97a87a618ad9818d5b35721553..637018c891eff7110620ba3aff2ff9f5e573ec8d 100644 --- a/fs/dlm/lowcomms.c +++ b/fs/dlm/lowcomms.c @@ -50,6 +50,7 @@ #include #include #include +#include #include #include @@ -138,7 +139,7 @@ static struct workqueue_struct *recv_workqueue; static struct workqueue_struct *send_workqueue; static DEFINE_IDR(connections_idr); -static DECLARE_MUTEX(connections_lock); +static DEFINE_MUTEX(connections_lock); static int max_nodeid; static struct kmem_cache *con_cache; @@ -205,9 +206,9 @@ static struct connection *nodeid2con(int nodeid, gfp_t allocation) { struct connection *con; - down(&connections_lock); + mutex_lock(&connections_lock); con = __nodeid2con(nodeid, allocation); - up(&connections_lock); + mutex_unlock(&connections_lock); return con; } @@ -218,15 +219,15 @@ static struct connection *assoc2con(int assoc_id) int i; struct connection *con; - down(&connections_lock); + mutex_lock(&connections_lock); for (i=0; i<=max_nodeid; i++) { con = __nodeid2con(i, 0); if (con && con->sctp_assoc == assoc_id) { - up(&connections_lock); + mutex_unlock(&connections_lock); return con; } } - up(&connections_lock); + mutex_unlock(&connections_lock); return NULL; } @@ -381,7 +382,7 @@ static void sctp_init_failed(void) int i; struct connection *con; - down(&connections_lock); + mutex_lock(&connections_lock); for (i=1; i<=max_nodeid; i++) { con = __nodeid2con(i, 0); if (!con) @@ -393,7 +394,7 @@ static void sctp_init_failed(void) } } } - up(&connections_lock); + mutex_unlock(&connections_lock); } /* Something happened to an association */ @@ -930,7 +931,7 @@ out_err: * errors we try again until the max number of retries is reached. */ if (result != -EHOSTUNREACH && result != -ENETUNREACH && - result != -ENETDOWN && result != EINVAL + result != -ENETDOWN && result != -EINVAL && result != -EPROTONOSUPPORT) { lowcomms_connect_sock(con); result = 0; @@ -1417,7 +1418,7 @@ void dlm_lowcomms_stop(void) /* Set all the flags to prevent any socket activity. */ - down(&connections_lock); + mutex_lock(&connections_lock); for (i = 0; i <= max_nodeid; i++) { con = __nodeid2con(i, 0); if (con) { @@ -1426,11 +1427,11 @@ void dlm_lowcomms_stop(void) con->sock->sk->sk_user_data = NULL; } } - up(&connections_lock); + mutex_unlock(&connections_lock); work_stop(); - down(&connections_lock); + mutex_lock(&connections_lock); clean_writequeues(); for (i = 0; i <= max_nodeid; i++) { @@ -1443,7 +1444,7 @@ void dlm_lowcomms_stop(void) } } max_nodeid = 0; - up(&connections_lock); + mutex_unlock(&connections_lock); kmem_cache_destroy(con_cache); idr_init(&connections_idr); } diff --git a/fs/dlm/netlink.c b/fs/dlm/netlink.c index 714593621f4f548d4a8484751e78bc53e28c7346..18bda83cc8925b3ecbb5f3b3fc5cacfb65eacadc 100644 --- a/fs/dlm/netlink.c +++ b/fs/dlm/netlink.c @@ -95,7 +95,7 @@ int __init dlm_netlink_init(void) return rv; } -void __exit dlm_netlink_exit(void) +void dlm_netlink_exit(void) { genl_unregister_ops(&family, &dlm_nl_ops); genl_unregister_family(&family); diff --git a/fs/dlm/plock.c b/fs/dlm/plock.c index d6d6e370f89c43fe3e9a89cdf4fb2d0101b39f67..78878c5781cadc0d13846d8af6a993039d8b39e6 100644 --- a/fs/dlm/plock.c +++ b/fs/dlm/plock.c @@ -379,7 +379,7 @@ static ssize_t dev_write(struct file *file, const char __user *u, size_t count, struct plock_xop *xop; xop = (struct plock_xop *)op; if (xop->callback) - count = dlm_plock_callback(op); + dlm_plock_callback(op); else wake_up(&recv_wq); } else diff --git a/fs/dquot.c b/fs/dquot.c index dfba1623cccb27a8d79a5098ace72b729ae45669..5ac77da19959f9f15792d16669d0b4110674cc3e 100644 --- a/fs/dquot.c +++ b/fs/dquot.c @@ -1491,6 +1491,16 @@ int vfs_quota_off(struct super_block *sb, int type, int remount) /* We need to serialize quota_off() for device */ mutex_lock(&dqopt->dqonoff_mutex); + + /* + * Skip everything if there's nothing to do. We have to do this because + * sometimes we are called when fill_super() failed and calling + * sync_fs() in such cases does no good. + */ + if (!sb_any_quota_enabled(sb) && !sb_any_quota_suspended(sb)) { + mutex_unlock(&dqopt->dqonoff_mutex); + return 0; + } for (cnt = 0; cnt < MAXQUOTAS; cnt++) { toputinode[cnt] = NULL; if (type != -1 && cnt != type) diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 0a1397335a8eb49a245e81b1826607a5158a2685..c92cc1c00aae9a845911011f091480d9cbe4ffca 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -37,17 +37,11 @@ static struct dentry *lock_parent(struct dentry *dentry) { struct dentry *dir; - dir = dget(dentry->d_parent); + dir = dget_parent(dentry); mutex_lock_nested(&(dir->d_inode->i_mutex), I_MUTEX_PARENT); return dir; } -static void unlock_parent(struct dentry *dentry) -{ - mutex_unlock(&(dentry->d_parent->d_inode->i_mutex)); - dput(dentry->d_parent); -} - static void unlock_dir(struct dentry *dir) { mutex_unlock(&dir->d_inode->i_mutex); @@ -426,8 +420,9 @@ static int ecryptfs_unlink(struct inode *dir, struct dentry *dentry) int rc = 0; struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir); + struct dentry *lower_dir_dentry; - lock_parent(lower_dentry); + lower_dir_dentry = lock_parent(lower_dentry); rc = vfs_unlink(lower_dir_inode, lower_dentry); if (rc) { printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc); @@ -439,7 +434,7 @@ static int ecryptfs_unlink(struct inode *dir, struct dentry *dentry) dentry->d_inode->i_ctime = dir->i_ctime; d_drop(dentry); out_unlock: - unlock_parent(lower_dentry); + unlock_dir(lower_dir_dentry); return rc; } diff --git a/fs/ecryptfs/miscdev.c b/fs/ecryptfs/miscdev.c index 788995efd1d3247298a3107935a8a54fccd80cfd..6560da1a58ce7a885f4624cd663d4d70a8eb3475 100644 --- a/fs/ecryptfs/miscdev.c +++ b/fs/ecryptfs/miscdev.c @@ -257,12 +257,14 @@ ecryptfs_miscdev_read(struct file *file, char __user *buf, size_t count, mutex_lock(&daemon->mux); if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) { rc = 0; + mutex_unlock(&ecryptfs_daemon_hash_mux); printk(KERN_WARNING "%s: Attempt to read from zombified " "daemon\n", __func__); goto out_unlock_daemon; } if (daemon->flags & ECRYPTFS_DAEMON_IN_READ) { rc = 0; + mutex_unlock(&ecryptfs_daemon_hash_mux); goto out_unlock_daemon; } /* This daemon will not go away so long as this flag is set */ diff --git a/fs/exec.c b/fs/exec.c index aeaa9791d8be2ed499aea2c314d939f385d76e54..3c2ba7ce11d46505e2e5d5539179b4435075118a 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -736,7 +736,7 @@ static int exec_mmap(struct mm_struct *mm) tsk->active_mm = mm; activate_mm(active_mm, mm); task_unlock(tsk); - mm_update_next_owner(mm); + mm_update_next_owner(old_mm); arch_pick_mmap_layout(mm); if (old_mm) { up_read(&old_mm->mmap_sem); @@ -1251,6 +1251,12 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs) EXPORT_SYMBOL(search_binary_handler); +void free_bprm(struct linux_binprm *bprm) +{ + free_arg_pages(bprm); + kfree(bprm); +} + /* * sys_execve() executes a new program. */ @@ -1320,17 +1326,15 @@ int do_execve(char * filename, retval = search_binary_handler(bprm,regs); if (retval >= 0) { /* execve success */ - free_arg_pages(bprm); security_bprm_free(bprm); acct_update_integrals(current); - kfree(bprm); + free_bprm(bprm); if (displaced) put_files_struct(displaced); return retval; } out: - free_arg_pages(bprm); if (bprm->security) security_bprm_free(bprm); @@ -1344,7 +1348,7 @@ out_file: fput(bprm->file); } out_kfree: - kfree(bprm); + free_bprm(bprm); out_files: if (displaced) diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c index d4a4f0e9ff699ae49165ea93ff4b53c162b6a60a..175414ac22109ef19bf0cf5841d131000cb7e6d2 100644 --- a/fs/ext3/xattr.c +++ b/fs/ext3/xattr.c @@ -1000,6 +1000,11 @@ ext3_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index, i.value = NULL; error = ext3_xattr_block_set(handle, inode, &i, &bs); } else if (error == -ENOSPC) { + if (EXT3_I(inode)->i_file_acl && !bs.s.base) { + error = ext3_xattr_block_find(inode, &i, &bs); + if (error) + goto cleanup; + } error = ext3_xattr_block_set(handle, inode, &i, &bs); if (error) goto cleanup; diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index da994374ec3b2c6e13c103bf9e83b7dd87353edc..30494c5da84303eb820cc5494b3f4fb2302f5e6a 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c @@ -287,11 +287,11 @@ read_block_bitmap(struct super_block *sb, ext4_group_t block_group) (int)block_group, (unsigned long long)bitmap_blk); return NULL; } - if (!ext4_valid_block_bitmap(sb, desc, block_group, bh)) { - put_bh(bh); - return NULL; - } - + ext4_valid_block_bitmap(sb, desc, block_group, bh); + /* + * file system mounted not to panic on error, + * continue with corrupt bitmap + */ return bh; } /* @@ -1770,7 +1770,12 @@ allocated: "Allocating block in system zone - " "blocks from %llu, length %lu", ret_block, num); - goto out; + /* + * claim_block marked the blocks we allocated + * as in use. So we may want to selectively + * mark some of the blocks as free + */ + goto retry_alloc; } performed_allocation = 1; diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index fbec2ef93797efb9bf6ac16f2a9465fc198dc018..873ad9b3418ceeeb6b232566e525b60ccac07616 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -2639,8 +2639,7 @@ static int ext4_mb_init_per_dev_proc(struct super_block *sb) struct proc_dir_entry *proc; char devname[64]; - snprintf(devname, sizeof(devname) - 1, "%s", - bdevname(sb->s_bdev, devname)); + bdevname(sb->s_bdev, devname); sbi->s_mb_proc = proc_mkdir(devname, proc_root_ext4); MB_PROC_HANDLER(EXT4_MB_STATS_NAME, stats); @@ -2674,8 +2673,7 @@ static int ext4_mb_destroy_per_dev_proc(struct super_block *sb) if (sbi->s_mb_proc == NULL) return -EINVAL; - snprintf(devname, sizeof(devname) - 1, "%s", - bdevname(sb->s_bdev, devname)); + bdevname(sb->s_bdev, devname); remove_proc_entry(EXT4_MB_GROUP_PREALLOC, sbi->s_mb_proc); remove_proc_entry(EXT4_MB_STREAM_REQ, sbi->s_mb_proc); remove_proc_entry(EXT4_MB_ORDER2_REQ, sbi->s_mb_proc); @@ -2738,7 +2736,7 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac, struct ext4_sb_info *sbi; struct super_block *sb; ext4_fsblk_t block; - int err; + int err, len; BUG_ON(ac->ac_status != AC_STATUS_FOUND); BUG_ON(ac->ac_b_ex.fe_len <= 0); @@ -2772,14 +2770,27 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac, + ac->ac_b_ex.fe_start + le32_to_cpu(es->s_first_data_block); - if (block == ext4_block_bitmap(sb, gdp) || - block == ext4_inode_bitmap(sb, gdp) || - in_range(block, ext4_inode_table(sb, gdp), - EXT4_SB(sb)->s_itb_per_group)) { - + len = ac->ac_b_ex.fe_len; + if (in_range(ext4_block_bitmap(sb, gdp), block, len) || + in_range(ext4_inode_bitmap(sb, gdp), block, len) || + in_range(block, ext4_inode_table(sb, gdp), + EXT4_SB(sb)->s_itb_per_group) || + in_range(block + len - 1, ext4_inode_table(sb, gdp), + EXT4_SB(sb)->s_itb_per_group)) { ext4_error(sb, __func__, "Allocating block in system zone - block = %llu", block); + /* File system mounted not to panic on error + * Fix the bitmap and repeat the block allocation + * We leak some of the blocks here. + */ + mb_set_bits(sb_bgl_lock(sbi, ac->ac_b_ex.fe_group), + bitmap_bh->b_data, ac->ac_b_ex.fe_start, + ac->ac_b_ex.fe_len); + err = ext4_journal_dirty_metadata(handle, bitmap_bh); + if (!err) + err = -EAGAIN; + goto out_err; } #ifdef AGGRESSIVE_CHECK { @@ -2882,12 +2893,11 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac, if (size < i_size_read(ac->ac_inode)) size = i_size_read(ac->ac_inode); - /* max available blocks in a free group */ - max = EXT4_BLOCKS_PER_GROUP(ac->ac_sb) - 1 - 1 - - EXT4_SB(ac->ac_sb)->s_itb_per_group; + /* max size of free chunks */ + max = 2 << bsbits; -#define NRL_CHECK_SIZE(req, size, max,bits) \ - (req <= (size) || max <= ((size) >> bits)) +#define NRL_CHECK_SIZE(req, size, max, chunk_size) \ + (req <= (size) || max <= (chunk_size)) /* first, try to predict filesize */ /* XXX: should this table be tunable? */ @@ -2906,16 +2916,16 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac, size = 512 * 1024; } else if (size <= 1024 * 1024) { size = 1024 * 1024; - } else if (NRL_CHECK_SIZE(size, 4 * 1024 * 1024, max, bsbits)) { + } else if (NRL_CHECK_SIZE(size, 4 * 1024 * 1024, max, 2 * 1024)) { start_off = ((loff_t)ac->ac_o_ex.fe_logical >> - (20 - bsbits)) << 20; - size = 1024 * 1024; - } else if (NRL_CHECK_SIZE(size, 8 * 1024 * 1024, max, bsbits)) { + (21 - bsbits)) << 21; + size = 2 * 1024 * 1024; + } else if (NRL_CHECK_SIZE(size, 8 * 1024 * 1024, max, 4 * 1024)) { start_off = ((loff_t)ac->ac_o_ex.fe_logical >> (22 - bsbits)) << 22; size = 4 * 1024 * 1024; } else if (NRL_CHECK_SIZE(ac->ac_o_ex.fe_len, - (8<<20)>>bsbits, max, bsbits)) { + (8<<20)>>bsbits, max, 8 * 1024)) { start_off = ((loff_t)ac->ac_o_ex.fe_logical >> (23 - bsbits)) << 23; size = 8 * 1024 * 1024; @@ -4035,7 +4045,6 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, ac->ac_op = EXT4_MB_HISTORY_ALLOC; ext4_mb_normalize_request(ac, ar); - repeat: /* allocate space in core */ ext4_mb_regular_allocator(ac); @@ -4049,10 +4058,21 @@ repeat: } if (likely(ac->ac_status == AC_STATUS_FOUND)) { - ext4_mb_mark_diskspace_used(ac, handle); - *errp = 0; - block = ext4_grp_offs_to_block(sb, &ac->ac_b_ex); - ar->len = ac->ac_b_ex.fe_len; + *errp = ext4_mb_mark_diskspace_used(ac, handle); + if (*errp == -EAGAIN) { + ac->ac_b_ex.fe_group = 0; + ac->ac_b_ex.fe_start = 0; + ac->ac_b_ex.fe_len = 0; + ac->ac_status = AC_STATUS_CONTINUE; + goto repeat; + } else if (*errp) { + ac->ac_b_ex.fe_len = 0; + ar->len = 0; + ext4_mb_show_ac(ac); + } else { + block = ext4_grp_offs_to_block(sb, &ac->ac_b_ex); + ar->len = ac->ac_b_ex.fe_len; + } } else { freed = ext4_mb_discard_preallocations(sb, ac->ac_o_ex.fe_len); if (freed) @@ -4239,6 +4259,8 @@ do_more: ext4_error(sb, __func__, "Freeing blocks in system zone - " "Block = %lu, count = %lu", block, count); + /* err = 0. ext4_std_error should be a no op */ + goto error_return; } BUFFER_TRACE(bitmap_bh, "getting write access"); diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 52dd0679a4e2f8d77e418cb1f6bd5a842bc10ca1..09d9359c80550a66654653b0993c30117b9f0865 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -979,7 +979,7 @@ static int parse_options (char *options, struct super_block *sb, int data_opt = 0; int option; #ifdef CONFIG_QUOTA - int qtype; + int qtype, qfmt; char *qname; #endif @@ -1162,9 +1162,11 @@ static int parse_options (char *options, struct super_block *sb, case Opt_grpjquota: qtype = GRPQUOTA; set_qf_name: - if (sb_any_quota_enabled(sb)) { + if ((sb_any_quota_enabled(sb) || + sb_any_quota_suspended(sb)) && + !sbi->s_qf_names[qtype]) { printk(KERN_ERR - "EXT4-fs: Cannot change journalled " + "EXT4-fs: Cannot change journaled " "quota options when quota turned on.\n"); return 0; } @@ -1200,9 +1202,11 @@ set_qf_name: case Opt_offgrpjquota: qtype = GRPQUOTA; clear_qf_name: - if (sb_any_quota_enabled(sb)) { + if ((sb_any_quota_enabled(sb) || + sb_any_quota_suspended(sb)) && + sbi->s_qf_names[qtype]) { printk(KERN_ERR "EXT4-fs: Cannot change " - "journalled quota options when " + "journaled quota options when " "quota turned on.\n"); return 0; } @@ -1213,10 +1217,20 @@ clear_qf_name: sbi->s_qf_names[qtype] = NULL; break; case Opt_jqfmt_vfsold: - sbi->s_jquota_fmt = QFMT_VFS_OLD; - break; + qfmt = QFMT_VFS_OLD; + goto set_qf_format; case Opt_jqfmt_vfsv0: - sbi->s_jquota_fmt = QFMT_VFS_V0; + qfmt = QFMT_VFS_V0; +set_qf_format: + if ((sb_any_quota_enabled(sb) || + sb_any_quota_suspended(sb)) && + sbi->s_jquota_fmt != qfmt) { + printk(KERN_ERR "EXT4-fs: Cannot change " + "journaled quota options when " + "quota turned on.\n"); + return 0; + } + sbi->s_jquota_fmt = qfmt; break; case Opt_quota: case Opt_usrquota: @@ -1241,6 +1255,9 @@ clear_qf_name: case Opt_quota: case Opt_usrquota: case Opt_grpquota: + printk(KERN_ERR + "EXT4-fs: quota options not supported.\n"); + break; case Opt_usrjquota: case Opt_grpjquota: case Opt_offusrjquota: @@ -1248,7 +1265,7 @@ clear_qf_name: case Opt_jqfmt_vfsold: case Opt_jqfmt_vfsv0: printk(KERN_ERR - "EXT4-fs: journalled quota options not " + "EXT4-fs: journaled quota options not " "supported.\n"); break; case Opt_noquota: @@ -1333,14 +1350,14 @@ clear_qf_name: } if (!sbi->s_jquota_fmt) { - printk(KERN_ERR "EXT4-fs: journalled quota format " + printk(KERN_ERR "EXT4-fs: journaled quota format " "not specified.\n"); return 0; } } else { if (sbi->s_jquota_fmt) { - printk(KERN_ERR "EXT4-fs: journalled quota format " - "specified with no journalling " + printk(KERN_ERR "EXT4-fs: journaled quota format " + "specified with no journaling " "enabled.\n"); return 0; } @@ -1581,7 +1598,7 @@ static void ext4_orphan_cleanup (struct super_block * sb, int ret = ext4_quota_on_mount(sb, i); if (ret < 0) printk(KERN_ERR - "EXT4-fs: Cannot turn on journalled " + "EXT4-fs: Cannot turn on journaled " "quota: error %d\n", ret); } } @@ -3106,7 +3123,7 @@ static int ext4_release_dquot(struct dquot *dquot) static int ext4_mark_dquot_dirty(struct dquot *dquot) { - /* Are we journalling quotas? */ + /* Are we journaling quotas? */ if (EXT4_SB(dquot->dq_sb)->s_qf_names[USRQUOTA] || EXT4_SB(dquot->dq_sb)->s_qf_names[GRPQUOTA]) { dquot_mark_dquot_dirty(dquot); @@ -3153,23 +3170,42 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id, if (!test_opt(sb, QUOTA)) return -EINVAL; - /* Not journalling quota? */ - if ((!EXT4_SB(sb)->s_qf_names[USRQUOTA] && - !EXT4_SB(sb)->s_qf_names[GRPQUOTA]) || remount) + /* When remounting, no checks are needed and in fact, path is NULL */ + if (remount) return vfs_quota_on(sb, type, format_id, path, remount); + err = path_lookup(path, LOOKUP_FOLLOW, &nd); if (err) return err; + /* Quotafile not on the same filesystem? */ if (nd.path.mnt->mnt_sb != sb) { path_put(&nd.path); return -EXDEV; } - /* Quotafile not of fs root? */ - if (nd.path.dentry->d_parent->d_inode != sb->s_root->d_inode) - printk(KERN_WARNING - "EXT4-fs: Quota file not on filesystem root. " - "Journalled quota will not work.\n"); + /* Journaling quota? */ + if (EXT4_SB(sb)->s_qf_names[type]) { + /* Quotafile not of fs root? */ + if (nd.path.dentry->d_parent->d_inode != sb->s_root->d_inode) + printk(KERN_WARNING + "EXT4-fs: Quota file not on filesystem root. " + "Journaled quota will not work.\n"); + } + + /* + * When we journal data on quota file, we have to flush journal to see + * all updates to the file when we bypass pagecache... + */ + if (ext4_should_journal_data(nd.path.dentry->d_inode)) { + /* + * We don't need to lock updates but journal_flush() could + * otherwise be livelocked... + */ + jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); + jbd2_journal_flush(EXT4_SB(sb)->s_journal); + jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); + } + path_put(&nd.path); return vfs_quota_on(sb, type, format_id, path, remount); } diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 3fbc2c6c3d0e900c5ce8e1a5f8e56270f5984768..ff08633f398edb410cba33f9912f743ebfa29ada 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -1009,6 +1009,11 @@ ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index, i.value = NULL; error = ext4_xattr_block_set(handle, inode, &i, &bs); } else if (error == -ENOSPC) { + if (EXT4_I(inode)->i_file_acl && !bs.s.base) { + error = ext4_xattr_block_find(inode, &i, &bs); + if (error) + goto cleanup; + } error = ext4_xattr_block_set(handle, inode, &i, &bs); if (error) goto cleanup; diff --git a/fs/file.c b/fs/file.c index 4c6f0ea12c419c52154558c271586b7887dabf13..7b3887e054d0bcb5e0e187c8e1e42691c4fadcd0 100644 --- a/fs/file.c +++ b/fs/file.c @@ -26,6 +26,8 @@ struct fdtable_defer { }; int sysctl_nr_open __read_mostly = 1024*1024; +int sysctl_nr_open_min = BITS_PER_LONG; +int sysctl_nr_open_max = 1024 * 1024; /* raised later */ /* * We use this list to defer free fdtables that have vmalloced @@ -119,8 +121,6 @@ static void copy_fdtable(struct fdtable *nfdt, struct fdtable *ofdt) unsigned int cpy, set; BUG_ON(nfdt->max_fds < ofdt->max_fds); - if (ofdt->max_fds == 0) - return; cpy = ofdt->max_fds * sizeof(struct file *); set = (nfdt->max_fds - ofdt->max_fds) * sizeof(struct file *); @@ -261,6 +261,139 @@ int expand_files(struct files_struct *files, int nr) return expand_fdtable(files, nr); } +static int count_open_files(struct fdtable *fdt) +{ + int size = fdt->max_fds; + int i; + + /* Find the last open fd */ + for (i = size/(8*sizeof(long)); i > 0; ) { + if (fdt->open_fds->fds_bits[--i]) + break; + } + i = (i+1) * 8 * sizeof(long); + return i; +} + +/* + * Allocate a new files structure and copy contents from the + * passed in files structure. + * errorp will be valid only when the returned files_struct is NULL. + */ +struct files_struct *dup_fd(struct files_struct *oldf, int *errorp) +{ + struct files_struct *newf; + struct file **old_fds, **new_fds; + int open_files, size, i; + struct fdtable *old_fdt, *new_fdt; + + *errorp = -ENOMEM; + newf = kmem_cache_alloc(files_cachep, GFP_KERNEL); + if (!newf) + goto out; + + atomic_set(&newf->count, 1); + + spin_lock_init(&newf->file_lock); + newf->next_fd = 0; + new_fdt = &newf->fdtab; + new_fdt->max_fds = NR_OPEN_DEFAULT; + new_fdt->close_on_exec = (fd_set *)&newf->close_on_exec_init; + new_fdt->open_fds = (fd_set *)&newf->open_fds_init; + new_fdt->fd = &newf->fd_array[0]; + INIT_RCU_HEAD(&new_fdt->rcu); + new_fdt->next = NULL; + + spin_lock(&oldf->file_lock); + old_fdt = files_fdtable(oldf); + open_files = count_open_files(old_fdt); + + /* + * Check whether we need to allocate a larger fd array and fd set. + */ + while (unlikely(open_files > new_fdt->max_fds)) { + spin_unlock(&oldf->file_lock); + + if (new_fdt != &newf->fdtab) { + free_fdarr(new_fdt); + free_fdset(new_fdt); + kfree(new_fdt); + } + + new_fdt = alloc_fdtable(open_files - 1); + if (!new_fdt) { + *errorp = -ENOMEM; + goto out_release; + } + + /* beyond sysctl_nr_open; nothing to do */ + if (unlikely(new_fdt->max_fds < open_files)) { + free_fdarr(new_fdt); + free_fdset(new_fdt); + kfree(new_fdt); + *errorp = -EMFILE; + goto out_release; + } + + /* + * Reacquire the oldf lock and a pointer to its fd table + * who knows it may have a new bigger fd table. We need + * the latest pointer. + */ + spin_lock(&oldf->file_lock); + old_fdt = files_fdtable(oldf); + open_files = count_open_files(old_fdt); + } + + old_fds = old_fdt->fd; + new_fds = new_fdt->fd; + + memcpy(new_fdt->open_fds->fds_bits, + old_fdt->open_fds->fds_bits, open_files/8); + memcpy(new_fdt->close_on_exec->fds_bits, + old_fdt->close_on_exec->fds_bits, open_files/8); + + for (i = open_files; i != 0; i--) { + struct file *f = *old_fds++; + if (f) { + get_file(f); + } else { + /* + * The fd may be claimed in the fd bitmap but not yet + * instantiated in the files array if a sibling thread + * is partway through open(). So make sure that this + * fd is available to the new process. + */ + FD_CLR(open_files - i, new_fdt->open_fds); + } + rcu_assign_pointer(*new_fds++, f); + } + spin_unlock(&oldf->file_lock); + + /* compute the remainder to be cleared */ + size = (new_fdt->max_fds - open_files) * sizeof(struct file *); + + /* This is long word aligned thus could use a optimized version */ + memset(new_fds, 0, size); + + if (new_fdt->max_fds > open_files) { + int left = (new_fdt->max_fds-open_files)/8; + int start = open_files / (8 * sizeof(unsigned long)); + + memset(&new_fdt->open_fds->fds_bits[start], 0, left); + memset(&new_fdt->close_on_exec->fds_bits[start], 0, left); + } + + rcu_assign_pointer(newf->fdt, new_fdt); + + return newf; + +out_release: + kmem_cache_free(files_cachep, newf); +out: + return NULL; +} + static void __devinit fdtable_defer_list_init(int cpu) { struct fdtable_defer *fddef = &per_cpu(fdtable_defer_list, cpu); @@ -274,4 +407,19 @@ void __init files_defer_init(void) int i; for_each_possible_cpu(i) fdtable_defer_list_init(i); + sysctl_nr_open_max = min((size_t)INT_MAX, ~(size_t)0/sizeof(void *)) & + -BITS_PER_LONG; } + +struct files_struct init_files = { + .count = ATOMIC_INIT(1), + .fdt = &init_files.fdtab, + .fdtab = { + .max_fds = NR_OPEN_DEFAULT, + .fd = &init_files.fd_array[0], + .close_on_exec = (fd_set *)&init_files.close_on_exec_init, + .open_fds = (fd_set *)&init_files.open_fds_init, + .rcu = RCU_HEAD_INIT, + }, + .file_lock = __SPIN_LOCK_UNLOCKED(init_task.file_lock), +}; diff --git a/fs/fuse/file.c b/fs/fuse/file.c index f28cf8b46f806f89c595de8f746731032e625d0d..8092f0d9fd1fa590ac87f7f0ec7a79331760acb6 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -804,6 +804,8 @@ static ssize_t fuse_fill_write_pages(struct fuse_req *req, if (offset == PAGE_CACHE_SIZE) offset = 0; + if (!fc->big_writes) + break; } while (iov_iter_count(ii) && count < fc->max_write && req->num_pages < FUSE_MAX_PAGES_PER_REQ && offset == 0); diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index dadffa21a206d220307e9b3e1212b09080bf5741..bae948657c4fdfd268e86912c6b4fa6c1f944851 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -404,6 +404,9 @@ struct fuse_conn { /** Is bmap not implemented by fs? */ unsigned no_bmap : 1; + /** Do multi-page cached writes */ + unsigned big_writes : 1; + /** The number of requests waiting for completion */ atomic_t num_waiting; diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 79b61587383832f7a7ff2187642f0fdcc509f047..fb77e0962132ea5ee1d2f9dc28f97206335f9125 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -576,6 +576,8 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) fc->no_lock = 1; if (arg->flags & FUSE_ATOMIC_O_TRUNC) fc->atomic_o_trunc = 1; + if (arg->flags & FUSE_BIG_WRITES) + fc->big_writes = 1; } else { ra_pages = fc->max_read / PAGE_CACHE_SIZE; fc->no_lock = 1; @@ -599,7 +601,8 @@ static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req) arg->major = FUSE_KERNEL_VERSION; arg->minor = FUSE_KERNEL_MINOR_VERSION; arg->max_readahead = fc->bdi.ra_pages * PAGE_CACHE_SIZE; - arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_ATOMIC_O_TRUNC; + arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_ATOMIC_O_TRUNC | + FUSE_BIG_WRITES; req->in.h.opcode = FUSE_INIT; req->in.numargs = 1; req->in.args[0].size = sizeof(*arg); diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index d53b2af91c25d78e39c17a692733224753e1905f..67e1c8b467c496565359331e79ca7c706166a30d 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c @@ -65,6 +65,8 @@ static int hfsplus_releasepage(struct page *page, gfp_t mask) BUG(); return 0; } + if (!tree) + return 0; if (tree->node_size >= PAGE_CACHE_SIZE) { nidx = page->index >> (tree->node_size_shift - PAGE_CACHE_SHIFT); spin_lock(&tree->hash_lock); diff --git a/fs/hppfs/Makefile b/fs/hppfs/Makefile index 6890433f7595c7514c0dd9ee8fb5cbc1ba103b11..8a1f50344368a9e1c1a3efab4120effd5d7e70da 100644 --- a/fs/hppfs/Makefile +++ b/fs/hppfs/Makefile @@ -1,9 +1,9 @@ # -# Copyright (C) 2002, 2003 Jeff Dike (jdike@karaya.com) +# Copyright (C) 2002 - 2008 Jeff Dike (jdike@{addtoit,linux.intel}.com) # Licensed under the GPL # -hppfs-objs := hppfs_kern.o +hppfs-objs := hppfs.o obj-y = -obj-$(CONFIG_HPPFS) += hppfs.o +obj-$(CONFIG_HPPFS) += $(hppfs-objs) diff --git a/fs/hppfs/hppfs_kern.c b/fs/hppfs/hppfs.c similarity index 92% rename from fs/hppfs/hppfs_kern.c rename to fs/hppfs/hppfs.c index 8601d8ef3b550d1c803c3a5bb7cd37f831717fd2..65077aa90f0a74ea405d25ff5796fe3ef3442be1 100644 --- a/fs/hppfs/hppfs_kern.c +++ b/fs/hppfs/hppfs.c @@ -33,7 +33,7 @@ struct hppfs_private { }; struct hppfs_inode_info { - struct dentry *proc_dentry; + struct dentry *proc_dentry; struct inode vfs_inode; }; @@ -52,7 +52,7 @@ static int is_pid(struct dentry *dentry) int i; sb = dentry->d_sb; - if ((sb->s_op != &hppfs_sbops) || (dentry->d_parent != sb->s_root)) + if (dentry->d_parent != sb->s_root) return 0; for (i = 0; i < dentry->d_name.len; i++) { @@ -136,7 +136,7 @@ static int file_removed(struct dentry *dentry, const char *file) } static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry, - struct nameidata *nd) + struct nameidata *nd) { struct dentry *proc_dentry, *new, *parent; struct inode *inode; @@ -254,6 +254,8 @@ static ssize_t hppfs_read(struct file *file, char __user *buf, size_t count, int err; if (hppfs->contents != NULL) { + int rem; + if (*ppos >= hppfs->len) return 0; @@ -267,8 +269,10 @@ static ssize_t hppfs_read(struct file *file, char __user *buf, size_t count, if (off + count > hppfs->len) count = hppfs->len - off; - copy_to_user(buf, &data->contents[off], count); - *ppos += count; + rem = copy_to_user(buf, &data->contents[off], count); + *ppos += count - rem; + if (rem > 0) + return -EFAULT; } else if (hppfs->host_fd != -1) { err = os_seek_file(hppfs->host_fd, *ppos); if (err) { @@ -285,21 +289,15 @@ static ssize_t hppfs_read(struct file *file, char __user *buf, size_t count, return count; } -static ssize_t hppfs_write(struct file *file, const char __user *buf, size_t len, - loff_t *ppos) +static ssize_t hppfs_write(struct file *file, const char __user *buf, + size_t len, loff_t *ppos) { struct hppfs_private *data = file->private_data; struct file *proc_file = data->proc_file; ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *); - int err; write = proc_file->f_path.dentry->d_inode->i_fop->write; - - proc_file->f_pos = file->f_pos; - err = (*write)(proc_file, buf, len, &proc_file->f_pos); - file->f_pos = proc_file->f_pos; - - return err; + return (*write)(proc_file, buf, len, ppos); } static int open_host_sock(char *host_file, int *filter_out) @@ -357,7 +355,7 @@ static struct hppfs_data *hppfs_get_data(int fd, int filter, if (filter) { while ((n = read_proc(proc_file, data->contents, - sizeof(data->contents), NULL, 0)) > 0) + sizeof(data->contents), NULL, 0)) > 0) os_write_file(fd, data->contents, n); err = os_shutdown_socket(fd, 0, 1); if (err) { @@ -429,8 +427,8 @@ static int file_mode(int fmode) static int hppfs_open(struct inode *inode, struct file *file) { struct hppfs_private *data; - struct dentry *proc_dentry; struct vfsmount *proc_mnt; + struct dentry *proc_dentry; char *host_file; int err, fd, type, filter; @@ -492,8 +490,8 @@ static int hppfs_open(struct inode *inode, struct file *file) static int hppfs_dir_open(struct inode *inode, struct file *file) { struct hppfs_private *data; - struct dentry *proc_dentry; struct vfsmount *proc_mnt; + struct dentry *proc_dentry; int err; err = -ENOMEM; @@ -620,6 +618,9 @@ static struct inode *hppfs_alloc_inode(struct super_block *sb) void hppfs_delete_inode(struct inode *ino) { + dput(HPPFS_I(ino)->proc_dentry); + mntput(ino->i_sb->s_fs_info); + clear_inode(ino); } @@ -628,69 +629,46 @@ static void hppfs_destroy_inode(struct inode *inode) kfree(HPPFS_I(inode)); } -static void hppfs_put_super(struct super_block *sb) -{ - mntput(sb->s_fs_info); -} - static const struct super_operations hppfs_sbops = { .alloc_inode = hppfs_alloc_inode, .destroy_inode = hppfs_destroy_inode, .delete_inode = hppfs_delete_inode, .statfs = hppfs_statfs, - .put_super = hppfs_put_super, }; static int hppfs_readlink(struct dentry *dentry, char __user *buffer, int buflen) { - struct file *proc_file; struct dentry *proc_dentry; - struct vfsmount *proc_mnt; - int ret; proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry; - proc_mnt = dentry->d_sb->s_fs_info; - - proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt), O_RDONLY); - if (IS_ERR(proc_file)) - return PTR_ERR(proc_file); - - ret = proc_dentry->d_inode->i_op->readlink(proc_dentry, buffer, buflen); - - fput(proc_file); - - return ret; + return proc_dentry->d_inode->i_op->readlink(proc_dentry, buffer, + buflen); } -static void* hppfs_follow_link(struct dentry *dentry, struct nameidata *nd) +static void *hppfs_follow_link(struct dentry *dentry, struct nameidata *nd) { - struct file *proc_file; struct dentry *proc_dentry; - struct vfsmount *proc_mnt; - void *ret; proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry; - proc_mnt = dentry->d_sb->s_fs_info; - - proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt), O_RDONLY); - if (IS_ERR(proc_file)) - return proc_file; - - ret = proc_dentry->d_inode->i_op->follow_link(proc_dentry, nd); - fput(proc_file); + return proc_dentry->d_inode->i_op->follow_link(proc_dentry, nd); +} - return ret; +int hppfs_permission(struct inode *inode, int mask, struct nameidata *nd) +{ + return generic_permission(inode, mask, NULL); } static const struct inode_operations hppfs_dir_iops = { .lookup = hppfs_lookup, + .permission = hppfs_permission, }; static const struct inode_operations hppfs_link_iops = { .readlink = hppfs_readlink, .follow_link = hppfs_follow_link, + .permission = hppfs_permission, }; static struct inode *get_inode(struct super_block *sb, struct dentry *dentry) @@ -712,7 +690,7 @@ static struct inode *get_inode(struct super_block *sb, struct dentry *dentry) inode->i_fop = &hppfs_file_fops; } - HPPFS_I(inode)->proc_dentry = dentry; + HPPFS_I(inode)->proc_dentry = dget(dentry); inode->i_uid = proc_ino->i_uid; inode->i_gid = proc_ino->i_gid; @@ -725,7 +703,7 @@ static struct inode *get_inode(struct super_block *sb, struct dentry *dentry) inode->i_size = proc_ino->i_size; inode->i_blocks = proc_ino->i_blocks; - return 0; + return inode; } static int hppfs_fill_super(struct super_block *sb, void *d, int silent) diff --git a/fs/inode.c b/fs/inode.c index bf64781304243f62cc1ff52f9f395724651103d7..c36d9480335c6fc8a099aa1551910b0ce55a539f 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -1149,13 +1149,8 @@ static inline void iput_final(struct inode *inode) void iput(struct inode *inode) { if (inode) { - const struct super_operations *op = inode->i_sb->s_op; - BUG_ON(inode->i_state == I_CLEAR); - if (op && op->put_inode) - op->put_inode(inode); - if (atomic_dec_and_lock(&inode->i_count, &inode_lock)) iput_final(inode); } diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c index cd931ef1f000b2bb9c606b9be7b6c35c4b2c241a..5a8ca61498caf36cbb818fddc00eafbca2642f03 100644 --- a/fs/jbd/commit.c +++ b/fs/jbd/commit.c @@ -470,7 +470,9 @@ void journal_commit_transaction(journal_t *journal) * transaction! Now comes the tricky part: we need to write out * metadata. Loop over the transaction's entire buffer list: */ + spin_lock(&journal->j_state_lock); commit_transaction->t_state = T_COMMIT; + spin_unlock(&journal->j_state_lock); J_ASSERT(commit_transaction->t_nr_buffers <= commit_transaction->t_outstanding_credits); diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index e0139786f717839ff5c7b5f542449593c1fcab54..4d99685fdce43b5ebb1c5ccbcab5a89c2443747a 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c @@ -560,7 +560,9 @@ void jbd2_journal_commit_transaction(journal_t *journal) * transaction! Now comes the tricky part: we need to write out * metadata. Loop over the transaction's entire buffer list: */ + spin_lock(&journal->j_state_lock); commit_transaction->t_state = T_COMMIT; + spin_unlock(&journal->j_state_lock); stats.u.run.rs_logging = jiffies; stats.u.run.rs_flushing = jbd2_time_diff(stats.u.run.rs_flushing, diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 53632e3e8457e6227a182b28ea0d75a49880c5f6..2e24567c4a797ddf5c18c481bf53eef8bc01ad50 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c @@ -901,7 +901,7 @@ static void jbd2_stats_proc_init(journal_t *journal) { char name[BDEVNAME_SIZE]; - snprintf(name, sizeof(name) - 1, "%s", bdevname(journal->j_dev, name)); + bdevname(journal->j_dev, name); journal->j_proc_entry = proc_mkdir(name, proc_jbd2_stats); if (journal->j_proc_entry) { proc_create_data("history", S_IRUGO, journal->j_proc_entry, @@ -915,7 +915,7 @@ static void jbd2_stats_proc_exit(journal_t *journal) { char name[BDEVNAME_SIZE]; - snprintf(name, sizeof(name) - 1, "%s", bdevname(journal->j_dev, name)); + bdevname(journal->j_dev, name); remove_proc_entry("info", journal->j_proc_entry); remove_proc_entry("history", journal->j_proc_entry); remove_proc_entry(name, proc_jbd2_stats); diff --git a/fs/locks.c b/fs/locks.c index 663c069b59b3d6490fd2fa9046d4d0bc3620a581..11dbf08651b70861d31530ef73436dc2e3beffc1 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -773,7 +773,7 @@ static int flock_lock_file(struct file *filp, struct file_lock *request) * give it the opportunity to lock the file. */ if (found) - cond_resched(); + cond_resched_bkl(); find_conflict: for_each_lock(inode, before) { @@ -1753,6 +1753,7 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd, struct file_lock *file_lock = locks_alloc_lock(); struct flock flock; struct inode *inode; + struct file *f; int error; if (file_lock == NULL) @@ -1825,7 +1826,15 @@ again: * Attempt to detect a close/fcntl race and recover by * releasing the lock that was just acquired. */ - if (!error && fcheck(fd) != filp && flock.l_type != F_UNLCK) { + /* + * we need that spin_lock here - it prevents reordering between + * update of inode->i_flock and check for it done in close(). + * rcu_read_lock() wouldn't do. + */ + spin_lock(¤t->files->file_lock); + f = fcheck(fd); + spin_unlock(¤t->files->file_lock); + if (!error && f != filp && flock.l_type != F_UNLCK) { flock.l_type = F_UNLCK; goto again; } @@ -1881,6 +1890,7 @@ int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd, struct file_lock *file_lock = locks_alloc_lock(); struct flock64 flock; struct inode *inode; + struct file *f; int error; if (file_lock == NULL) @@ -1953,7 +1963,10 @@ again: * Attempt to detect a close/fcntl race and recover by * releasing the lock that was just acquired. */ - if (!error && fcheck(fd) != filp && flock.l_type != F_UNLCK) { + spin_lock(¤t->files->file_lock); + f = fcheck(fd); + spin_unlock(¤t->files->file_lock); + if (!error && f != filp && flock.l_type != F_UNLCK) { flock.l_type = F_UNLCK; goto again; } diff --git a/fs/namei.c b/fs/namei.c index 32fd9655485b7fc9b8c8616ad6a61f6ac243b328..c7e43536c49ad06433c5963c446ce936e0f94e9f 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -2003,18 +2003,22 @@ struct dentry *lookup_create(struct nameidata *nd, int is_dir) if (IS_ERR(dentry)) goto fail; + if (dentry->d_inode) + goto eexist; /* * Special case - lookup gave negative, but... we had foo/bar/ * From the vfs_mknod() POV we just have a negative dentry - * all is fine. Let's be bastards - you had / on the end, you've * been asking for (non-existent) directory. -ENOENT for you. */ - if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode) - goto enoent; + if (unlikely(!is_dir && nd->last.name[nd->last.len])) { + dput(dentry); + dentry = ERR_PTR(-ENOENT); + } return dentry; -enoent: +eexist: dput(dentry); - dentry = ERR_PTR(-ENOENT); + dentry = ERR_PTR(-EEXIST); fail: return dentry; } diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index 5606ae3d72d377792bfd8689487389cc967315b5..c1e7c83006292c5085d2b2cb5b54f6d46fb0e2fa 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c @@ -182,7 +182,7 @@ static int nfs_callback_authenticate(struct svc_rqst *rqstp) if (clp == NULL) return SVC_DROP; - dprintk("%s: %s NFSv4 callback!\n", __FUNCTION__, + dprintk("%s: %s NFSv4 callback!\n", __func__, svc_print_addr(rqstp, buf, sizeof(buf))); nfs_put_client(clp); diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index 15f7785048d3eca72defd3ddfc64452301226f5f..f7e83e23cf9f47a991ee6d303eee2227009f2712 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c @@ -57,7 +57,7 @@ out_iput: out_putclient: nfs_put_client(clp); out: - dprintk("%s: exit with status = %d\n", __FUNCTION__, ntohl(res->status)); + dprintk("%s: exit with status = %d\n", __func__, ntohl(res->status)); return res->status; } @@ -98,6 +98,6 @@ __be32 nfs4_callback_recall(struct cb_recallargs *args, void *dummy) nfs_put_client(prev); } while (clp != NULL); out: - dprintk("%s: exit with status = %d\n", __FUNCTION__, ntohl(res)); + dprintk("%s: exit with status = %d\n", __func__, ntohl(res)); return res; } diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c index 13619d24f023f5a3822109f122ee58f8d2aca521..dd0ef34b58450409b0ca959dca6f8e90c00568d7 100644 --- a/fs/nfs/callback_xdr.c +++ b/fs/nfs/callback_xdr.c @@ -141,7 +141,7 @@ static __be32 decode_compound_hdr_arg(struct xdr_stream *xdr, struct cb_compound /* We do not like overly long tags! */ if (hdr->taglen > CB_OP_TAGLEN_MAXSZ - 12) { printk("NFSv4 CALLBACK %s: client sent tag of length %u\n", - __FUNCTION__, hdr->taglen); + __func__, hdr->taglen); return htonl(NFS4ERR_RESOURCE); } p = read_buf(xdr, 12); @@ -151,7 +151,7 @@ static __be32 decode_compound_hdr_arg(struct xdr_stream *xdr, struct cb_compound /* Check minor version is zero. */ if (minor_version != 0) { printk(KERN_WARNING "%s: NFSv4 server callback with illegal minor version %u!\n", - __FUNCTION__, minor_version); + __func__, minor_version); return htonl(NFS4ERR_MINOR_VERS_MISMATCH); } hdr->callback_ident = ntohl(*p++); @@ -179,7 +179,7 @@ static __be32 decode_getattr_args(struct svc_rqst *rqstp, struct xdr_stream *xdr args->addr = svc_addr(rqstp); status = decode_bitmap(xdr, args->bitmap); out: - dprintk("%s: exit with status = %d\n", __FUNCTION__, ntohl(status)); + dprintk("%s: exit with status = %d\n", __func__, ntohl(status)); return status; } @@ -200,7 +200,7 @@ static __be32 decode_recall_args(struct svc_rqst *rqstp, struct xdr_stream *xdr, args->truncate = ntohl(*p); status = decode_fh(xdr, &args->fh); out: - dprintk("%s: exit with status = %d\n", __FUNCTION__, ntohl(status)); + dprintk("%s: exit with status = %d\n", __func__, ntohl(status)); return status; } @@ -349,7 +349,7 @@ static __be32 encode_getattr_res(struct svc_rqst *rqstp, struct xdr_stream *xdr, status = encode_attr_mtime(xdr, res->bitmap, &res->mtime); *savep = htonl((unsigned int)((char *)xdr->p - (char *)(savep+1))); out: - dprintk("%s: exit with status = %d\n", __FUNCTION__, ntohl(status)); + dprintk("%s: exit with status = %d\n", __func__, ntohl(status)); return status; } @@ -363,7 +363,7 @@ static __be32 process_op(struct svc_rqst *rqstp, long maxlen; __be32 res; - dprintk("%s: start\n", __FUNCTION__); + dprintk("%s: start\n", __func__); status = decode_op_hdr(xdr_in, &op_nr); if (likely(status == 0)) { switch (op_nr) { @@ -392,7 +392,7 @@ static __be32 process_op(struct svc_rqst *rqstp, status = res; if (op->encode_res != NULL && status == 0) status = op->encode_res(rqstp, xdr_out, resp); - dprintk("%s: done, status = %d\n", __FUNCTION__, ntohl(status)); + dprintk("%s: done, status = %d\n", __func__, ntohl(status)); return status; } @@ -401,37 +401,37 @@ static __be32 process_op(struct svc_rqst *rqstp, */ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *resp) { - struct cb_compound_hdr_arg hdr_arg; - struct cb_compound_hdr_res hdr_res; + struct cb_compound_hdr_arg hdr_arg = { 0 }; + struct cb_compound_hdr_res hdr_res = { NULL }; struct xdr_stream xdr_in, xdr_out; __be32 *p; __be32 status; - unsigned int nops = 1; + unsigned int nops = 0; - dprintk("%s: start\n", __FUNCTION__); + dprintk("%s: start\n", __func__); xdr_init_decode(&xdr_in, &rqstp->rq_arg, rqstp->rq_arg.head[0].iov_base); p = (__be32*)((char *)rqstp->rq_res.head[0].iov_base + rqstp->rq_res.head[0].iov_len); xdr_init_encode(&xdr_out, &rqstp->rq_res, p); - decode_compound_hdr_arg(&xdr_in, &hdr_arg); + status = decode_compound_hdr_arg(&xdr_in, &hdr_arg); + if (status == __constant_htonl(NFS4ERR_RESOURCE)) + return rpc_garbage_args; + hdr_res.taglen = hdr_arg.taglen; hdr_res.tag = hdr_arg.tag; - hdr_res.nops = NULL; - encode_compound_hdr_res(&xdr_out, &hdr_res); + if (encode_compound_hdr_res(&xdr_out, &hdr_res) != 0) + return rpc_system_err; - for (;;) { + while (status == 0 && nops != hdr_arg.nops) { status = process_op(rqstp, &xdr_in, argp, &xdr_out, resp); - if (status != 0) - break; - if (nops == hdr_arg.nops) - break; nops++; } + *hdr_res.status = status; *hdr_res.nops = htonl(nops); - dprintk("%s: done, status = %u\n", __FUNCTION__, ntohl(status)); + dprintk("%s: done, status = %u\n", __func__, ntohl(status)); return rpc_success; } diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 89ac5bb0401c243784925cef21199036558a2c0d..f2a092ca69b5649479698172795ffedc0bbf8219 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -488,7 +488,7 @@ static int nfs_create_rpc_client(struct nfs_client *clp, clnt = rpc_create(&args); if (IS_ERR(clnt)) { dprintk("%s: cannot create RPC client. Error = %ld\n", - __FUNCTION__, PTR_ERR(clnt)); + __func__, PTR_ERR(clnt)); return PTR_ERR(clnt); } @@ -576,7 +576,7 @@ static int nfs_init_server_rpcclient(struct nfs_server *server, server->client = rpc_clone_client(clp->cl_rpcclient); if (IS_ERR(server->client)) { - dprintk("%s: couldn't create rpc_client!\n", __FUNCTION__); + dprintk("%s: couldn't create rpc_client!\n", __func__); return PTR_ERR(server->client); } @@ -590,7 +590,7 @@ static int nfs_init_server_rpcclient(struct nfs_server *server, auth = rpcauth_create(pseudoflavour, server->client); if (IS_ERR(auth)) { - dprintk("%s: couldn't create credcache!\n", __FUNCTION__); + dprintk("%s: couldn't create credcache!\n", __func__); return PTR_ERR(auth); } } @@ -985,7 +985,7 @@ static int nfs4_init_client(struct nfs_client *clp, error = nfs_idmap_new(clp); if (error < 0) { dprintk("%s: failed to create idmapper. Error = %d\n", - __FUNCTION__, error); + __func__, error); goto error; } __set_bit(NFS_CS_IDMAP, &clp->cl_res_state); diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index 00a5e4405e16e2c41475f27c28ed7cc75c5a7bf7..cc563cfa69407c64553d4e6730bc020df2f11790 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c @@ -60,7 +60,7 @@ static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_ switch (status) { default: printk(KERN_ERR "%s: unhandled error %d.\n", - __FUNCTION__, status); + __func__, status); case -NFS4ERR_EXPIRED: /* kill_proc(fl->fl_pid, SIGLOST, 1); */ case -NFS4ERR_STALE_CLIENTID: @@ -186,7 +186,7 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct */ dfprintk(FILE, "%s: server %s handed out " "a duplicate delegation!\n", - __FUNCTION__, clp->cl_hostname); + __func__, clp->cl_hostname); if (delegation->type <= nfsi->delegation->type) { freeme = delegation; delegation = NULL; diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index f288b3ecab4afad46334d311ac301f7a2e1e1fa4..58d43daec0842ad2be1e16ac8e97e38ea38b474f 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -180,7 +180,7 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page) int error; dfprintk(DIRCACHE, "NFS: %s: reading cookie %Lu into page %lu\n", - __FUNCTION__, (long long)desc->entry->cookie, + __func__, (long long)desc->entry->cookie, page->index); again: @@ -256,7 +256,7 @@ int find_dirent(nfs_readdir_descriptor_t *desc) while((status = dir_decode(desc)) == 0) { dfprintk(DIRCACHE, "NFS: %s: examining cookie %Lu\n", - __FUNCTION__, (unsigned long long)entry->cookie); + __func__, (unsigned long long)entry->cookie); if (entry->prev_cookie == *desc->dir_cookie) break; if (loop_count++ > 200) { @@ -315,7 +315,7 @@ int find_dirent_page(nfs_readdir_descriptor_t *desc) int status; dfprintk(DIRCACHE, "NFS: %s: searching page %ld for target %Lu\n", - __FUNCTION__, desc->page_index, + __func__, desc->page_index, (long long) *desc->dir_cookie); /* If we find the page in the page_cache, we cannot be sure @@ -339,7 +339,7 @@ int find_dirent_page(nfs_readdir_descriptor_t *desc) if (status < 0) dir_page_release(desc); out: - dfprintk(DIRCACHE, "NFS: %s: returns %d\n", __FUNCTION__, status); + dfprintk(DIRCACHE, "NFS: %s: returns %d\n", __func__, status); return status; } @@ -380,7 +380,7 @@ int readdir_search_pagecache(nfs_readdir_descriptor_t *desc) } } - dfprintk(DIRCACHE, "NFS: %s: returns %d\n", __FUNCTION__, res); + dfprintk(DIRCACHE, "NFS: %s: returns %d\n", __func__, res); return res; } @@ -506,7 +506,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent, desc->entry->eof = 0; out: dfprintk(DIRCACHE, "NFS: %s: returns %d\n", - __FUNCTION__, status); + __func__, status); return status; out_release: dir_page_release(desc); @@ -780,7 +780,7 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd) if (is_bad_inode(inode)) { dfprintk(LOOKUPCACHE, "%s: %s/%s has dud inode\n", - __FUNCTION__, dentry->d_parent->d_name.name, + __func__, dentry->d_parent->d_name.name, dentry->d_name.name); goto out_bad; } @@ -808,7 +808,7 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd) unlock_kernel(); dput(parent); dfprintk(LOOKUPCACHE, "NFS: %s(%s/%s) is valid\n", - __FUNCTION__, dentry->d_parent->d_name.name, + __func__, dentry->d_parent->d_name.name, dentry->d_name.name); return 1; out_zap_parent: @@ -827,7 +827,7 @@ out_zap_parent: unlock_kernel(); dput(parent); dfprintk(LOOKUPCACHE, "NFS: %s(%s/%s) is invalid\n", - __FUNCTION__, dentry->d_parent->d_name.name, + __func__, dentry->d_parent->d_name.name, dentry->d_name.name); return 0; } diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 3536b01164f9ca036aa102ee5211d670273f26df..d84a3d8f32af395f8109b58dcdd232fc3d0ddaa3 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -526,7 +526,7 @@ static int do_vfs_lock(struct file *file, struct file_lock *fl) if (res < 0) dprintk(KERN_WARNING "%s: VFS is out of sync with lock manager" " - error %d!\n", - __FUNCTION__, res); + __func__, res); return res; } diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 5cb3345eb6940a7532457f447d7ea77d89b86113..596c5d8e86f4783f78699ae685911958699162d5 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -541,8 +541,7 @@ static void __put_nfs_open_context(struct nfs_open_context *ctx, int wait) } if (ctx->cred != NULL) put_rpccred(ctx->cred); - dput(ctx->path.dentry); - mntput(ctx->path.mnt); + path_put(&ctx->path); kfree(ctx); } @@ -707,6 +706,13 @@ int nfs_attribute_timeout(struct inode *inode) if (nfs_have_delegation(inode, FMODE_READ)) return 0; + /* + * Special case: if the attribute timeout is set to 0, then always + * treat the cache as having expired (unless holding + * a delegation). + */ + if (nfsi->attrtimeo == 0) + return 1; return !time_in_range(jiffies, nfsi->read_cache_jiffies, nfsi->read_cache_jiffies + nfsi->attrtimeo); } @@ -995,7 +1001,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) unsigned long now = jiffies; dfprintk(VFS, "NFS: %s(%s/%ld ct=%d info=0x%x)\n", - __FUNCTION__, inode->i_sb->s_id, inode->i_ino, + __func__, inode->i_sb->s_id, inode->i_ino, atomic_read(&inode->i_count), fattr->valid); if (nfsi->fileid != fattr->fileid) @@ -1119,7 +1125,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) * Big trouble! The inode has become a different object. */ printk(KERN_DEBUG "%s: inode %ld mode changed, %07o to %07o\n", - __FUNCTION__, inode->i_ino, inode->i_mode, fattr->mode); + __func__, inode->i_ino, inode->i_mode, fattr->mode); out_err: /* * No need to worry about unhashing the dentry, as the diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c index af4d0f1e402cdc79696bbb96343ca004a4dd7a43..2f285ef76399f227283146fc15d05a30508f6dbd 100644 --- a/fs/nfs/namespace.c +++ b/fs/nfs/namespace.c @@ -106,7 +106,7 @@ static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd) dprintk("--> nfs_follow_mountpoint()\n"); BUG_ON(IS_ROOT(dentry)); - dprintk("%s: enter\n", __FUNCTION__); + dprintk("%s: enter\n", __func__); dput(nd->path.dentry); nd->path.dentry = dget(dentry); @@ -137,13 +137,12 @@ static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd) goto out_follow; goto out_err; } - mntput(nd->path.mnt); - dput(nd->path.dentry); + path_put(&nd->path); nd->path.mnt = mnt; nd->path.dentry = dget(mnt->mnt_root); schedule_delayed_work(&nfs_automount_task, nfs_mountpoint_expiry_timeout); out: - dprintk("%s: done, returned %d\n", __FUNCTION__, err); + dprintk("%s: done, returned %d\n", __func__, err); dprintk("<-- nfs_follow_mountpoint() = %d\n", err); return ERR_PTR(err); @@ -230,7 +229,7 @@ static struct vfsmount *nfs_do_submount(const struct vfsmount *mnt_parent, dprintk("--> nfs_do_submount()\n"); - dprintk("%s: submounting on %s/%s\n", __FUNCTION__, + dprintk("%s: submounting on %s/%s\n", __func__, dentry->d_parent->d_name.name, dentry->d_name.name); if (page == NULL) @@ -243,7 +242,7 @@ static struct vfsmount *nfs_do_submount(const struct vfsmount *mnt_parent, free_page: free_page((unsigned long)page); out: - dprintk("%s: done\n", __FUNCTION__); + dprintk("%s: done\n", __func__); dprintk("<-- nfs_do_submount() = %p\n", mnt); return mnt; diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index 549dbce714a4bde33c55386ed18357ddf911eab4..c3523ad03ed1b6d860b4782878eeb01ccfd071c3 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c @@ -63,15 +63,15 @@ do_proc_get_root(struct rpc_clnt *client, struct nfs_fh *fhandle, }; int status; - dprintk("%s: call fsinfo\n", __FUNCTION__); + dprintk("%s: call fsinfo\n", __func__); nfs_fattr_init(info->fattr); status = rpc_call_sync(client, &msg, 0); - dprintk("%s: reply fsinfo: %d\n", __FUNCTION__, status); + dprintk("%s: reply fsinfo: %d\n", __func__, status); if (!(info->fattr->valid & NFS_ATTR_FATTR)) { msg.rpc_proc = &nfs3_procedures[NFS3PROC_GETATTR]; msg.rpc_resp = info->fattr; status = rpc_call_sync(client, &msg, 0); - dprintk("%s: reply getattr: %d\n", __FUNCTION__, status); + dprintk("%s: reply getattr: %d\n", __func__, status); } return status; } diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index bd1b9d663fb9545893dc0b95722185c98a0666fa..ea790645fda66385a461c515c5bca63652cdd699 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h @@ -206,7 +206,6 @@ struct rpc_cred *nfs4_get_renew_cred(struct nfs_client *clp); extern struct nfs4_state_owner * nfs4_get_state_owner(struct nfs_server *, struct rpc_cred *); extern void nfs4_put_state_owner(struct nfs4_state_owner *); -extern void nfs4_drop_state_owner(struct nfs4_state_owner *); extern struct nfs4_state * nfs4_get_open_state(struct inode *, struct nfs4_state_owner *); extern void nfs4_put_open_state(struct nfs4_state *); extern void nfs4_close_state(struct path *, struct nfs4_state *, mode_t); diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c index 5f9ba41ed5bfa6b175ef38f1f54bcb4986b26b29..b112857301f724665153259aed547503737554ce 100644 --- a/fs/nfs/nfs4namespace.c +++ b/fs/nfs/nfs4namespace.c @@ -86,7 +86,7 @@ static int nfs4_validate_fspath(const struct vfsmount *mnt_parent, if (strncmp(path, fs_path, strlen(fs_path)) != 0) { dprintk("%s: path %s does not begin with fsroot %s\n", - __FUNCTION__, path, fs_path); + __func__, path, fs_path); return -ENOENT; } @@ -134,7 +134,7 @@ static struct vfsmount *nfs_follow_referral(const struct vfsmount *mnt_parent, if (locations == NULL || locations->nlocations <= 0) goto out; - dprintk("%s: referral at %s/%s\n", __FUNCTION__, + dprintk("%s: referral at %s/%s\n", __func__, dentry->d_parent->d_name.name, dentry->d_name.name); page = (char *) __get_free_page(GFP_USER); @@ -204,7 +204,7 @@ static struct vfsmount *nfs_follow_referral(const struct vfsmount *mnt_parent, out: free_page((unsigned long) page); free_page((unsigned long) page2); - dprintk("%s: done\n", __FUNCTION__); + dprintk("%s: done\n", __func__); return mnt; } @@ -223,7 +223,7 @@ struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentr int err; /* BUG_ON(IS_ROOT(dentry)); */ - dprintk("%s: enter\n", __FUNCTION__); + dprintk("%s: enter\n", __func__); page = alloc_page(GFP_KERNEL); if (page == NULL) @@ -238,7 +238,7 @@ struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentr parent = dget_parent(dentry); dprintk("%s: getting locations for %s/%s\n", - __FUNCTION__, parent->d_name.name, dentry->d_name.name); + __func__, parent->d_name.name, dentry->d_name.name); err = nfs4_proc_fs_locations(parent->d_inode, &dentry->d_name, fs_locations, page); dput(parent); @@ -252,6 +252,6 @@ out_free: __free_page(page); kfree(fs_locations); out: - dprintk("%s: done\n", __FUNCTION__); + dprintk("%s: done\n", __func__); return mnt; } diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index dbc09271af027f9d48b316e5a987c85aca79788e..1293e0acd82b7ab80604a9077277f0f4f97c333d 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -73,7 +73,7 @@ int nfs4_map_errors(int err) { if (err < -1000) { dprintk("%s could not handle NFSv4 error %d\n", - __FUNCTION__, -err); + __func__, -err); return -EIO; } return err; @@ -306,8 +306,7 @@ static void nfs4_opendata_free(struct kref *kref) nfs4_put_open_state(p->state); nfs4_put_state_owner(p->owner); dput(p->dir); - dput(p->path.dentry); - mntput(p->path.mnt); + path_put(&p->path); kfree(p); } @@ -1210,8 +1209,7 @@ static void nfs4_free_closedata(void *data) nfs4_put_open_state(calldata->state); nfs_free_seqid(calldata->arg.seqid); nfs4_put_state_owner(sp); - dput(calldata->path.dentry); - mntput(calldata->path.mnt); + path_put(&calldata->path); kfree(calldata); } @@ -1578,7 +1576,7 @@ static int nfs4_get_referral(struct inode *dir, const struct qstr *name, struct goto out; /* Make sure server returned a different fsid for the referral */ if (nfs_fsid_equal(&NFS_SERVER(dir)->fsid, &locations->fattr.fsid)) { - dprintk("%s: server did not return a different fsid for a referral at %s\n", __FUNCTION__, name->name); + dprintk("%s: server did not return a different fsid for a referral at %s\n", __func__, name->name); status = -EIO; goto out; } @@ -2211,7 +2209,7 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, }; int status; - dprintk("%s: dentry = %s/%s, cookie = %Lu\n", __FUNCTION__, + dprintk("%s: dentry = %s/%s, cookie = %Lu\n", __func__, dentry->d_parent->d_name.name, dentry->d_name.name, (unsigned long long)cookie); @@ -2223,7 +2221,7 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, nfs_invalidate_atime(dir); - dprintk("%s: returns %d\n", __FUNCTION__, status); + dprintk("%s: returns %d\n", __func__, status); return status; } @@ -3342,7 +3340,7 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata) struct nfs4_lockdata *data = calldata; struct nfs4_state *state = data->lsp->ls_state; - dprintk("%s: begin!\n", __FUNCTION__); + dprintk("%s: begin!\n", __func__); if (nfs_wait_on_sequence(data->arg.lock_seqid, task) != 0) return; /* Do we need to do an open_to_lock_owner? */ @@ -3356,14 +3354,14 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata) data->arg.new_lock_owner = 0; data->timestamp = jiffies; rpc_call_start(task); - dprintk("%s: done!, ret = %d\n", __FUNCTION__, data->rpc_status); + dprintk("%s: done!, ret = %d\n", __func__, data->rpc_status); } static void nfs4_lock_done(struct rpc_task *task, void *calldata) { struct nfs4_lockdata *data = calldata; - dprintk("%s: begin!\n", __FUNCTION__); + dprintk("%s: begin!\n", __func__); data->rpc_status = task->tk_status; if (RPC_ASSASSINATED(task)) @@ -3381,14 +3379,14 @@ static void nfs4_lock_done(struct rpc_task *task, void *calldata) renew_lease(NFS_SERVER(data->ctx->path.dentry->d_inode), data->timestamp); } out: - dprintk("%s: done, ret = %d!\n", __FUNCTION__, data->rpc_status); + dprintk("%s: done, ret = %d!\n", __func__, data->rpc_status); } static void nfs4_lock_release(void *calldata) { struct nfs4_lockdata *data = calldata; - dprintk("%s: begin!\n", __FUNCTION__); + dprintk("%s: begin!\n", __func__); nfs_free_seqid(data->arg.open_seqid); if (data->cancelled != 0) { struct rpc_task *task; @@ -3396,13 +3394,13 @@ static void nfs4_lock_release(void *calldata) data->arg.lock_seqid); if (!IS_ERR(task)) rpc_put_task(task); - dprintk("%s: cancelling lock!\n", __FUNCTION__); + dprintk("%s: cancelling lock!\n", __func__); } else nfs_free_seqid(data->arg.lock_seqid); nfs4_put_lock_state(data->lsp); put_nfs_open_context(data->ctx); kfree(data); - dprintk("%s: done!\n", __FUNCTION__); + dprintk("%s: done!\n", __func__); } static const struct rpc_call_ops nfs4_lock_ops = { @@ -3428,7 +3426,7 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f }; int ret; - dprintk("%s: begin!\n", __FUNCTION__); + dprintk("%s: begin!\n", __func__); data = nfs4_alloc_lockdata(fl, nfs_file_open_context(fl->fl_file), fl->fl_u.nfs4_fl.owner); if (data == NULL) @@ -3451,7 +3449,7 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f } else data->cancelled = 1; rpc_put_task(task); - dprintk("%s: done, ret = %d!\n", __FUNCTION__, ret); + dprintk("%s: done, ret = %d!\n", __func__, ret); return ret; } @@ -3527,7 +3525,7 @@ static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock /* Note: we always want to sleep here! */ request->fl_flags = fl_flags | FL_SLEEP; if (do_vfs_lock(request->fl_file, request) < 0) - printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n", __FUNCTION__); + printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n", __func__); out_unlock: up_read(&clp->cl_sem); out: @@ -3665,12 +3663,12 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name, }; int status; - dprintk("%s: start\n", __FUNCTION__); + dprintk("%s: start\n", __func__); nfs_fattr_init(&fs_locations->fattr); fs_locations->server = server; fs_locations->nlocations = 0; status = rpc_call_sync(server->client, &msg, 0); - dprintk("%s: returned status = %d\n", __FUNCTION__, status); + dprintk("%s: returned status = %d\n", __func__, status); return status; } diff --git a/fs/nfs/nfs4renewd.c b/fs/nfs/nfs4renewd.c index 5e2e4af1a0e6c016237448b8e810165da63190d3..3305acbbe2ae3b7f4258baed8f5f807fbf7a1805 100644 --- a/fs/nfs/nfs4renewd.c +++ b/fs/nfs/nfs4renewd.c @@ -66,7 +66,7 @@ nfs4_renew_state(struct work_struct *work) unsigned long last, now; down_read(&clp->cl_sem); - dprintk("%s: start\n", __FUNCTION__); + dprintk("%s: start\n", __func__); /* Are there any active superblocks? */ if (list_empty(&clp->cl_superblocks)) goto out; @@ -92,17 +92,17 @@ nfs4_renew_state(struct work_struct *work) spin_lock(&clp->cl_lock); } else dprintk("%s: failed to call renewd. Reason: lease not expired \n", - __FUNCTION__); + __func__); if (timeout < 5 * HZ) /* safeguard */ timeout = 5 * HZ; dprintk("%s: requeueing work. Lease period = %ld\n", - __FUNCTION__, (timeout + HZ - 1) / HZ); + __func__, (timeout + HZ - 1) / HZ); cancel_delayed_work(&clp->cl_renewd); schedule_delayed_work(&clp->cl_renewd, timeout); spin_unlock(&clp->cl_lock); out: up_read(&clp->cl_sem); - dprintk("%s: done\n", __FUNCTION__); + dprintk("%s: done\n", __func__); } /* Must be called with clp->cl_sem locked for writes */ @@ -117,7 +117,7 @@ nfs4_schedule_state_renewal(struct nfs_client *clp) if (timeout < 5 * HZ) timeout = 5 * HZ; dprintk("%s: requeueing work. Lease period = %ld\n", - __FUNCTION__, (timeout + HZ - 1) / HZ); + __func__, (timeout + HZ - 1) / HZ); cancel_delayed_work(&clp->cl_renewd); schedule_delayed_work(&clp->cl_renewd, timeout); set_bit(NFS_CS_RENEWD, &clp->cl_res_state); diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 46eb624e4f167d0f14189313655971a623f314b5..856a8934f610ef4addd8ea4b51deb5d918dd5e53 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -282,7 +282,7 @@ nfs4_alloc_state_owner(void) return sp; } -void +static void nfs4_drop_state_owner(struct nfs4_state_owner *sp) { if (!RB_EMPTY_NODE(&sp->so_client_node)) { @@ -828,7 +828,7 @@ static int nfs4_reclaim_locks(struct nfs4_state_recovery_ops *ops, struct nfs4_s switch (status) { default: printk(KERN_ERR "%s: unhandled error %d. Zeroing state\n", - __FUNCTION__, status); + __func__, status); case -NFS4ERR_EXPIRED: case -NFS4ERR_NO_GRACE: case -NFS4ERR_RECLAIM_BAD: @@ -869,14 +869,14 @@ static int nfs4_reclaim_open_state(struct nfs4_state_recovery_ops *ops, struct n list_for_each_entry(lock, &state->lock_states, ls_locks) { if (!(lock->ls_flags & NFS_LOCK_INITIALIZED)) printk("%s: Lock reclaim failed!\n", - __FUNCTION__); + __func__); } continue; } switch (status) { default: printk(KERN_ERR "%s: unhandled error %d. Zeroing state\n", - __FUNCTION__, status); + __func__, status); case -ENOENT: case -NFS4ERR_RECLAIM_BAD: case -NFS4ERR_RECLAIM_CONFLICT: diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 5a2d64927b35fd038d9a74edd5390ee071fe0edf..b916297d233461c84a7ce3d8b6a49ea52252dee0 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -1831,7 +1831,7 @@ static int nfs4_xdr_enc_readdir(struct rpc_rqst *req, __be32 *p, const struct nf xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages, args->pgbase, args->count); dprintk("%s: inlined page args = (%u, %p, %u, %u)\n", - __FUNCTION__, replen, args->pages, + __func__, replen, args->pages, args->pgbase, args->count); out: @@ -2192,9 +2192,9 @@ out: p = xdr_inline_decode(xdr, nbytes); \ if (unlikely(!p)) { \ dprintk("nfs: %s: prematurely hit end of receive" \ - " buffer\n", __FUNCTION__); \ + " buffer\n", __func__); \ dprintk("nfs: %s: xdr->p=%p, bytes=%u, xdr->end=%p\n", \ - __FUNCTION__, xdr->p, nbytes, xdr->end); \ + __func__, xdr->p, nbytes, xdr->end); \ return -EIO; \ } \ } while (0) @@ -2306,12 +2306,12 @@ static int decode_attr_type(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t * READ_BUF(4); READ32(*type); if (*type < NF4REG || *type > NF4NAMEDATTR) { - dprintk("%s: bad type %d\n", __FUNCTION__, *type); + dprintk("%s: bad type %d\n", __func__, *type); return -EIO; } bitmap[0] &= ~FATTR4_WORD0_TYPE; } - dprintk("%s: type=0%o\n", __FUNCTION__, nfs_type2fmt[*type].nfs2type); + dprintk("%s: type=0%o\n", __func__, nfs_type2fmt[*type].nfs2type); return 0; } @@ -2327,7 +2327,7 @@ static int decode_attr_change(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t READ64(*change); bitmap[0] &= ~FATTR4_WORD0_CHANGE; } - dprintk("%s: change attribute=%Lu\n", __FUNCTION__, + dprintk("%s: change attribute=%Lu\n", __func__, (unsigned long long)*change); return 0; } @@ -2344,7 +2344,7 @@ static int decode_attr_size(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t * READ64(*size); bitmap[0] &= ~FATTR4_WORD0_SIZE; } - dprintk("%s: file size=%Lu\n", __FUNCTION__, (unsigned long long)*size); + dprintk("%s: file size=%Lu\n", __func__, (unsigned long long)*size); return 0; } @@ -2360,7 +2360,7 @@ static int decode_attr_link_support(struct xdr_stream *xdr, uint32_t *bitmap, ui READ32(*res); bitmap[0] &= ~FATTR4_WORD0_LINK_SUPPORT; } - dprintk("%s: link support=%s\n", __FUNCTION__, *res == 0 ? "false" : "true"); + dprintk("%s: link support=%s\n", __func__, *res == 0 ? "false" : "true"); return 0; } @@ -2376,7 +2376,7 @@ static int decode_attr_symlink_support(struct xdr_stream *xdr, uint32_t *bitmap, READ32(*res); bitmap[0] &= ~FATTR4_WORD0_SYMLINK_SUPPORT; } - dprintk("%s: symlink support=%s\n", __FUNCTION__, *res == 0 ? "false" : "true"); + dprintk("%s: symlink support=%s\n", __func__, *res == 0 ? "false" : "true"); return 0; } @@ -2394,7 +2394,7 @@ static int decode_attr_fsid(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs READ64(fsid->minor); bitmap[0] &= ~FATTR4_WORD0_FSID; } - dprintk("%s: fsid=(0x%Lx/0x%Lx)\n", __FUNCTION__, + dprintk("%s: fsid=(0x%Lx/0x%Lx)\n", __func__, (unsigned long long)fsid->major, (unsigned long long)fsid->minor); return 0; @@ -2412,7 +2412,7 @@ static int decode_attr_lease_time(struct xdr_stream *xdr, uint32_t *bitmap, uint READ32(*res); bitmap[0] &= ~FATTR4_WORD0_LEASE_TIME; } - dprintk("%s: file size=%u\n", __FUNCTION__, (unsigned int)*res); + dprintk("%s: file size=%u\n", __func__, (unsigned int)*res); return 0; } @@ -2428,7 +2428,7 @@ static int decode_attr_aclsupport(struct xdr_stream *xdr, uint32_t *bitmap, uint READ32(*res); bitmap[0] &= ~FATTR4_WORD0_ACLSUPPORT; } - dprintk("%s: ACLs supported=%u\n", __FUNCTION__, (unsigned int)*res); + dprintk("%s: ACLs supported=%u\n", __func__, (unsigned int)*res); return 0; } @@ -2444,7 +2444,7 @@ static int decode_attr_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t READ64(*fileid); bitmap[0] &= ~FATTR4_WORD0_FILEID; } - dprintk("%s: fileid=%Lu\n", __FUNCTION__, (unsigned long long)*fileid); + dprintk("%s: fileid=%Lu\n", __func__, (unsigned long long)*fileid); return 0; } @@ -2460,7 +2460,7 @@ static int decode_attr_mounted_on_fileid(struct xdr_stream *xdr, uint32_t *bitma READ64(*fileid); bitmap[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID; } - dprintk("%s: fileid=%Lu\n", __FUNCTION__, (unsigned long long)*fileid); + dprintk("%s: fileid=%Lu\n", __func__, (unsigned long long)*fileid); return 0; } @@ -2477,7 +2477,7 @@ static int decode_attr_files_avail(struct xdr_stream *xdr, uint32_t *bitmap, uin READ64(*res); bitmap[0] &= ~FATTR4_WORD0_FILES_AVAIL; } - dprintk("%s: files avail=%Lu\n", __FUNCTION__, (unsigned long long)*res); + dprintk("%s: files avail=%Lu\n", __func__, (unsigned long long)*res); return status; } @@ -2494,7 +2494,7 @@ static int decode_attr_files_free(struct xdr_stream *xdr, uint32_t *bitmap, uint READ64(*res); bitmap[0] &= ~FATTR4_WORD0_FILES_FREE; } - dprintk("%s: files free=%Lu\n", __FUNCTION__, (unsigned long long)*res); + dprintk("%s: files free=%Lu\n", __func__, (unsigned long long)*res); return status; } @@ -2511,7 +2511,7 @@ static int decode_attr_files_total(struct xdr_stream *xdr, uint32_t *bitmap, uin READ64(*res); bitmap[0] &= ~FATTR4_WORD0_FILES_TOTAL; } - dprintk("%s: files total=%Lu\n", __FUNCTION__, (unsigned long long)*res); + dprintk("%s: files total=%Lu\n", __func__, (unsigned long long)*res); return status; } @@ -2569,7 +2569,7 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st status = 0; if (unlikely(!(bitmap[0] & FATTR4_WORD0_FS_LOCATIONS))) goto out; - dprintk("%s: fsroot ", __FUNCTION__); + dprintk("%s: fsroot ", __func__); status = decode_pathname(xdr, &res->fs_path); if (unlikely(status != 0)) goto out; @@ -2586,7 +2586,7 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st READ32(m); loc->nservers = 0; - dprintk("%s: servers ", __FUNCTION__); + dprintk("%s: servers ", __func__); while (loc->nservers < m) { struct nfs4_string *server = &loc->servers[loc->nservers]; status = decode_opaque_inline(xdr, &server->len, &server->data); @@ -2599,7 +2599,7 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st unsigned int i; dprintk("%s: using first %u of %u servers " "returned for location %u\n", - __FUNCTION__, + __func__, NFS4_FS_LOCATION_MAXSERVERS, m, res->nlocations); for (i = loc->nservers; i < m; i++) { @@ -2618,7 +2618,7 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st res->nlocations++; } out: - dprintk("%s: fs_locations done, error = %d\n", __FUNCTION__, status); + dprintk("%s: fs_locations done, error = %d\n", __func__, status); return status; out_eio: status = -EIO; @@ -2638,7 +2638,7 @@ static int decode_attr_maxfilesize(struct xdr_stream *xdr, uint32_t *bitmap, uin READ64(*res); bitmap[0] &= ~FATTR4_WORD0_MAXFILESIZE; } - dprintk("%s: maxfilesize=%Lu\n", __FUNCTION__, (unsigned long long)*res); + dprintk("%s: maxfilesize=%Lu\n", __func__, (unsigned long long)*res); return status; } @@ -2655,7 +2655,7 @@ static int decode_attr_maxlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_ READ32(*maxlink); bitmap[0] &= ~FATTR4_WORD0_MAXLINK; } - dprintk("%s: maxlink=%u\n", __FUNCTION__, *maxlink); + dprintk("%s: maxlink=%u\n", __func__, *maxlink); return status; } @@ -2672,7 +2672,7 @@ static int decode_attr_maxname(struct xdr_stream *xdr, uint32_t *bitmap, uint32_ READ32(*maxname); bitmap[0] &= ~FATTR4_WORD0_MAXNAME; } - dprintk("%s: maxname=%u\n", __FUNCTION__, *maxname); + dprintk("%s: maxname=%u\n", __func__, *maxname); return status; } @@ -2693,7 +2693,7 @@ static int decode_attr_maxread(struct xdr_stream *xdr, uint32_t *bitmap, uint32_ *res = (uint32_t)maxread; bitmap[0] &= ~FATTR4_WORD0_MAXREAD; } - dprintk("%s: maxread=%lu\n", __FUNCTION__, (unsigned long)*res); + dprintk("%s: maxread=%lu\n", __func__, (unsigned long)*res); return status; } @@ -2714,7 +2714,7 @@ static int decode_attr_maxwrite(struct xdr_stream *xdr, uint32_t *bitmap, uint32 *res = (uint32_t)maxwrite; bitmap[0] &= ~FATTR4_WORD0_MAXWRITE; } - dprintk("%s: maxwrite=%lu\n", __FUNCTION__, (unsigned long)*res); + dprintk("%s: maxwrite=%lu\n", __func__, (unsigned long)*res); return status; } @@ -2731,7 +2731,7 @@ static int decode_attr_mode(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t * *mode &= ~S_IFMT; bitmap[1] &= ~FATTR4_WORD1_MODE; } - dprintk("%s: file mode=0%o\n", __FUNCTION__, (unsigned int)*mode); + dprintk("%s: file mode=0%o\n", __func__, (unsigned int)*mode); return 0; } @@ -2747,7 +2747,7 @@ static int decode_attr_nlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t READ32(*nlink); bitmap[1] &= ~FATTR4_WORD1_NUMLINKS; } - dprintk("%s: nlink=%u\n", __FUNCTION__, (unsigned int)*nlink); + dprintk("%s: nlink=%u\n", __func__, (unsigned int)*nlink); return 0; } @@ -2766,13 +2766,13 @@ static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, struct nf if (len < XDR_MAX_NETOBJ) { if (nfs_map_name_to_uid(clp, (char *)p, len, uid) != 0) dprintk("%s: nfs_map_name_to_uid failed!\n", - __FUNCTION__); + __func__); } else dprintk("%s: name too long (%u)!\n", - __FUNCTION__, len); + __func__, len); bitmap[1] &= ~FATTR4_WORD1_OWNER; } - dprintk("%s: uid=%d\n", __FUNCTION__, (int)*uid); + dprintk("%s: uid=%d\n", __func__, (int)*uid); return 0; } @@ -2791,13 +2791,13 @@ static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, struct nf if (len < XDR_MAX_NETOBJ) { if (nfs_map_group_to_gid(clp, (char *)p, len, gid) != 0) dprintk("%s: nfs_map_group_to_gid failed!\n", - __FUNCTION__); + __func__); } else dprintk("%s: name too long (%u)!\n", - __FUNCTION__, len); + __func__, len); bitmap[1] &= ~FATTR4_WORD1_OWNER_GROUP; } - dprintk("%s: gid=%d\n", __FUNCTION__, (int)*gid); + dprintk("%s: gid=%d\n", __func__, (int)*gid); return 0; } @@ -2820,7 +2820,7 @@ static int decode_attr_rdev(struct xdr_stream *xdr, uint32_t *bitmap, dev_t *rde *rdev = tmp; bitmap[1] &= ~ FATTR4_WORD1_RAWDEV; } - dprintk("%s: rdev=(0x%x:0x%x)\n", __FUNCTION__, major, minor); + dprintk("%s: rdev=(0x%x:0x%x)\n", __func__, major, minor); return 0; } @@ -2837,7 +2837,7 @@ static int decode_attr_space_avail(struct xdr_stream *xdr, uint32_t *bitmap, uin READ64(*res); bitmap[1] &= ~FATTR4_WORD1_SPACE_AVAIL; } - dprintk("%s: space avail=%Lu\n", __FUNCTION__, (unsigned long long)*res); + dprintk("%s: space avail=%Lu\n", __func__, (unsigned long long)*res); return status; } @@ -2854,7 +2854,7 @@ static int decode_attr_space_free(struct xdr_stream *xdr, uint32_t *bitmap, uint READ64(*res); bitmap[1] &= ~FATTR4_WORD1_SPACE_FREE; } - dprintk("%s: space free=%Lu\n", __FUNCTION__, (unsigned long long)*res); + dprintk("%s: space free=%Lu\n", __func__, (unsigned long long)*res); return status; } @@ -2871,7 +2871,7 @@ static int decode_attr_space_total(struct xdr_stream *xdr, uint32_t *bitmap, uin READ64(*res); bitmap[1] &= ~FATTR4_WORD1_SPACE_TOTAL; } - dprintk("%s: space total=%Lu\n", __FUNCTION__, (unsigned long long)*res); + dprintk("%s: space total=%Lu\n", __func__, (unsigned long long)*res); return status; } @@ -2887,7 +2887,7 @@ static int decode_attr_space_used(struct xdr_stream *xdr, uint32_t *bitmap, uint READ64(*used); bitmap[1] &= ~FATTR4_WORD1_SPACE_USED; } - dprintk("%s: space used=%Lu\n", __FUNCTION__, + dprintk("%s: space used=%Lu\n", __func__, (unsigned long long)*used); return 0; } @@ -2918,7 +2918,7 @@ static int decode_attr_time_access(struct xdr_stream *xdr, uint32_t *bitmap, str status = decode_attr_time(xdr, time); bitmap[1] &= ~FATTR4_WORD1_TIME_ACCESS; } - dprintk("%s: atime=%ld\n", __FUNCTION__, (long)time->tv_sec); + dprintk("%s: atime=%ld\n", __func__, (long)time->tv_sec); return status; } @@ -2934,7 +2934,7 @@ static int decode_attr_time_metadata(struct xdr_stream *xdr, uint32_t *bitmap, s status = decode_attr_time(xdr, time); bitmap[1] &= ~FATTR4_WORD1_TIME_METADATA; } - dprintk("%s: ctime=%ld\n", __FUNCTION__, (long)time->tv_sec); + dprintk("%s: ctime=%ld\n", __func__, (long)time->tv_sec); return status; } @@ -2950,7 +2950,7 @@ static int decode_attr_time_modify(struct xdr_stream *xdr, uint32_t *bitmap, str status = decode_attr_time(xdr, time); bitmap[1] &= ~FATTR4_WORD1_TIME_MODIFY; } - dprintk("%s: mtime=%ld\n", __FUNCTION__, (long)time->tv_sec); + dprintk("%s: mtime=%ld\n", __func__, (long)time->tv_sec); return status; } @@ -2962,7 +2962,7 @@ static int verify_attr_len(struct xdr_stream *xdr, __be32 *savep, uint32_t attrl if (unlikely(attrwords != nwords)) { dprintk("%s: server returned incorrect attribute length: " "%u %c %u\n", - __FUNCTION__, + __func__, attrwords << 2, (attrwords < nwords) ? '<' : '>', nwords << 2); @@ -3067,7 +3067,7 @@ static int decode_server_caps(struct xdr_stream *xdr, struct nfs4_server_caps_re goto xdr_error; status = verify_attr_len(xdr, savep, attrlen); xdr_error: - dprintk("%s: xdr returned %d!\n", __FUNCTION__, -status); + dprintk("%s: xdr returned %d!\n", __func__, -status); return status; } @@ -3100,7 +3100,7 @@ static int decode_statfs(struct xdr_stream *xdr, struct nfs_fsstat *fsstat) status = verify_attr_len(xdr, savep, attrlen); xdr_error: - dprintk("%s: xdr returned %d!\n", __FUNCTION__, -status); + dprintk("%s: xdr returned %d!\n", __func__, -status); return status; } @@ -3125,7 +3125,7 @@ static int decode_pathconf(struct xdr_stream *xdr, struct nfs_pathconf *pathconf status = verify_attr_len(xdr, savep, attrlen); xdr_error: - dprintk("%s: xdr returned %d!\n", __FUNCTION__, -status); + dprintk("%s: xdr returned %d!\n", __func__, -status); return status; } @@ -3193,7 +3193,7 @@ static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr, cons if ((status = verify_attr_len(xdr, savep, attrlen)) == 0) fattr->valid = NFS_ATTR_FATTR | NFS_ATTR_FATTR_V3 | NFS_ATTR_FATTR_V4; xdr_error: - dprintk("%s: xdr returned %d\n", __FUNCTION__, -status); + dprintk("%s: xdr returned %d\n", __func__, -status); return status; } @@ -3226,7 +3226,7 @@ static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo) status = verify_attr_len(xdr, savep, attrlen); xdr_error: - dprintk("%s: xdr returned %d!\n", __FUNCTION__, -status); + dprintk("%s: xdr returned %d!\n", __func__, -status); return status; } @@ -3418,7 +3418,7 @@ static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res) return decode_delegation(xdr, res); xdr_error: - dprintk("%s: Bitmap too large! Length = %u\n", __FUNCTION__, bmlen); + dprintk("%s: Bitmap too large! Length = %u\n", __func__, bmlen); return -EIO; } @@ -3575,7 +3575,7 @@ short_pkt: * the call was successful, but incomplete. The caller can retry the * readdir starting at the last cookie. */ - dprintk("%s: short packet at entry %d\n", __FUNCTION__, nr); + dprintk("%s: short packet at entry %d\n", __func__, nr); entry[0] = entry[1] = 0; if (nr) goto out; diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c index 5ccf7faee19cd17cc63a3506f91990e6c8b5b17f..03599bfe81cf878fb0a65f233b80aeb184146bb4 100644 --- a/fs/nfs/proc.c +++ b/fs/nfs/proc.c @@ -63,17 +63,17 @@ nfs_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle, }; int status; - dprintk("%s: call getattr\n", __FUNCTION__); + dprintk("%s: call getattr\n", __func__); nfs_fattr_init(fattr); status = rpc_call_sync(server->nfs_client->cl_rpcclient, &msg, 0); - dprintk("%s: reply getattr: %d\n", __FUNCTION__, status); + dprintk("%s: reply getattr: %d\n", __func__, status); if (status) return status; - dprintk("%s: call statfs\n", __FUNCTION__); + dprintk("%s: call statfs\n", __func__); msg.rpc_proc = &nfs_procedures[NFSPROC_STATFS]; msg.rpc_resp = &fsinfo; status = rpc_call_sync(server->nfs_client->cl_rpcclient, &msg, 0); - dprintk("%s: reply statfs: %d\n", __FUNCTION__, status); + dprintk("%s: reply statfs: %d\n", __func__, status); if (status) return status; info->rtmax = NFS_MAXDATA; diff --git a/fs/nfs/read.c b/fs/nfs/read.c index 16f57e0af999a51dc166b181dd01c3e8ef72e79d..40d17987d0e847a87fa4596a9a4c9f39a464288e 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c @@ -329,7 +329,7 @@ int nfs_readpage_result(struct rpc_task *task, struct nfs_read_data *data) { int status; - dprintk("NFS: %s: %5u, (status %d)\n", __FUNCTION__, task->tk_pid, + dprintk("NFS: %s: %5u, (status %d)\n", __func__, task->tk_pid, task->tk_status); status = NFS_PROTO(data->inode)->read_done(task, data); diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 7226a506f3ca55ea587ece913ec8a64982ff64be..2a4a024a4e7bf09c53575b6ef74398c67779d329 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -405,7 +405,7 @@ static int nfs_statfs(struct dentry *dentry, struct kstatfs *buf) return 0; out_err: - dprintk("%s: statfs error = %d\n", __FUNCTION__, -error); + dprintk("%s: statfs error = %d\n", __func__, -error); unlock_kernel(); return error; } @@ -2015,6 +2015,10 @@ static int nfs4_get_sb(struct file_system_type *fs_type, goto error_splat_super; } + error = security_sb_set_mnt_opts(s, &data.lsm_opts); + if (error) + goto error_splat_root; + s->s_flags |= MS_ACTIVE; mnt->mnt_sb = s; mnt->mnt_root = mntroot; @@ -2031,6 +2035,8 @@ out_free: nfs_free_server(server); goto out; +error_splat_root: + dput(mntroot); error_splat_super: up_write(&s->s_umount); deactivate_super(s); @@ -2114,6 +2120,8 @@ static int nfs4_xdev_get_sb(struct file_system_type *fs_type, int flags, mnt->mnt_sb = s; mnt->mnt_root = mntroot; + security_sb_clone_mnt_opts(data->sb, s); + dprintk("<-- nfs4_xdev_get_sb() = 0\n"); return 0; @@ -2197,6 +2205,8 @@ static int nfs4_referral_get_sb(struct file_system_type *fs_type, int flags, mnt->mnt_sb = s; mnt->mnt_root = mntroot; + security_sb_clone_mnt_opts(data->sb, s); + dprintk("<-- nfs4_referral_get_sb() = 0\n"); return 0; diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 1ade11d1ba078c922e8dc24b0d2d98eec022d09f..6d8ace3e3259d9f643fbf1e92fc3c4f1c4dc40f0 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -415,7 +415,7 @@ nfs_dirty_request(struct nfs_page *req) if (page == NULL || test_bit(PG_NEED_COMMIT, &req->wb_flags)) return 0; - return !PageWriteback(req->wb_page); + return !PageWriteback(page); } #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) diff --git a/fs/pipe.c b/fs/pipe.c index 3499f9ff6316ba7189475ec11021bab74dcf083a..ec228bc9f8824128ea99c5cb24abc743063e00bb 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -1086,8 +1087,11 @@ asmlinkage long __weak sys_pipe(int __user *fildes) error = do_pipe(fd); if (!error) { - if (copy_to_user(fildes, fd, sizeof(fd))) + if (copy_to_user(fildes, fd, sizeof(fd))) { + sys_close(fd[0]); + sys_close(fd[1]); error = -EFAULT; + } } return error; } diff --git a/fs/proc/array.c b/fs/proc/array.c index dca997a93bff32295fd3af13737d17cd24da9d7b..9e3b8c33c24b65c496f815658895dd4d2afd9c00 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -298,6 +298,7 @@ static inline void task_cap(struct seq_file *m, struct task_struct *p) render_cap_t(m, "CapInh:\t", &p->cap_inheritable); render_cap_t(m, "CapPrm:\t", &p->cap_permitted); render_cap_t(m, "CapEff:\t", &p->cap_effective); + render_cap_t(m, "CapBnd:\t", &p->cap_bset); } static inline void task_context_switch_counts(struct seq_file *m, diff --git a/fs/proc/base.c b/fs/proc/base.c index 808cbdc193d309572c68b03d1b81b318511a4efc..c447e0743a3c95e231bc0e9f98a33d474c2e86bb 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -2441,7 +2441,7 @@ static const struct pid_entry tgid_base_stuff[] = { REG("oom_adj", S_IRUGO|S_IWUSR, oom_adjust), #ifdef CONFIG_AUDITSYSCALL REG("loginuid", S_IWUSR|S_IRUGO, loginuid), - REG("sessionid", S_IRUSR, sessionid), + REG("sessionid", S_IRUGO, sessionid), #endif #ifdef CONFIG_FAULT_INJECTION REG("make-it-fail", S_IRUGO|S_IWUSR, fault_inject), diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index e2b8e769f510d676997698b8fd28ef4346478d2c..88717c0f941b0b770617bf34e7f364e2e9923e04 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -5,11 +5,9 @@ #include #include #include -#include #include #include #include -#include #include #include diff --git a/fs/splice.c b/fs/splice.c index 633f58ebfb72a2ad7b132adb7492f7c268daecca..78150038b58422155b2a89e47e8a228967f0ca3d 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -811,24 +811,19 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out, { struct address_space *mapping = out->f_mapping; struct inode *inode = mapping->host; - int killsuid, killpriv; + struct splice_desc sd = { + .total_len = len, + .flags = flags, + .pos = *ppos, + .u.file = out, + }; ssize_t ret; - int err = 0; - - killpriv = security_inode_need_killpriv(out->f_path.dentry); - killsuid = should_remove_suid(out->f_path.dentry); - if (unlikely(killsuid || killpriv)) { - mutex_lock(&inode->i_mutex); - if (killpriv) - err = security_inode_killpriv(out->f_path.dentry); - if (!err && killsuid) - err = __remove_suid(out->f_path.dentry, killsuid); - mutex_unlock(&inode->i_mutex); - if (err) - return err; - } - ret = splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_file); + inode_double_lock(inode, pipe->inode); + ret = remove_suid(out->f_path.dentry); + if (likely(!ret)) + ret = __splice_from_pipe(pipe, &sd, pipe_to_file); + inode_double_unlock(inode, pipe->inode); if (ret > 0) { unsigned long nr_pages; @@ -840,6 +835,8 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out, * sync it. */ if (unlikely((out->f_flags & O_SYNC) || IS_SYNC(inode))) { + int err; + mutex_lock(&inode->i_mutex); err = generic_osync_inode(inode, mapping, OSYNC_METADATA|OSYNC_DATA); @@ -1075,7 +1072,7 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, ret = splice_direct_to_actor(in, &sd, direct_splice_actor); if (ret > 0) - *ppos = sd.pos; + *ppos += ret; return ret; } diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 2b34c8ca6c83ed2e6aa01f955664ffccf7eb1ec0..d3231947db19edc3e4e592d3feadd7ab95e2c08a 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c @@ -32,6 +32,7 @@ #include #include #include +#include static inline int udf_match(int len1, const char *name1, int len2, const char *name2) @@ -158,6 +159,8 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir, sector_t offset; struct extent_position epos = {}; struct udf_inode_info *dinfo = UDF_I(dir); + int isdotdot = dentry->d_name.len == 2 && + dentry->d_name.name[0] == '.' && dentry->d_name.name[1] == '.'; size = udf_ext0_offset(dir) + dir->i_size; f_pos = udf_ext0_offset(dir); @@ -225,6 +228,12 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir, continue; } + if ((cfi->fileCharacteristics & FID_FILE_CHAR_PARENT) && + isdotdot) { + brelse(epos.bh); + return fi; + } + if (!lfi) continue; @@ -286,9 +295,8 @@ static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry, } } unlock_kernel(); - d_add(dentry, inode); - return NULL; + return d_splice_alias(inode, dentry); } static struct fileIdentDesc *udf_add_entry(struct inode *dir, @@ -307,7 +315,7 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir, uint16_t liu; int block; kernel_lb_addr eloc; - uint32_t elen; + uint32_t elen = 0; sector_t offset; struct extent_position epos = {}; struct udf_inode_info *dinfo; @@ -398,7 +406,8 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir, } add: - if (dinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { + /* Is there any extent whose size we need to round up? */ + if (dinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB && elen) { elen = (elen + sb->s_blocksize - 1) & ~(sb->s_blocksize - 1); if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) epos.offset -= sizeof(short_ad); @@ -1232,6 +1241,134 @@ end_rename: return retval; } +static struct dentry *udf_get_parent(struct dentry *child) +{ + struct dentry *parent; + struct inode *inode = NULL; + struct dentry dotdot; + struct fileIdentDesc cfi; + struct udf_fileident_bh fibh; + + dotdot.d_name.name = ".."; + dotdot.d_name.len = 2; + + lock_kernel(); + if (!udf_find_entry(child->d_inode, &dotdot, &fibh, &cfi)) + goto out_unlock; + + if (fibh.sbh != fibh.ebh) + brelse(fibh.ebh); + brelse(fibh.sbh); + + inode = udf_iget(child->d_inode->i_sb, + lelb_to_cpu(cfi.icb.extLocation)); + if (!inode) + goto out_unlock; + unlock_kernel(); + + parent = d_alloc_anon(inode); + if (!parent) { + iput(inode); + parent = ERR_PTR(-ENOMEM); + } + + return parent; +out_unlock: + unlock_kernel(); + return ERR_PTR(-EACCES); +} + + +static struct dentry *udf_nfs_get_inode(struct super_block *sb, u32 block, + u16 partref, __u32 generation) +{ + struct inode *inode; + struct dentry *result; + kernel_lb_addr loc; + + if (block == 0) + return ERR_PTR(-ESTALE); + + loc.logicalBlockNum = block; + loc.partitionReferenceNum = partref; + inode = udf_iget(sb, loc); + + if (inode == NULL) + return ERR_PTR(-ENOMEM); + + if (generation && inode->i_generation != generation) { + iput(inode); + return ERR_PTR(-ESTALE); + } + result = d_alloc_anon(inode); + if (!result) { + iput(inode); + return ERR_PTR(-ENOMEM); + } + return result; +} + +static struct dentry *udf_fh_to_dentry(struct super_block *sb, + struct fid *fid, int fh_len, int fh_type) +{ + if ((fh_len != 3 && fh_len != 5) || + (fh_type != FILEID_UDF_WITH_PARENT && + fh_type != FILEID_UDF_WITHOUT_PARENT)) + return NULL; + + return udf_nfs_get_inode(sb, fid->udf.block, fid->udf.partref, + fid->udf.generation); +} + +static struct dentry *udf_fh_to_parent(struct super_block *sb, + struct fid *fid, int fh_len, int fh_type) +{ + if (fh_len != 5 || fh_type != FILEID_UDF_WITH_PARENT) + return NULL; + + return udf_nfs_get_inode(sb, fid->udf.parent_block, + fid->udf.parent_partref, + fid->udf.parent_generation); +} +static int udf_encode_fh(struct dentry *de, __u32 *fh, int *lenp, + int connectable) +{ + int len = *lenp; + struct inode *inode = de->d_inode; + kernel_lb_addr location = UDF_I(inode)->i_location; + struct fid *fid = (struct fid *)fh; + int type = FILEID_UDF_WITHOUT_PARENT; + + if (len < 3 || (connectable && len < 5)) + return 255; + + *lenp = 3; + fid->udf.block = location.logicalBlockNum; + fid->udf.partref = location.partitionReferenceNum; + fid->udf.generation = inode->i_generation; + + if (connectable && !S_ISDIR(inode->i_mode)) { + spin_lock(&de->d_lock); + inode = de->d_parent->d_inode; + location = UDF_I(inode)->i_location; + fid->udf.parent_block = location.logicalBlockNum; + fid->udf.parent_partref = location.partitionReferenceNum; + fid->udf.parent_generation = inode->i_generation; + spin_unlock(&de->d_lock); + *lenp = 5; + type = FILEID_UDF_WITH_PARENT; + } + + return type; +} + +const struct export_operations udf_export_ops = { + .encode_fh = udf_encode_fh, + .fh_to_dentry = udf_fh_to_dentry, + .fh_to_parent = udf_fh_to_parent, + .get_parent = udf_get_parent, +}; + const struct inode_operations udf_dir_inode_operations = { .lookup = udf_lookup, .create = udf_create, diff --git a/fs/udf/partition.c b/fs/udf/partition.c index 63610f026ae15046d701d3ab45ab93a04ff51371..96dfd207c3d6339f5a07377a217e5f15c01140e2 100644 --- a/fs/udf/partition.c +++ b/fs/udf/partition.c @@ -27,8 +27,8 @@ #include #include -inline uint32_t udf_get_pblock(struct super_block *sb, uint32_t block, - uint16_t partition, uint32_t offset) +uint32_t udf_get_pblock(struct super_block *sb, uint32_t block, + uint16_t partition, uint32_t offset) { struct udf_sb_info *sbi = UDF_SB(sb); struct udf_part_map *map; diff --git a/fs/udf/super.c b/fs/udf/super.c index 9fb18a340fc1efa95fb0acd15d50c89c90652875..7a5f69be6ac2127de968661bd6d5e134712940b3 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -1933,6 +1933,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) /* Fill in the rest of the superblock */ sb->s_op = &udf_sb_ops; + sb->s_export_op = &udf_export_ops; sb->dq_op = NULL; sb->s_dirt = 0; sb->s_magic = UDF_SUPER_MAGIC; diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h index f3f45d029277a4f1b038c6baf38ca2cce8703739..8fa9c2d70911701fb6aa0abded2bc86ed439d749 100644 --- a/fs/udf/udfdecl.h +++ b/fs/udf/udfdecl.h @@ -73,6 +73,7 @@ struct task_struct; struct buffer_head; struct super_block; +extern const struct export_operations udf_export_ops; extern const struct inode_operations udf_dir_inode_operations; extern const struct file_operations udf_dir_operations; extern const struct inode_operations udf_file_inode_operations; diff --git a/fs/ufs/ufs.h b/fs/ufs/ufs.h index 244a1aaa940eea43a82619ff8bde98fa27b4caed..11c035168ea6e3c1201ee8f95ed1693c72e566e2 100644 --- a/fs/ufs/ufs.h +++ b/fs/ufs/ufs.h @@ -107,7 +107,6 @@ extern struct inode * ufs_new_inode (struct inode *, int); /* inode.c */ extern struct inode *ufs_iget(struct super_block *, unsigned long); -extern void ufs_put_inode (struct inode *); extern int ufs_write_inode (struct inode *, int); extern int ufs_sync_inode (struct inode *); extern void ufs_delete_inode (struct inode *); diff --git a/include/asm-alpha/barrier.h b/include/asm-alpha/barrier.h index 384dc08d6f53d26974b87511e498719a1fe84c4f..ac78eba909bce225243a9ddb979c3b5321d3da17 100644 --- a/include/asm-alpha/barrier.h +++ b/include/asm-alpha/barrier.h @@ -24,7 +24,7 @@ __asm__ __volatile__("mb": : :"memory") #define smp_mb() barrier() #define smp_rmb() barrier() #define smp_wmb() barrier() -#define smp_read_barrier_depends() barrier() +#define smp_read_barrier_depends() do { } while (0) #endif #define set_mb(var, value) \ diff --git a/include/asm-alpha/param.h b/include/asm-alpha/param.h index 0982f1d39499fbe337b440cc995913e2fbbb792d..e691ecfedb2ce93b7544596487f8abf9f9fff652 100644 --- a/include/asm-alpha/param.h +++ b/include/asm-alpha/param.h @@ -5,8 +5,12 @@ hardware ignores reprogramming. We also need userland buy-in to the change in HZ, since this is visible in the wait4 resources etc. */ +#ifdef __KERNEL__ #define HZ CONFIG_HZ #define USER_HZ HZ +#else +#define HZ 1024 +#endif #define EXEC_PAGESIZE 8192 diff --git a/include/asm-alpha/pgtable.h b/include/asm-alpha/pgtable.h index 05ce5fba43e32ef37143836f1961a5300667f30c..3f0c59f6d8aa07dc5b68f96d1e928ac7f5b222d5 100644 --- a/include/asm-alpha/pgtable.h +++ b/include/asm-alpha/pgtable.h @@ -287,17 +287,34 @@ extern inline pte_t pte_mkspecial(pte_t pte) { return pte; } #define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1)) #define pgd_offset(mm, address) ((mm)->pgd+pgd_index(address)) +/* + * The smp_read_barrier_depends() in the following functions are required to + * order the load of *dir (the pointer in the top level page table) with any + * subsequent load of the returned pmd_t *ret (ret is data dependent on *dir). + * + * If this ordering is not enforced, the CPU might load an older value of + * *ret, which may be uninitialized data. See mm/memory.c:__pte_alloc for + * more details. + * + * Note that we never change the mm->pgd pointer after the task is running, so + * pgd_offset does not require such a barrier. + */ + /* Find an entry in the second-level page table.. */ extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address) { - return (pmd_t *) pgd_page_vaddr(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PAGE - 1)); + pmd_t *ret = (pmd_t *) pgd_page_vaddr(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PAGE - 1)); + smp_read_barrier_depends(); /* see above */ + return ret; } /* Find an entry in the third-level page table.. */ extern inline pte_t * pte_offset_kernel(pmd_t * dir, unsigned long address) { - return (pte_t *) pmd_page_vaddr(*dir) + pte_t *ret = (pte_t *) pmd_page_vaddr(*dir) + ((address >> PAGE_SHIFT) & (PTRS_PER_PAGE - 1)); + smp_read_barrier_depends(); /* see above */ + return ret; } #define pte_offset_map(dir,addr) pte_offset_kernel((dir),(addr)) diff --git a/include/asm-arm/arch-omap/common.h b/include/asm-arm/arch-omap/common.h index 224e009e529633a07042429c4f51cf93c5781799..36a3b62d4d8d4da2a982a7e3e7961a4d08627615 100644 --- a/include/asm-arm/arch-omap/common.h +++ b/include/asm-arm/arch-omap/common.h @@ -47,4 +47,8 @@ static inline int omap_register_i2c_bus(int bus_id, u32 clkrate, } #endif +void omap2_set_globals_242x(void); +void omap2_set_globals_243x(void); +void omap2_set_globals_343x(void); + #endif /* __ARCH_ARM_MACH_OMAP_COMMON_H */ diff --git a/include/asm-arm/arch-omap/control.h b/include/asm-arm/arch-omap/control.h index 9944bb5d53300794dd5857275ee0fad479878c7a..59c0686f8be7fa572c091eabc852df1a4f11a057 100644 --- a/include/asm-arm/arch-omap/control.h +++ b/include/asm-arm/arch-omap/control.h @@ -80,7 +80,7 @@ #define OMAP24XX_CONTROL_SEC_TAP (OMAP2_CONTROL_GENERAL + 0x0064) #define OMAP24XX_CONTROL_OCM_PUB_RAM_ADD (OMAP2_CONTROL_GENERAL + 0x006c) #define OMAP24XX_CONTROL_EXT_SEC_RAM_START_ADD (OMAP2_CONTROL_GENERAL + 0x0070) -#define OMAP24XX_CONTROL_EXT_SEC_RAM_STOP_ADD (OMAP2_CONTROL_GENERAL + 0x0074 +#define OMAP24XX_CONTROL_EXT_SEC_RAM_STOP_ADD (OMAP2_CONTROL_GENERAL + 0x0074) #define OMAP24XX_CONTROL_SEC_STATUS (OMAP2_CONTROL_GENERAL + 0x0080) #define OMAP24XX_CONTROL_SEC_ERR_STATUS (OMAP2_CONTROL_GENERAL + 0x0084) #define OMAP24XX_CONTROL_STATUS (OMAP2_CONTROL_GENERAL + 0x0088) diff --git a/include/asm-arm/arch-omap/mmc.h b/include/asm-arm/arch-omap/mmc.h index c9588f49eb5253bb23ce4150722d4b7181607fd6..7cfc5f2585606ef6a77b3d57a18aff153cb64096 100644 --- a/include/asm-arm/arch-omap/mmc.h +++ b/include/asm-arm/arch-omap/mmc.h @@ -15,21 +15,16 @@ #include #include +#include + #define OMAP_MMC_MAX_SLOTS 2 struct omap_mmc_platform_data { struct omap_mmc_conf conf; - unsigned enabled:1; /* number of slots on board */ unsigned nr_slots:2; - /* nomux means "standard" muxing is wrong on this board, and that - * board-specific code handled it before common init logic. - */ - unsigned nomux:1; - /* 4 wire signaling is optional, and is only used for SD/SDIO and - * MMCv4 */ - unsigned wire4:1; + /* set if your board has components or wiring that limits the * maximum frequency on the MMC bus */ unsigned int max_freq; @@ -40,6 +35,11 @@ struct omap_mmc_platform_data { * not supported */ int (* init)(struct device *dev); void (* cleanup)(struct device *dev); + void (* shutdown)(struct device *dev); + + /* To handle board related suspend/resume functionality for MMC */ + int (*suspend)(struct device *dev, int slot); + int (*resume)(struct device *dev, int slot); struct omap_mmc_slot_data { int (* set_bus_mode)(struct device *dev, int slot, int bus_mode); @@ -56,13 +56,19 @@ struct omap_mmc_platform_data { const char *name; u32 ocr_mask; + + /* Card detection IRQs */ + int card_detect_irq; + int (* card_detect)(int irq); + + unsigned int ban_openended:1; + } slots[OMAP_MMC_MAX_SLOTS]; }; extern void omap_set_mmc_info(int host, const struct omap_mmc_platform_data *info); /* called from board-specific card detection service routine */ -extern void omap_mmc_notify_card_detect(struct device *dev, int slot, int detected); extern void omap_mmc_notify_cover_event(struct device *dev, int slot, int is_closed); #endif diff --git a/include/asm-arm/arch-pxa/pm.h b/include/asm-arm/arch-pxa/pm.h index 9d9f4b54b2ce6f20013c6e5f39f69980b308288f..261e5bc958db158739c6ad45bfcd8e36b1c8ae19 100644 --- a/include/asm-arm/arch-pxa/pm.h +++ b/include/asm-arm/arch-pxa/pm.h @@ -10,7 +10,7 @@ #include struct pxa_cpu_pm_fns { - int save_size; + int save_count; void (*save)(unsigned long *); void (*restore)(unsigned long *); int (*valid)(suspend_state_t state); diff --git a/include/asm-arm/arch-pxa/system.h b/include/asm-arm/arch-pxa/system.h index a758a719180f64e5f4167eea0e9b6ca8b6ff3a75..9aa6c2e939e87938da14896651aed10f2b90dbbe 100644 --- a/include/asm-arm/arch-pxa/system.h +++ b/include/asm-arm/arch-pxa/system.h @@ -22,7 +22,8 @@ static inline void arch_idle(void) static inline void arch_reset(char mode) { - RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR; + if (cpu_is_pxa2xx()) + RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR; if (mode == 's') { /* Jump into ROM at address 0 */ diff --git a/include/asm-arm/arch-sa1100/irqs.h b/include/asm-arm/arch-sa1100/irqs.h index d7940683efb18c8175c7b836901a0680c5f650a5..7bf80484bb77ad6dafeab8befa48be648efd29da 100644 --- a/include/asm-arm/arch-sa1100/irqs.h +++ b/include/asm-arm/arch-sa1100/irqs.h @@ -141,7 +141,7 @@ #define IRQ_LOCOMO_LT (IRQ_BOARD_END + 17) #define IRQ_LOCOMO_SPI_RFR (IRQ_BOARD_END + 18) #define IRQ_LOCOMO_SPI_RFW (IRQ_BOARD_END + 19) -#define IRQ_LOCOMO_SPI_OVRN (IRQ_BOARD_END + 20) +#define IRQ_LOCOMO_SPI_REND (IRQ_BOARD_END + 20) #define IRQ_LOCOMO_SPI_TEND (IRQ_BOARD_END + 21) /* diff --git a/include/asm-arm/hardware/locomo.h b/include/asm-arm/hardware/locomo.h index adab77780ed3afe2522c1b2cb34fb7ae05b222d4..fb0645de6f3158b72c6685514ac181240de8230e 100644 --- a/include/asm-arm/hardware/locomo.h +++ b/include/asm-arm/hardware/locomo.h @@ -58,6 +58,11 @@ #define LOCOMO_SPIMD 0x00 /* SPI mode setting */ #define LOCOMO_SPICT 0x04 /* SPI mode control */ #define LOCOMO_SPIST 0x08 /* SPI status */ +#define LOCOMO_SPI_TEND (1 << 3) /* Transfer end bit */ +#define LOCOMO_SPI_REND (1 << 2) /* Receive end bit */ +#define LOCOMO_SPI_RFW (1 << 1) /* write buffer bit */ +#define LOCOMO_SPI_RFR (1) /* read buffer bit */ + #define LOCOMO_SPIIS 0x10 /* SPI interrupt status */ #define LOCOMO_SPIWE 0x14 /* SPI interrupt status write enable */ #define LOCOMO_SPIIE 0x18 /* SPI interrupt enable */ @@ -66,16 +71,12 @@ #define LOCOMO_SPIRD 0x24 /* SPI receive data read */ #define LOCOMO_SPITS 0x28 /* SPI transfer data shift */ #define LOCOMO_SPIRS 0x2C /* SPI receive data shift */ -#define LOCOMO_SPI_TEND (1 << 3) /* Transfer end bit */ -#define LOCOMO_SPI_OVRN (1 << 2) /* Over Run bit */ -#define LOCOMO_SPI_RFW (1 << 1) /* write buffer bit */ -#define LOCOMO_SPI_RFR (1) /* read buffer bit */ /* GPIO */ #define LOCOMO_GPD 0x90 /* GPIO direction */ #define LOCOMO_GPE 0x94 /* GPIO input enable */ #define LOCOMO_GPL 0x98 /* GPIO level */ -#define LOCOMO_GPO 0x9c /* GPIO out data setteing */ +#define LOCOMO_GPO 0x9c /* GPIO out data setting */ #define LOCOMO_GRIE 0xa0 /* GPIO rise detection */ #define LOCOMO_GFIE 0xa4 /* GPIO fall detection */ #define LOCOMO_GIS 0xa8 /* GPIO edge detection status */ @@ -96,6 +97,9 @@ #define LOCOMO_GPIO_DAC_SDATA LOCOMO_GPIO(10) #define LOCOMO_GPIO_DAC_SCK LOCOMO_GPIO(11) #define LOCOMO_GPIO_DAC_SLOAD LOCOMO_GPIO(12) +#define LOCOMO_GPIO_CARD_DETECT LOCOMO_GPIO(13) +#define LOCOMO_GPIO_WRITE_PROT LOCOMO_GPIO(14) +#define LOCOMO_GPIO_CARD_POWER LOCOMO_GPIO(15) /* Start the definitions of the devices. Each device has an initial * base address and a series of offsets from that base address. */ @@ -122,7 +126,7 @@ /* Audio controller */ #define LOCOMO_AUDIO 0x54 #define LOCOMO_ACC 0x00 /* Audio clock */ -#define LOCOMO_PAIF 0x7C /* PCM audio interface */ +#define LOCOMO_PAIF 0xD0 /* PCM audio interface */ /* Audio clock */ #define LOCOMO_ACC_XON 0x80 #define LOCOMO_ACC_XEN 0x40 @@ -162,7 +166,7 @@ extern struct bus_type locomo_bus_type; #define LOCOMO_DEVID_AUDIO 3 #define LOCOMO_DEVID_LED 4 #define LOCOMO_DEVID_UART 5 -#define LOCOMO_DEVID_SPI 6 +#define LOCOMO_DEVID_SPI 6 struct locomo_dev { struct device dev; @@ -204,7 +208,6 @@ int locomo_gpio_read_level(struct device *dev, unsigned int bits); int locomo_gpio_read_output(struct device *dev, unsigned int bits); void locomo_gpio_write(struct device *dev, unsigned int bits, unsigned int set); - /* M62332 control function */ void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int channel); diff --git a/include/asm-blackfin/bfin-global.h b/include/asm-blackfin/bfin-global.h index 716df7c8592322d2b8e851a81a0dcefb7efe0bf4..a9248d8836754224dd6fd95840be6064d8eb5bec 100644 --- a/include/asm-blackfin/bfin-global.h +++ b/include/asm-blackfin/bfin-global.h @@ -37,7 +37,9 @@ #include #include -#if defined(CONFIG_DMA_UNCACHED_2M) +#if defined(CONFIG_DMA_UNCACHED_4M) +# define DMA_UNCACHED_REGION (4 * 1024 * 1024) +#elif defined(CONFIG_DMA_UNCACHED_2M) # define DMA_UNCACHED_REGION (2 * 1024 * 1024) #elif defined(CONFIG_DMA_UNCACHED_1M) # define DMA_UNCACHED_REGION (1024 * 1024) diff --git a/include/asm-blackfin/checksum.h b/include/asm-blackfin/checksum.h index 2638f2586d2f12d3836ebda6007678a16068298f..6f6af2b8e9e01c35ba7289aad0b1e4f072735a0b 100644 --- a/include/asm-blackfin/checksum.h +++ b/include/asm-blackfin/checksum.h @@ -15,7 +15,7 @@ * * it's best to have buff aligned on a 32-bit boundary */ -unsigned int csum_partial(const unsigned char *buff, int len, unsigned int sum); +__wsum csum_partial(const void *buff, int len, __wsum sum); /* * the same as csum_partial, but copies from src while it @@ -25,8 +25,8 @@ unsigned int csum_partial(const unsigned char *buff, int len, unsigned int sum); * better 64-bit) boundary */ -unsigned int csum_partial_copy(const unsigned char *src, unsigned char *dst, - int len, int sum); +__wsum csum_partial_copy(const void *src, void *dst, + int len, __wsum sum); /* * the same as csum_partial_copy, but copies from user space. @@ -35,20 +35,19 @@ unsigned int csum_partial_copy(const unsigned char *src, unsigned char *dst, * better 64-bit) boundary */ -extern unsigned int csum_partial_copy_from_user(const unsigned char *src, - unsigned char *dst, int len, - int sum, int *csum_err); +extern __wsum csum_partial_copy_from_user(const void __user *src, void *dst, + int len, __wsum sum, int *csum_err); #define csum_partial_copy_nocheck(src, dst, len, sum) \ csum_partial_copy((src), (dst), (len), (sum)) -unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl); +__sum16 ip_fast_csum(unsigned char *iph, unsigned int ihl); /* * Fold a partial checksum */ -static inline unsigned int csum_fold(unsigned int sum) +static inline __sum16 csum_fold(__wsum sum) { while (sum >> 16) sum = (sum & 0xffff) + (sum >> 16); @@ -60,9 +59,9 @@ static inline unsigned int csum_fold(unsigned int sum) * returns a 16-bit checksum, already complemented */ -static inline unsigned int -csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr, unsigned short len, - unsigned short proto, unsigned int sum) +static inline __wsum +csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, + unsigned short proto, __wsum sum) { __asm__ ("%0 = %0 + %1;\n\t" @@ -84,9 +83,9 @@ csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr, unsigned short len, return (sum); } -static inline unsigned short int -csum_tcpudp_magic(unsigned long saddr, unsigned long daddr, unsigned short len, - unsigned short proto, unsigned int sum) +static inline __sum16 +csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len, + unsigned short proto, __wsum sum) { return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum)); } @@ -96,6 +95,6 @@ csum_tcpudp_magic(unsigned long saddr, unsigned long daddr, unsigned short len, * in icmp.c */ -extern unsigned short ip_compute_csum(const unsigned char *buff, int len); +extern __sum16 ip_compute_csum(const void *buff, int len); #endif /* _BFIN_CHECKSUM_H */ diff --git a/include/asm-blackfin/dpmc.h b/include/asm-blackfin/dpmc.h index 686cf83a5269bf70990e5008a3267ea1db28be3e..7f34cd384f12abbacab586bfe7417eb059e01c5e 100644 --- a/include/asm-blackfin/dpmc.h +++ b/include/asm-blackfin/dpmc.h @@ -1,7 +1,7 @@ /* * include/asm-blackfin/dpmc.h - Miscellaneous IOCTL commands for Dynamic Power * Management Controller Driver. - * Copyright (C) 2004 Analog Device Inc. + * Copyright (C) 2004-2008 Analog Device Inc. * */ #ifndef _BLACKFIN_DPMC_H_ @@ -65,6 +65,14 @@ void disable_wdog_timer(void); extern unsigned long get_cclk(void); extern unsigned long get_sclk(void); +struct bfin_dpmc_platform_data { + const unsigned int *tuple_tab; + unsigned short tabsize; + unsigned short vr_settling_time; /* in us */ +}; + +#define VRPAIR(vlev, freq) (((vlev) << 16) | ((freq) >> 16)) + #endif /* __KERNEL__ */ #endif /*_BLACKFIN_DPMC_H_*/ diff --git a/include/asm-blackfin/entry.h b/include/asm-blackfin/entry.h index 562c6d3a3232ba21f7b46ba724864384af452991..c4f721e0d00def673b14bf4febd92b342c477efb 100644 --- a/include/asm-blackfin/entry.h +++ b/include/asm-blackfin/entry.h @@ -17,6 +17,11 @@ #define PF_DTRACE_OFF 1 #define PF_DTRACE_BIT 5 +/* + * NOTE! The single-stepping code assumes that all interrupt handlers + * start by saving SYSCFG on the stack with their first instruction. + */ + /* This one is used for exceptions, emulation, and NMI. It doesn't push RETI and doesn't do cli. */ #define SAVE_ALL_SYS save_context_no_interrupts diff --git a/include/asm-blackfin/gpio.h b/include/asm-blackfin/gpio.h index 27ff532a806c6fc1aa804f05c79e5c47f0518963..ff95e9d883427fca797a9f6c84c7b9f21076f1ff 100644 --- a/include/asm-blackfin/gpio.h +++ b/include/asm-blackfin/gpio.h @@ -437,7 +437,6 @@ void gpio_set_value(unsigned gpio, int arg); int gpio_get_value(unsigned gpio); #ifndef BF548_FAMILY -#define gpio_get_value(gpio) get_gpio_data(gpio) #define gpio_set_value(gpio, value) set_gpio_data(gpio, value) #endif diff --git a/include/asm-blackfin/io.h b/include/asm-blackfin/io.h index 574fe56989d1d68c82e90ef6d1d365720a7ce162..cbbf7ffdbbff1d4450e29ef0b68c5d1cde99c168 100644 --- a/include/asm-blackfin/io.h +++ b/include/asm-blackfin/io.h @@ -117,10 +117,12 @@ static inline unsigned int readl(const volatile void __iomem *addr) extern void outsb(unsigned long port, const void *addr, unsigned long count); extern void outsw(unsigned long port, const void *addr, unsigned long count); +extern void outsw_8(unsigned long port, const void *addr, unsigned long count); extern void outsl(unsigned long port, const void *addr, unsigned long count); extern void insb(unsigned long port, void *addr, unsigned long count); extern void insw(unsigned long port, void *addr, unsigned long count); +extern void insw_8(unsigned long port, void *addr, unsigned long count); extern void insl(unsigned long port, void *addr, unsigned long count); extern void insl_16(unsigned long port, void *addr, unsigned long count); diff --git a/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h index f0ab2736a680415f42c25fc0714233d70b32994c..26e3c8076b4e5cafe08bb5ef97468a0f0db421f2 100644 --- a/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h +++ b/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h @@ -44,10 +44,15 @@ #define UART_PUT_CHAR(uart, v) bfin_write16(((uart)->port.membase + OFFSET_THR), v) #define UART_PUT_DLL(uart, v) bfin_write16(((uart)->port.membase + OFFSET_DLL), v) #define UART_PUT_IER(uart, v) bfin_write16(((uart)->port.membase + OFFSET_IER), v) +#define UART_SET_IER(uart, v) UART_PUT_IER(uart, UART_GET_IER(uart) | (v)) +#define UART_CLEAR_IER(uart, v) UART_PUT_IER(uart, UART_GET_IER(uart) & ~(v)) #define UART_PUT_DLH(uart, v) bfin_write16(((uart)->port.membase + OFFSET_DLH), v) #define UART_PUT_LCR(uart, v) bfin_write16(((uart)->port.membase + OFFSET_LCR), v) #define UART_PUT_GCTL(uart, v) bfin_write16(((uart)->port.membase + OFFSET_GCTL), v) +#define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0) +#define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0) + #if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS) # define CONFIG_SERIAL_BFIN_CTSRTS diff --git a/include/asm-blackfin/mach-bf527/blackfin.h b/include/asm-blackfin/mach-bf527/blackfin.h index 2891727b61766809c085d1b5e29f646160c34fee..297821e2d79a7217f1551d38bcbaf920fea50ea4 100644 --- a/include/asm-blackfin/mach-bf527/blackfin.h +++ b/include/asm-blackfin/mach-bf527/blackfin.h @@ -39,22 +39,22 @@ #include "defBF522.h" #include "anomaly.h" -#if defined(CONFIG_BF527) +#if defined(CONFIG_BF527) || defined(CONFIG_BF526) #include "defBF527.h" #endif -#if defined(CONFIG_BF525) +#if defined(CONFIG_BF525) || defined(CONFIG_BF524) #include "defBF525.h" #endif #if !defined(__ASSEMBLY__) #include "cdefBF522.h" -#if defined(CONFIG_BF527) +#if defined(CONFIG_BF527) || defined(CONFIG_BF526) #include "cdefBF527.h" #endif -#if defined(CONFIG_BF525) +#if defined(CONFIG_BF525) || defined(CONFIG_BF524) #include "cdefBF525.h" #endif #endif diff --git a/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h index fbe88dee3e2d8d379fbd713e4a405d7366ab7daa..d016603b661518eedcad888adeadbb8e6faf005f 100644 --- a/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h +++ b/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h @@ -44,10 +44,15 @@ #define UART_PUT_CHAR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_THR),v) #define UART_PUT_DLL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLL),v) #define UART_PUT_IER(uart,v) bfin_write16(((uart)->port.membase + OFFSET_IER),v) +#define UART_SET_IER(uart,v) UART_PUT_IER(uart, UART_GET_IER(uart) | (v)) +#define UART_CLEAR_IER(uart,v) UART_PUT_IER(uart, UART_GET_IER(uart) & ~(v)) #define UART_PUT_DLH(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLH),v) #define UART_PUT_LCR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_LCR),v) #define UART_PUT_GCTL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_GCTL),v) +#define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0) +#define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0) + #ifdef CONFIG_BFIN_UART0_CTSRTS # define CONFIG_SERIAL_BFIN_CTSRTS # ifndef CONFIG_UART0_CTS_PIN diff --git a/include/asm-blackfin/mach-bf533/defBF532.h b/include/asm-blackfin/mach-bf533/defBF532.h index 17e1548cec0813cd1004e57e7c19cec638a7cba5..0ab4dd7494cfe348ae7373764a64bfd12582d5ca 100644 --- a/include/asm-blackfin/mach-bf533/defBF532.h +++ b/include/asm-blackfin/mach-bf533/defBF532.h @@ -468,6 +468,8 @@ #define VLEV_110 0x00B0 /* VLEV = 1.10 V (-5% - +10% Accuracy) */ #define VLEV_115 0x00C0 /* VLEV = 1.15 V (-5% - +10% Accuracy) */ #define VLEV_120 0x00D0 /* VLEV = 1.20 V (-5% - +10% Accuracy) */ +#define VLEV_125 0x00E0 /* VLEV = 1.25 V (-5% - +10% Accuracy) */ +#define VLEV_130 0x00F0 /* VLEV = 1.30 V (-5% - +10% Accuracy) */ #define WAKE 0x0100 /* Enable RTC/Reset Wakeup From Hibernate */ #define SCKELOW 0x8000 /* Do Not Drive SCKE High During Reset After Hibernate */ diff --git a/include/asm-blackfin/mach-bf533/irq.h b/include/asm-blackfin/mach-bf533/irq.h index 832e6f6122da332d91072457ffbadaf56b6e9eff..5aa38e5da6b7d3a5b1d65f0ec00a7bc31ef60971 100644 --- a/include/asm-blackfin/mach-bf533/irq.h +++ b/include/asm-blackfin/mach-bf533/irq.h @@ -66,12 +66,13 @@ Core Emulation ** DMA8/9 Interrupt IVG13 28 DMA10/11 Interrupt IVG13 29 Watchdog Timer IVG13 30 - Software Interrupt 1 IVG14 31 - Software Interrupt 2 -- + + Softirq IVG14 31 + System Call -- (lowest priority) IVG15 32 * */ -#define SYS_IRQS 32 -#define NR_PERI_INTS 24 +#define SYS_IRQS 31 +#define NR_PERI_INTS 24 /* The ABSTRACT IRQ definitions */ /** the first seven of the following are fixed, the rest you change if you need to **/ @@ -96,7 +97,7 @@ Core Emulation ** #define IRQ_SPORT0_TX 17 /*DMA2 Interrupt (SPORT0 TX) */ #define IRQ_SPORT1_RX 18 /*DMA3 Interrupt (SPORT1 RX) */ #define IRQ_SPORT1_TX 19 /*DMA4 Interrupt (SPORT1 TX) */ -#define IRQ_SPI 20 /*DMA5 Interrupt (SPI) */ +#define IRQ_SPI 20 /*DMA5 Interrupt (SPI) */ #define IRQ_UART_RX 21 /*DMA6 Interrupt (UART RX) */ #define IRQ_UART_TX 22 /*DMA7 Interrupt (UART TX) */ #define IRQ_TMR0 23 /*Timer 0 */ @@ -108,9 +109,6 @@ Core Emulation ** #define IRQ_MEM_DMA1 29 /*DMA10/11 Interrupt (Memory DMA Stream 1) */ #define IRQ_WATCH 30 /*Watch Dog Timer */ -#define IRQ_SW_INT1 31 /*Software Int 1 */ -#define IRQ_SW_INT2 32 /*Software Int 2 (reserved for SYSCALL) */ - #define IRQ_PF0 33 #define IRQ_PF1 34 #define IRQ_PF2 35 diff --git a/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h index fd100a415b98bb937efbc87b22ff326f997b0da5..f79d1a0e9129bb0f3e74e64d8c831227fcf460f1 100644 --- a/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h +++ b/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h @@ -44,10 +44,15 @@ #define UART_PUT_CHAR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_THR),v) #define UART_PUT_DLL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLL),v) #define UART_PUT_IER(uart,v) bfin_write16(((uart)->port.membase + OFFSET_IER),v) +#define UART_SET_IER(uart,v) UART_PUT_IER(uart, UART_GET_IER(uart) | (v)) +#define UART_CLEAR_IER(uart,v) UART_PUT_IER(uart, UART_GET_IER(uart) & ~(v)) #define UART_PUT_DLH(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLH),v) #define UART_PUT_LCR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_LCR),v) #define UART_PUT_GCTL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_GCTL),v) +#define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0) +#define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0) + #if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS) # define CONFIG_SERIAL_BFIN_CTSRTS diff --git a/include/asm-blackfin/mach-bf537/irq.h b/include/asm-blackfin/mach-bf537/irq.h index be6f2ff77f311a0153414c428252dadfbd65b786..2e68a8a1e7309a61aae408d470615ee7b22db7f2 100644 --- a/include/asm-blackfin/mach-bf537/irq.h +++ b/include/asm-blackfin/mach-bf537/irq.h @@ -34,24 +34,23 @@ /* * Interrupt source definitions - Event Source Core Event Name -Core Emulation ** - Events (highest priority) EMU 0 - Reset RST 1 - NMI NMI 2 - Exception EVX 3 - Reserved -- 4 - Hardware Error IVHW 5 - Core Timer IVTMR 6 * - -..... - - Software Interrupt 1 IVG14 31 - Software Interrupt 2 -- - (lowest priority) IVG15 32 * + * Event Source Core Event Name + * Core Emulation ** + * Events (highest priority) EMU 0 + * Reset RST 1 + * NMI NMI 2 + * Exception EVX 3 + * Reserved -- 4 + * Hardware Error IVHW 5 + * Core Timer IVTMR 6 + * ..... + * + * Softirq IVG14 + * System Call -- + * (lowest priority) IVG15 */ -#define SYS_IRQS 41 +#define SYS_IRQS 39 #define NR_PERI_INTS 32 /* The ABSTRACT IRQ definitions */ @@ -95,10 +94,8 @@ Core Emulation ** #define IRQ_PORTG_INTB 35 /* PF Port G (PF15:0) Interrupt B */ #define IRQ_MEM_DMA0 36 /*(Memory DMA Stream 0) */ #define IRQ_MEM_DMA1 37 /*(Memory DMA Stream 1) */ -#define IRQ_PROG_INTB 38 /* PF Ports F (PF15:0) Interrupt B */ +#define IRQ_PROG_INTB 38 /* PF Ports F (PF15:0) Interrupt B */ #define IRQ_WATCH 38 /*Watch Dog Timer */ -#define IRQ_SW_INT1 40 /*Software Int 1 */ -#define IRQ_SW_INT2 41 /*Software Int 2 (reserved for SYSCALL) */ #define IRQ_PPI_ERROR 42 /*PPI Error Interrupt */ #define IRQ_CAN_ERROR 43 /*CAN Error Interrupt */ diff --git a/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h index 6547027cd3e62174a0bd5a0f9ee2aa0a6429fe5d..5eb46a77d919fd5eb2fab2caebf1ca25abce618d 100644 --- a/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h +++ b/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h @@ -54,6 +54,9 @@ #define UART_PUT_GCTL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_GCTL),v) #define UART_PUT_MCR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_MCR),v) +#define UART_SET_DLAB(uart) /* MMRs not muxed on BF54x */ +#define UART_CLEAR_DLAB(uart) /* MMRs not muxed on BF54x */ + #if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS) # define CONFIG_SERIAL_BFIN_CTSRTS diff --git a/include/asm-blackfin/mach-bf548/defBF54x_base.h b/include/asm-blackfin/mach-bf548/defBF54x_base.h index 08f90c21fe8a0f6538224f171853ea847177795d..e022e896cb1839717d4ea92f6e5dca3e7b3c0b73 100644 --- a/include/asm-blackfin/mach-bf548/defBF54x_base.h +++ b/include/asm-blackfin/mach-bf548/defBF54x_base.h @@ -2329,6 +2329,26 @@ #define KPADWE 0x1000 /* Keypad Wake-Up Enable */ #define ROTWE 0x2000 /* Rotary Wake-Up Enable */ +#define FREQ_333 0x0001 /* Switching Frequency Is 333 kHz */ +#define FREQ_667 0x0002 /* Switching Frequency Is 667 kHz */ +#define FREQ_1000 0x0003 /* Switching Frequency Is 1 MHz */ + +#define GAIN_5 0x0000 /* GAIN = 5*/ +#define GAIN_10 0x0004 /* GAIN = 1*/ +#define GAIN_20 0x0008 /* GAIN = 2*/ +#define GAIN_50 0x000C /* GAIN = 5*/ + +#define VLEV_085 0x0060 /* VLEV = 0.85 V (-5% - +10% Accuracy) */ +#define VLEV_090 0x0070 /* VLEV = 0.90 V (-5% - +10% Accuracy) */ +#define VLEV_095 0x0080 /* VLEV = 0.95 V (-5% - +10% Accuracy) */ +#define VLEV_100 0x0090 /* VLEV = 1.00 V (-5% - +10% Accuracy) */ +#define VLEV_105 0x00A0 /* VLEV = 1.05 V (-5% - +10% Accuracy) */ +#define VLEV_110 0x00B0 /* VLEV = 1.10 V (-5% - +10% Accuracy) */ +#define VLEV_115 0x00C0 /* VLEV = 1.15 V (-5% - +10% Accuracy) */ +#define VLEV_120 0x00D0 /* VLEV = 1.20 V (-5% - +10% Accuracy) */ +#define VLEV_125 0x00E0 /* VLEV = 1.25 V (-5% - +10% Accuracy) */ +#define VLEV_130 0x00F0 /* VLEV = 1.30 V (-5% - +10% Accuracy) */ + /* Bit masks for NFC_CTL */ #define WR_DLY 0xf /* Write Strobe Delay */ diff --git a/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h index 8a4e66d1db37aa0b80423cf3c54639833480a1c4..7a962876929619e5da8a0e3abc1f029a602a807b 100644 --- a/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h +++ b/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h @@ -44,10 +44,15 @@ #define UART_PUT_CHAR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_THR),v) #define UART_PUT_DLL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLL),v) #define UART_PUT_IER(uart,v) bfin_write16(((uart)->port.membase + OFFSET_IER),v) +#define UART_SET_IER(uart,v) UART_PUT_IER(uart, UART_GET_IER(uart) | (v)) +#define UART_CLEAR_IER(uart,v) UART_PUT_IER(uart, UART_GET_IER(uart) & ~(v)) #define UART_PUT_DLH(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLH),v) #define UART_PUT_LCR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_LCR),v) #define UART_PUT_GCTL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_GCTL),v) +#define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0) +#define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0) + #ifdef CONFIG_BFIN_UART0_CTSRTS # define CONFIG_SERIAL_BFIN_CTSRTS # ifndef CONFIG_UART0_CTS_PIN diff --git a/include/asm-blackfin/mach-bf561/defBF561.h b/include/asm-blackfin/mach-bf561/defBF561.h index 366c9b9a0cb70cf2f345b2075024df35b8ea3671..1ab50e906fe7e7db351fc006aca3385d4045fd34 100644 --- a/include/asm-blackfin/mach-bf561/defBF561.h +++ b/include/asm-blackfin/mach-bf561/defBF561.h @@ -868,6 +868,34 @@ #define CHIPID_FAMILY 0x0FFFF000 #define CHIPID_MANUFACTURE 0x00000FFE +/* VR_CTL Masks */ +#define FREQ 0x0003 /* Switching Oscillator Frequency For Regulator */ +#define HIBERNATE 0x0000 /* Powerdown/Bypass On-Board Regulation */ +#define FREQ_333 0x0001 /* Switching Frequency Is 333 kHz */ +#define FREQ_667 0x0002 /* Switching Frequency Is 667 kHz */ +#define FREQ_1000 0x0003 /* Switching Frequency Is 1 MHz */ + +#define GAIN 0x000C /* Voltage Level Gain */ +#define GAIN_5 0x0000 /* GAIN = 5*/ +#define GAIN_10 0x0004 /* GAIN = 1*/ +#define GAIN_20 0x0008 /* GAIN = 2*/ +#define GAIN_50 0x000C /* GAIN = 5*/ + +#define VLEV 0x00F0 /* Internal Voltage Level */ +#define VLEV_085 0x0060 /* VLEV = 0.85 V (-5% - +10% Accuracy) */ +#define VLEV_090 0x0070 /* VLEV = 0.90 V (-5% - +10% Accuracy) */ +#define VLEV_095 0x0080 /* VLEV = 0.95 V (-5% - +10% Accuracy) */ +#define VLEV_100 0x0090 /* VLEV = 1.00 V (-5% - +10% Accuracy) */ +#define VLEV_105 0x00A0 /* VLEV = 1.05 V (-5% - +10% Accuracy) */ +#define VLEV_110 0x00B0 /* VLEV = 1.10 V (-5% - +10% Accuracy) */ +#define VLEV_115 0x00C0 /* VLEV = 1.15 V (-5% - +10% Accuracy) */ +#define VLEV_120 0x00D0 /* VLEV = 1.20 V (-5% - +10% Accuracy) */ +#define VLEV_125 0x00E0 /* VLEV = 1.25 V (-5% - +10% Accuracy) */ +#define VLEV_130 0x00F0 /* VLEV = 1.30 V (-5% - +10% Accuracy) */ + +#define WAKE 0x0100 /* Enable RTC/Reset Wakeup From Hibernate */ +#define SCKELOW 0x8000 /* Do Not Drive SCKE High During Reset After Hibernate */ + /* PLL_DIV Masks */ #define SCLK_DIV(x) (x) /* SCLK = VCO / x */ diff --git a/include/asm-blackfin/mach-bf561/dma.h b/include/asm-blackfin/mach-bf561/dma.h index 21d982003e7525c80188ae55bf2df8985ec77658..8bc46cd89a0238ba3949c0bd65cdc2d2778e9e15 100644 --- a/include/asm-blackfin/mach-bf561/dma.h +++ b/include/asm-blackfin/mach-bf561/dma.h @@ -25,11 +25,11 @@ #define CH_MEM_STREAM1_SRC 27 /* RX */ #define CH_MEM_STREAM2_DEST 28 #define CH_MEM_STREAM2_SRC 29 -#define CH_MEM_STREAM3_SRC 30 -#define CH_MEM_STREAM3_DEST 31 +#define CH_MEM_STREAM3_DEST 30 +#define CH_MEM_STREAM3_SRC 31 #define CH_IMEM_STREAM0_DEST 32 #define CH_IMEM_STREAM0_SRC 33 -#define CH_IMEM_STREAM1_SRC 34 -#define CH_IMEM_STREAM1_DEST 35 +#define CH_IMEM_STREAM1_DEST 34 +#define CH_IMEM_STREAM1_SRC 35 #endif diff --git a/include/asm-blackfin/mach-bf561/irq.h b/include/asm-blackfin/mach-bf561/irq.h index 83f0383957d25e099f36e04c139bf4197e7d705c..6698389c556451c51306b9dba7ed2f029af73416 100644 --- a/include/asm-blackfin/mach-bf561/irq.h +++ b/include/asm-blackfin/mach-bf561/irq.h @@ -118,12 +118,13 @@ Supplemental interrupt 0 IVG7 69 supplemental interrupt 1 IVG7 70 - Software Interrupt 1 IVG14 71 - Software Interrupt 2 IVG15 72 * - (lowest priority) + Softirq IVG14 + System Call -- + (lowest priority) IVG15 + **********************************************************************/ -#define SYS_IRQS 72 +#define SYS_IRQS 71 #define NR_PERI_INTS 64 /* @@ -237,9 +238,7 @@ #define IRQ_RESERVED_2 (IVG_BASE + 61) /* Reserved interrupt */ #define IRQ_SUPPLE_0 (IVG_BASE + 62) /* Supplemental interrupt 0 */ #define IRQ_SUPPLE_1 (IVG_BASE + 63) /* supplemental interrupt 1 */ -#define IRQ_SW_INT1 71 /* Software Interrupt 1 */ -#define IRQ_SW_INT2 72 /* Software Interrupt 2 */ - /* reserved for SYSCALL */ + #define IRQ_PF0 73 #define IRQ_PF1 74 #define IRQ_PF2 75 diff --git a/include/asm-blackfin/mach-common/context.S b/include/asm-blackfin/mach-common/context.S index fd0ebe1862b84c499397341b5134d7a1537363d9..c0e630edfb9a30950b92eca4101c50be14dc79ed 100644 --- a/include/asm-blackfin/mach-common/context.S +++ b/include/asm-blackfin/mach-common/context.S @@ -27,6 +27,11 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +/* + * NOTE! The single-stepping code assumes that all interrupt handlers + * start by saving SYSCFG on the stack with their first instruction. + */ + /* * Code to save processor context. * We even save the register which are preserved by a function call diff --git a/include/asm-blackfin/serial.h b/include/asm-blackfin/serial.h new file mode 100644 index 0000000000000000000000000000000000000000..994dd869558c0fe7c1e11af2bbe661e3b7425868 --- /dev/null +++ b/include/asm-blackfin/serial.h @@ -0,0 +1,5 @@ +/* + * include/asm-blackfin/serial.h + */ + +#define SERIAL_EXTRA_IRQ_FLAGS IRQF_TRIGGER_HIGH diff --git a/include/asm-blackfin/time.h b/include/asm-blackfin/time.h index 6e5859b6ea32f234fd0019582a3518fc14885420..ddc43ce385338054a68a1c50a149c01b53185ce7 100644 --- a/include/asm-blackfin/time.h +++ b/include/asm-blackfin/time.h @@ -24,6 +24,8 @@ #ifndef CONFIG_CPU_FREQ #define TIME_SCALE 1 +#define __bfin_cycles_off (0) +#define __bfin_cycles_mod (0) #else /* * Blackfin CPU frequency scaling supports max Core Clock 1, 1/2 and 1/4 . @@ -31,6 +33,8 @@ * adjust the Core Timer Presale Register. This way we don't lose time. */ #define TIME_SCALE 4 +extern unsigned long long __bfin_cycles_off; +extern unsigned int __bfin_cycles_mod; #endif #endif diff --git a/include/asm-frv/system.h b/include/asm-frv/system.h index cb307f8a6b486406424319c89cab2ac491a5b2fa..d3a12a9079f78f672615c3b5a31ed1bb7921e37f 100644 --- a/include/asm-frv/system.h +++ b/include/asm-frv/system.h @@ -179,7 +179,7 @@ do { \ #define mb() asm volatile ("membar" : : :"memory") #define rmb() asm volatile ("membar" : : :"memory") #define wmb() asm volatile ("membar" : : :"memory") -#define read_barrier_depends() barrier() +#define read_barrier_depends() do { } while (0) #ifdef CONFIG_SMP #define smp_mb() mb() diff --git a/include/asm-h8300/param.h b/include/asm-h8300/param.h index 04f64f1003792b77c4a6be5a8da51f3f7b2e9b93..1c72fb8080ff645dffeb799d052283014bc2e535 100644 --- a/include/asm-h8300/param.h +++ b/include/asm-h8300/param.h @@ -1,14 +1,12 @@ #ifndef _H8300_PARAM_H #define _H8300_PARAM_H - -#ifndef HZ -#define HZ CONFIG_HZ -#endif - #ifdef __KERNEL__ +#define HZ CONFIG_HZ #define USER_HZ HZ #define CLOCKS_PER_SEC (USER_HZ) +#else +#define HZ 100 #endif #define EXEC_PAGESIZE 4096 diff --git a/include/asm-ia64/kvm.h b/include/asm-ia64/kvm.h index eb2d3559d089a52c24d7df5cecc1bf0b82cccdab..3f6a090cbd9abeef0ba6732a369bf77cc48b8bb7 100644 --- a/include/asm-ia64/kvm.h +++ b/include/asm-ia64/kvm.h @@ -22,14 +22,13 @@ */ #include -#include #include /* Architectural interrupt line count. */ #define KVM_NR_INTERRUPTS 256 -#define KVM_IOAPIC_NUM_PINS 24 +#define KVM_IOAPIC_NUM_PINS 48 struct kvm_ioapic_state { __u64 base_address; @@ -61,6 +60,13 @@ struct kvm_ioapic_state { #define KVM_CONTEXT_SIZE 8*1024 +struct kvm_fpreg { + union { + unsigned long bits[2]; + long double __dummy; /* force 16-byte alignment */ + } u; +}; + union context { /* 8K size */ char dummy[KVM_CONTEXT_SIZE]; @@ -77,7 +83,7 @@ union context { unsigned long ibr[8]; unsigned long dbr[8]; unsigned long pkr[8]; - struct ia64_fpreg fr[128]; + struct kvm_fpreg fr[128]; }; }; diff --git a/include/asm-ia64/machvec.h b/include/asm-ia64/machvec.h index 9f020eb825c58c89224bfd10923a1872d77cb3ad..0721a5e8271e7ffe2181a487689f155b7b85cb89 100644 --- a/include/asm-ia64/machvec.h +++ b/include/asm-ia64/machvec.h @@ -126,6 +126,8 @@ extern void machvec_tlb_migrate_finish (struct mm_struct *); # include # elif defined (CONFIG_IA64_SGI_SN2) # include +# elif defined (CONFIG_IA64_SGI_UV) +# include # elif defined (CONFIG_IA64_GENERIC) # ifdef MACHVEC_PLATFORM_HEADER diff --git a/include/asm-ia64/machvec_uv.h b/include/asm-ia64/machvec_uv.h new file mode 100644 index 0000000000000000000000000000000000000000..2931447f3813c2cf34c469614923a84b70dfcb22 --- /dev/null +++ b/include/asm-ia64/machvec_uv.h @@ -0,0 +1,26 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * SGI UV Core Functions + * + * Copyright (C) 2008 Silicon Graphics, Inc. All rights reserved. + */ + +#ifndef _ASM_IA64_MACHVEC_UV_H +#define _ASM_IA64_MACHVEC_UV_H + +extern ia64_mv_setup_t uv_setup; + +/* + * This stuff has dual use! + * + * For a generic kernel, the macros are used to initialize the + * platform's machvec structure. When compiling a non-generic kernel, + * the macros are used directly. + */ +#define platform_name "uv" +#define platform_setup uv_setup + +#endif /* _ASM_IA64_MACHVEC_UV_H */ diff --git a/include/asm-ia64/uv/uv_hub.h b/include/asm-ia64/uv/uv_hub.h new file mode 100644 index 0000000000000000000000000000000000000000..f607018af4a19397691212e7074a55455a2f3cd2 --- /dev/null +++ b/include/asm-ia64/uv/uv_hub.h @@ -0,0 +1,309 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * SGI UV architectural definitions + * + * Copyright (C) 2008 Silicon Graphics, Inc. All rights reserved. + */ + +#ifndef __ASM_IA64_UV_HUB_H__ +#define __ASM_IA64_UV_HUB_H__ + +#include +#include +#include +#include + + +/* + * Addressing Terminology + * + * M - The low M bits of a physical address represent the offset + * into the blade local memory. RAM memory on a blade is physically + * contiguous (although various IO spaces may punch holes in + * it).. + * + * N - Number of bits in the node portion of a socket physical + * address. + * + * NASID - network ID of a router, Mbrick or Cbrick. Nasid values of + * routers always have low bit of 1, C/MBricks have low bit + * equal to 0. Most addressing macros that target UV hub chips + * right shift the NASID by 1 to exclude the always-zero bit. + * NASIDs contain up to 15 bits. + * + * GNODE - NASID right shifted by 1 bit. Most mmrs contain gnodes instead + * of nasids. + * + * PNODE - the low N bits of the GNODE. The PNODE is the most useful variant + * of the nasid for socket usage. + * + * + * NumaLink Global Physical Address Format: + * +--------------------------------+---------------------+ + * |00..000| GNODE | NodeOffset | + * +--------------------------------+---------------------+ + * |<-------53 - M bits --->|<--------M bits -----> + * + * M - number of node offset bits (35 .. 40) + * + * + * Memory/UV-HUB Processor Socket Address Format: + * +----------------+---------------+---------------------+ + * |00..000000000000| PNODE | NodeOffset | + * +----------------+---------------+---------------------+ + * <--- N bits --->|<--------M bits -----> + * + * M - number of node offset bits (35 .. 40) + * N - number of PNODE bits (0 .. 10) + * + * Note: M + N cannot currently exceed 44 (x86_64) or 46 (IA64). + * The actual values are configuration dependent and are set at + * boot time. M & N values are set by the hardware/BIOS at boot. + */ + + +/* + * Maximum number of bricks in all partitions and in all coherency domains. + * This is the total number of bricks accessible in the numalink fabric. It + * includes all C & M bricks. Routers are NOT included. + * + * This value is also the value of the maximum number of non-router NASIDs + * in the numalink fabric. + * + * NOTE: a brick may contain 1 or 2 OS nodes. Don't get these confused. + */ +#define UV_MAX_NUMALINK_BLADES 16384 + +/* + * Maximum number of C/Mbricks within a software SSI (hardware may support + * more). + */ +#define UV_MAX_SSI_BLADES 1 + +/* + * The largest possible NASID of a C or M brick (+ 2) + */ +#define UV_MAX_NASID_VALUE (UV_MAX_NUMALINK_NODES * 2) + +/* + * The following defines attributes of the HUB chip. These attributes are + * frequently referenced and are kept in the per-cpu data areas of each cpu. + * They are kept together in a struct to minimize cache misses. + */ +struct uv_hub_info_s { + unsigned long global_mmr_base; + unsigned long gpa_mask; + unsigned long gnode_upper; + unsigned long lowmem_remap_top; + unsigned long lowmem_remap_base; + unsigned short pnode; + unsigned short pnode_mask; + unsigned short coherency_domain_number; + unsigned short numa_blade_id; + unsigned char blade_processor_id; + unsigned char m_val; + unsigned char n_val; +}; +DECLARE_PER_CPU(struct uv_hub_info_s, __uv_hub_info); +#define uv_hub_info (&__get_cpu_var(__uv_hub_info)) +#define uv_cpu_hub_info(cpu) (&per_cpu(__uv_hub_info, cpu)) + +/* + * Local & Global MMR space macros. + * Note: macros are intended to be used ONLY by inline functions + * in this file - not by other kernel code. + * n - NASID (full 15-bit global nasid) + * g - GNODE (full 15-bit global nasid, right shifted 1) + * p - PNODE (local part of nsids, right shifted 1) + */ +#define UV_NASID_TO_PNODE(n) (((n) >> 1) & uv_hub_info->pnode_mask) +#define UV_PNODE_TO_NASID(p) (((p) << 1) | uv_hub_info->gnode_upper) + +#define UV_LOCAL_MMR_BASE 0xf4000000UL +#define UV_GLOBAL_MMR32_BASE 0xf8000000UL +#define UV_GLOBAL_MMR64_BASE (uv_hub_info->global_mmr_base) + +#define UV_GLOBAL_MMR32_PNODE_SHIFT 15 +#define UV_GLOBAL_MMR64_PNODE_SHIFT 26 + +#define UV_GLOBAL_MMR32_PNODE_BITS(p) ((p) << (UV_GLOBAL_MMR32_PNODE_SHIFT)) + +#define UV_GLOBAL_MMR64_PNODE_BITS(p) \ + ((unsigned long)(p) << UV_GLOBAL_MMR64_PNODE_SHIFT) + +/* + * Macros for converting between kernel virtual addresses, socket local physical + * addresses, and UV global physical addresses. + * Note: use the standard __pa() & __va() macros for converting + * between socket virtual and socket physical addresses. + */ + +/* socket phys RAM --> UV global physical address */ +static inline unsigned long uv_soc_phys_ram_to_gpa(unsigned long paddr) +{ + if (paddr < uv_hub_info->lowmem_remap_top) + paddr += uv_hub_info->lowmem_remap_base; + return paddr | uv_hub_info->gnode_upper; +} + + +/* socket virtual --> UV global physical address */ +static inline unsigned long uv_gpa(void *v) +{ + return __pa(v) | uv_hub_info->gnode_upper; +} + +/* socket virtual --> UV global physical address */ +static inline void *uv_vgpa(void *v) +{ + return (void *)uv_gpa(v); +} + +/* UV global physical address --> socket virtual */ +static inline void *uv_va(unsigned long gpa) +{ + return __va(gpa & uv_hub_info->gpa_mask); +} + +/* pnode, offset --> socket virtual */ +static inline void *uv_pnode_offset_to_vaddr(int pnode, unsigned long offset) +{ + return __va(((unsigned long)pnode << uv_hub_info->m_val) | offset); +} + + +/* + * Access global MMRs using the low memory MMR32 space. This region supports + * faster MMR access but not all MMRs are accessible in this space. + */ +static inline unsigned long *uv_global_mmr32_address(int pnode, + unsigned long offset) +{ + return __va(UV_GLOBAL_MMR32_BASE | + UV_GLOBAL_MMR32_PNODE_BITS(pnode) | offset); +} + +static inline void uv_write_global_mmr32(int pnode, unsigned long offset, + unsigned long val) +{ + *uv_global_mmr32_address(pnode, offset) = val; +} + +static inline unsigned long uv_read_global_mmr32(int pnode, + unsigned long offset) +{ + return *uv_global_mmr32_address(pnode, offset); +} + +/* + * Access Global MMR space using the MMR space located at the top of physical + * memory. + */ +static inline unsigned long *uv_global_mmr64_address(int pnode, + unsigned long offset) +{ + return __va(UV_GLOBAL_MMR64_BASE | + UV_GLOBAL_MMR64_PNODE_BITS(pnode) | offset); +} + +static inline void uv_write_global_mmr64(int pnode, unsigned long offset, + unsigned long val) +{ + *uv_global_mmr64_address(pnode, offset) = val; +} + +static inline unsigned long uv_read_global_mmr64(int pnode, + unsigned long offset) +{ + return *uv_global_mmr64_address(pnode, offset); +} + +/* + * Access hub local MMRs. Faster than using global space but only local MMRs + * are accessible. + */ +static inline unsigned long *uv_local_mmr_address(unsigned long offset) +{ + return __va(UV_LOCAL_MMR_BASE | offset); +} + +static inline unsigned long uv_read_local_mmr(unsigned long offset) +{ + return *uv_local_mmr_address(offset); +} + +static inline void uv_write_local_mmr(unsigned long offset, unsigned long val) +{ + *uv_local_mmr_address(offset) = val; +} + +/* + * Structures and definitions for converting between cpu, node, pnode, and blade + * numbers. + */ + +/* Blade-local cpu number of current cpu. Numbered 0 .. <# cpus on the blade> */ +static inline int uv_blade_processor_id(void) +{ + return smp_processor_id(); +} + +/* Blade number of current cpu. Numnbered 0 .. <#blades -1> */ +static inline int uv_numa_blade_id(void) +{ + return 0; +} + +/* Convert a cpu number to the the UV blade number */ +static inline int uv_cpu_to_blade_id(int cpu) +{ + return 0; +} + +/* Convert linux node number to the UV blade number */ +static inline int uv_node_to_blade_id(int nid) +{ + return 0; +} + +/* Convert a blade id to the PNODE of the blade */ +static inline int uv_blade_to_pnode(int bid) +{ + return 0; +} + +/* Determine the number of possible cpus on a blade */ +static inline int uv_blade_nr_possible_cpus(int bid) +{ + return num_possible_cpus(); +} + +/* Determine the number of online cpus on a blade */ +static inline int uv_blade_nr_online_cpus(int bid) +{ + return num_online_cpus(); +} + +/* Convert a cpu id to the PNODE of the blade containing the cpu */ +static inline int uv_cpu_to_pnode(int cpu) +{ + return 0; +} + +/* Convert a linux node number to the PNODE of the blade */ +static inline int uv_node_to_pnode(int nid) +{ + return 0; +} + +/* Maximum possible number of blades */ +static inline int uv_num_possible_blades(void) +{ + return 1; +} + +#endif /* __ASM_IA64_UV_HUB__ */ + diff --git a/include/asm-ia64/uv/uv_mmrs.h b/include/asm-ia64/uv/uv_mmrs.h new file mode 100644 index 0000000000000000000000000000000000000000..1cc1dbb0182f6bdb73d6fa0c53451d5ffce129a9 --- /dev/null +++ b/include/asm-ia64/uv/uv_mmrs.h @@ -0,0 +1,266 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * SGI UV MMR definitions + * + * Copyright (C) 2007-2008 Silicon Graphics, Inc. All rights reserved. + */ + +#ifndef __ASM_IA64_UV_MMRS__ +#define __ASM_IA64_UV_MMRS__ + +/* + * AUTO GENERATED - Do not edit + */ + + #define UV_MMR_ENABLE (1UL << 63) + +/* ========================================================================= */ +/* UVH_NODE_ID */ +/* ========================================================================= */ +#define UVH_NODE_ID 0x0UL + +#define UVH_NODE_ID_FORCE1_SHFT 0 +#define UVH_NODE_ID_FORCE1_MASK 0x0000000000000001UL +#define UVH_NODE_ID_MANUFACTURER_SHFT 1 +#define UVH_NODE_ID_MANUFACTURER_MASK 0x0000000000000ffeUL +#define UVH_NODE_ID_PART_NUMBER_SHFT 12 +#define UVH_NODE_ID_PART_NUMBER_MASK 0x000000000ffff000UL +#define UVH_NODE_ID_REVISION_SHFT 28 +#define UVH_NODE_ID_REVISION_MASK 0x00000000f0000000UL +#define UVH_NODE_ID_NODE_ID_SHFT 32 +#define UVH_NODE_ID_NODE_ID_MASK 0x00007fff00000000UL +#define UVH_NODE_ID_NODES_PER_BIT_SHFT 48 +#define UVH_NODE_ID_NODES_PER_BIT_MASK 0x007f000000000000UL +#define UVH_NODE_ID_NI_PORT_SHFT 56 +#define UVH_NODE_ID_NI_PORT_MASK 0x0f00000000000000UL + +union uvh_node_id_u { + unsigned long v; + struct uvh_node_id_s { + unsigned long force1 : 1; /* RO */ + unsigned long manufacturer : 11; /* RO */ + unsigned long part_number : 16; /* RO */ + unsigned long revision : 4; /* RO */ + unsigned long node_id : 15; /* RW */ + unsigned long rsvd_47 : 1; /* */ + unsigned long nodes_per_bit : 7; /* RW */ + unsigned long rsvd_55 : 1; /* */ + unsigned long ni_port : 4; /* RO */ + unsigned long rsvd_60_63 : 4; /* */ + } s; +}; + +/* ========================================================================= */ +/* UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR */ +/* ========================================================================= */ +#define UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR 0x16000d0UL + +#define UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR_DEST_BASE_SHFT 24 +#define UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR_DEST_BASE_MASK 0x00003fffff000000UL + +union uvh_rh_gam_alias210_redirect_config_0_mmr_u { + unsigned long v; + struct uvh_rh_gam_alias210_redirect_config_0_mmr_s { + unsigned long rsvd_0_23 : 24; /* */ + unsigned long dest_base : 22; /* RW */ + unsigned long rsvd_46_63: 18; /* */ + } s; +}; + +/* ========================================================================= */ +/* UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR */ +/* ========================================================================= */ +#define UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR 0x16000e0UL + +#define UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR_DEST_BASE_SHFT 24 +#define UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR_DEST_BASE_MASK 0x00003fffff000000UL + +union uvh_rh_gam_alias210_redirect_config_1_mmr_u { + unsigned long v; + struct uvh_rh_gam_alias210_redirect_config_1_mmr_s { + unsigned long rsvd_0_23 : 24; /* */ + unsigned long dest_base : 22; /* RW */ + unsigned long rsvd_46_63: 18; /* */ + } s; +}; + +/* ========================================================================= */ +/* UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR */ +/* ========================================================================= */ +#define UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR 0x16000f0UL + +#define UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR_DEST_BASE_SHFT 24 +#define UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR_DEST_BASE_MASK 0x00003fffff000000UL + +union uvh_rh_gam_alias210_redirect_config_2_mmr_u { + unsigned long v; + struct uvh_rh_gam_alias210_redirect_config_2_mmr_s { + unsigned long rsvd_0_23 : 24; /* */ + unsigned long dest_base : 22; /* RW */ + unsigned long rsvd_46_63: 18; /* */ + } s; +}; + +/* ========================================================================= */ +/* UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR */ +/* ========================================================================= */ +#define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR 0x1600010UL + +#define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT 28 +#define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffff0000000UL +#define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_GR4_SHFT 46 +#define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_GR4_MASK 0x0000400000000000UL +#define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_N_GRU_SHFT 52 +#define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_N_GRU_MASK 0x00f0000000000000UL +#define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63 +#define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL + +union uvh_rh_gam_gru_overlay_config_mmr_u { + unsigned long v; + struct uvh_rh_gam_gru_overlay_config_mmr_s { + unsigned long rsvd_0_27: 28; /* */ + unsigned long base : 18; /* RW */ + unsigned long gr4 : 1; /* RW */ + unsigned long rsvd_47_51: 5; /* */ + unsigned long n_gru : 4; /* RW */ + unsigned long rsvd_56_62: 7; /* */ + unsigned long enable : 1; /* RW */ + } s; +}; + +/* ========================================================================= */ +/* UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR */ +/* ========================================================================= */ +#define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR 0x1600028UL + +#define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_SHFT 26 +#define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffffc000000UL +#define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_DUAL_HUB_SHFT 46 +#define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_DUAL_HUB_MASK 0x0000400000000000UL +#define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63 +#define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL + +union uvh_rh_gam_mmr_overlay_config_mmr_u { + unsigned long v; + struct uvh_rh_gam_mmr_overlay_config_mmr_s { + unsigned long rsvd_0_25: 26; /* */ + unsigned long base : 20; /* RW */ + unsigned long dual_hub : 1; /* RW */ + unsigned long rsvd_47_62: 16; /* */ + unsigned long enable : 1; /* RW */ + } s; +}; + +/* ========================================================================= */ +/* UVH_RTC */ +/* ========================================================================= */ +#define UVH_RTC 0x28000UL + +#define UVH_RTC_REAL_TIME_CLOCK_SHFT 0 +#define UVH_RTC_REAL_TIME_CLOCK_MASK 0x00ffffffffffffffUL + +union uvh_rtc_u { + unsigned long v; + struct uvh_rtc_s { + unsigned long real_time_clock : 56; /* RW */ + unsigned long rsvd_56_63 : 8; /* */ + } s; +}; + +/* ========================================================================= */ +/* UVH_SI_ADDR_MAP_CONFIG */ +/* ========================================================================= */ +#define UVH_SI_ADDR_MAP_CONFIG 0xc80000UL + +#define UVH_SI_ADDR_MAP_CONFIG_M_SKT_SHFT 0 +#define UVH_SI_ADDR_MAP_CONFIG_M_SKT_MASK 0x000000000000003fUL +#define UVH_SI_ADDR_MAP_CONFIG_N_SKT_SHFT 8 +#define UVH_SI_ADDR_MAP_CONFIG_N_SKT_MASK 0x0000000000000f00UL + +union uvh_si_addr_map_config_u { + unsigned long v; + struct uvh_si_addr_map_config_s { + unsigned long m_skt : 6; /* RW */ + unsigned long rsvd_6_7: 2; /* */ + unsigned long n_skt : 4; /* RW */ + unsigned long rsvd_12_63: 52; /* */ + } s; +}; + +/* ========================================================================= */ +/* UVH_SI_ALIAS0_OVERLAY_CONFIG */ +/* ========================================================================= */ +#define UVH_SI_ALIAS0_OVERLAY_CONFIG 0xc80008UL + +#define UVH_SI_ALIAS0_OVERLAY_CONFIG_BASE_SHFT 24 +#define UVH_SI_ALIAS0_OVERLAY_CONFIG_BASE_MASK 0x00000000ff000000UL +#define UVH_SI_ALIAS0_OVERLAY_CONFIG_M_ALIAS_SHFT 48 +#define UVH_SI_ALIAS0_OVERLAY_CONFIG_M_ALIAS_MASK 0x001f000000000000UL +#define UVH_SI_ALIAS0_OVERLAY_CONFIG_ENABLE_SHFT 63 +#define UVH_SI_ALIAS0_OVERLAY_CONFIG_ENABLE_MASK 0x8000000000000000UL + +union uvh_si_alias0_overlay_config_u { + unsigned long v; + struct uvh_si_alias0_overlay_config_s { + unsigned long rsvd_0_23: 24; /* */ + unsigned long base : 8; /* RW */ + unsigned long rsvd_32_47: 16; /* */ + unsigned long m_alias : 5; /* RW */ + unsigned long rsvd_53_62: 10; /* */ + unsigned long enable : 1; /* RW */ + } s; +}; + +/* ========================================================================= */ +/* UVH_SI_ALIAS1_OVERLAY_CONFIG */ +/* ========================================================================= */ +#define UVH_SI_ALIAS1_OVERLAY_CONFIG 0xc80010UL + +#define UVH_SI_ALIAS1_OVERLAY_CONFIG_BASE_SHFT 24 +#define UVH_SI_ALIAS1_OVERLAY_CONFIG_BASE_MASK 0x00000000ff000000UL +#define UVH_SI_ALIAS1_OVERLAY_CONFIG_M_ALIAS_SHFT 48 +#define UVH_SI_ALIAS1_OVERLAY_CONFIG_M_ALIAS_MASK 0x001f000000000000UL +#define UVH_SI_ALIAS1_OVERLAY_CONFIG_ENABLE_SHFT 63 +#define UVH_SI_ALIAS1_OVERLAY_CONFIG_ENABLE_MASK 0x8000000000000000UL + +union uvh_si_alias1_overlay_config_u { + unsigned long v; + struct uvh_si_alias1_overlay_config_s { + unsigned long rsvd_0_23: 24; /* */ + unsigned long base : 8; /* RW */ + unsigned long rsvd_32_47: 16; /* */ + unsigned long m_alias : 5; /* RW */ + unsigned long rsvd_53_62: 10; /* */ + unsigned long enable : 1; /* RW */ + } s; +}; + +/* ========================================================================= */ +/* UVH_SI_ALIAS2_OVERLAY_CONFIG */ +/* ========================================================================= */ +#define UVH_SI_ALIAS2_OVERLAY_CONFIG 0xc80018UL + +#define UVH_SI_ALIAS2_OVERLAY_CONFIG_BASE_SHFT 24 +#define UVH_SI_ALIAS2_OVERLAY_CONFIG_BASE_MASK 0x00000000ff000000UL +#define UVH_SI_ALIAS2_OVERLAY_CONFIG_M_ALIAS_SHFT 48 +#define UVH_SI_ALIAS2_OVERLAY_CONFIG_M_ALIAS_MASK 0x001f000000000000UL +#define UVH_SI_ALIAS2_OVERLAY_CONFIG_ENABLE_SHFT 63 +#define UVH_SI_ALIAS2_OVERLAY_CONFIG_ENABLE_MASK 0x8000000000000000UL + +union uvh_si_alias2_overlay_config_u { + unsigned long v; + struct uvh_si_alias2_overlay_config_s { + unsigned long rsvd_0_23: 24; /* */ + unsigned long base : 8; /* RW */ + unsigned long rsvd_32_47: 16; /* */ + unsigned long m_alias : 5; /* RW */ + unsigned long rsvd_53_62: 10; /* */ + unsigned long enable : 1; /* RW */ + } s; +}; + + +#endif /* __ASM_IA64_UV_MMRS__ */ diff --git a/include/asm-m68k/bug.h b/include/asm-m68k/bug.h index 7b60776cc966dfd15be72db4366cc33a78bd8f9f..e5b528deb8a8496bb873c1ddffdf982eb074cbb2 100644 --- a/include/asm-m68k/bug.h +++ b/include/asm-m68k/bug.h @@ -7,7 +7,7 @@ #ifndef CONFIG_SUN3 #define BUG() do { \ printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ - asm volatile("illegal"); \ + __builtin_trap(); \ } while (0) #else #define BUG() do { \ @@ -17,7 +17,7 @@ #endif #else #define BUG() do { \ - asm volatile("illegal"); \ + __builtin_trap(); \ } while (0) #endif diff --git a/include/asm-m68k/io.h b/include/asm-m68k/io.h index baf4f9b8acfc327de5da8c759c310c7b43509e66..657187f0c7c2f0ef834817e622c330727d2bcd82 100644 --- a/include/asm-m68k/io.h +++ b/include/asm-m68k/io.h @@ -91,20 +91,20 @@ extern unsigned long gg2_isa_base; #undef MULTI_ISA #endif -#define Q40_ISA (1) -#define GG2_ISA (2) -#define AG_ISA (3) +#define ISA_TYPE_Q40 (1) +#define ISA_TYPE_GG2 (2) +#define ISA_TYPE_AG (3) #if defined(CONFIG_Q40) && !defined(MULTI_ISA) -#define ISA_TYPE Q40_ISA +#define ISA_TYPE ISA_TYPE_Q40 #define ISA_SEX 0 #endif #if defined(CONFIG_AMIGA_PCMCIA) && !defined(MULTI_ISA) -#define ISA_TYPE AG_ISA +#define ISA_TYPE ISA_TYPE_AG #define ISA_SEX 1 #endif #if defined(CONFIG_GG2) && !defined(MULTI_ISA) -#define ISA_TYPE GG2_ISA +#define ISA_TYPE ISA_TYPE_GG2 #define ISA_SEX 0 #endif @@ -126,13 +126,13 @@ static inline u8 __iomem *isa_itb(unsigned long addr) switch(ISA_TYPE) { #ifdef CONFIG_Q40 - case Q40_ISA: return (u8 __iomem *)Q40_ISA_IO_B(addr); + case ISA_TYPE_Q40: return (u8 __iomem *)Q40_ISA_IO_B(addr); #endif #ifdef CONFIG_GG2 - case GG2_ISA: return (u8 __iomem *)GG2_ISA_IO_B(addr); + case ISA_TYPE_GG2: return (u8 __iomem *)GG2_ISA_IO_B(addr); #endif #ifdef CONFIG_AMIGA_PCMCIA - case AG_ISA: return (u8 __iomem *)AG_ISA_IO_B(addr); + case ISA_TYPE_AG: return (u8 __iomem *)AG_ISA_IO_B(addr); #endif default: return NULL; /* avoid warnings, just in case */ } @@ -142,13 +142,13 @@ static inline u16 __iomem *isa_itw(unsigned long addr) switch(ISA_TYPE) { #ifdef CONFIG_Q40 - case Q40_ISA: return (u16 __iomem *)Q40_ISA_IO_W(addr); + case ISA_TYPE_Q40: return (u16 __iomem *)Q40_ISA_IO_W(addr); #endif #ifdef CONFIG_GG2 - case GG2_ISA: return (u16 __iomem *)GG2_ISA_IO_W(addr); + case ISA_TYPE_GG2: return (u16 __iomem *)GG2_ISA_IO_W(addr); #endif #ifdef CONFIG_AMIGA_PCMCIA - case AG_ISA: return (u16 __iomem *)AG_ISA_IO_W(addr); + case ISA_TYPE_AG: return (u16 __iomem *)AG_ISA_IO_W(addr); #endif default: return NULL; /* avoid warnings, just in case */ } @@ -158,7 +158,7 @@ static inline u32 __iomem *isa_itl(unsigned long addr) switch(ISA_TYPE) { #ifdef CONFIG_AMIGA_PCMCIA - case AG_ISA: return (u32 __iomem *)AG_ISA_IO_W(addr); + case ISA_TYPE_AG: return (u32 __iomem *)AG_ISA_IO_W(addr); #endif default: return 0; /* avoid warnings, just in case */ } @@ -168,13 +168,13 @@ static inline u8 __iomem *isa_mtb(unsigned long addr) switch(ISA_TYPE) { #ifdef CONFIG_Q40 - case Q40_ISA: return (u8 __iomem *)Q40_ISA_MEM_B(addr); + case ISA_TYPE_Q40: return (u8 __iomem *)Q40_ISA_MEM_B(addr); #endif #ifdef CONFIG_GG2 - case GG2_ISA: return (u8 __iomem *)GG2_ISA_MEM_B(addr); + case ISA_TYPE_GG2: return (u8 __iomem *)GG2_ISA_MEM_B(addr); #endif #ifdef CONFIG_AMIGA_PCMCIA - case AG_ISA: return (u8 __iomem *)addr; + case ISA_TYPE_AG: return (u8 __iomem *)addr; #endif default: return NULL; /* avoid warnings, just in case */ } @@ -184,13 +184,13 @@ static inline u16 __iomem *isa_mtw(unsigned long addr) switch(ISA_TYPE) { #ifdef CONFIG_Q40 - case Q40_ISA: return (u16 __iomem *)Q40_ISA_MEM_W(addr); + case ISA_TYPE_Q40: return (u16 __iomem *)Q40_ISA_MEM_W(addr); #endif #ifdef CONFIG_GG2 - case GG2_ISA: return (u16 __iomem *)GG2_ISA_MEM_W(addr); + case ISA_TYPE_GG2: return (u16 __iomem *)GG2_ISA_MEM_W(addr); #endif #ifdef CONFIG_AMIGA_PCMCIA - case AG_ISA: return (u16 __iomem *)addr; + case ISA_TYPE_AG: return (u16 __iomem *)addr; #endif default: return NULL; /* avoid warnings, just in case */ } @@ -218,13 +218,13 @@ static inline void isa_delay(void) switch(ISA_TYPE) { #ifdef CONFIG_Q40 - case Q40_ISA: isa_outb(0,0x80); break; + case ISA_TYPE_Q40: isa_outb(0,0x80); break; #endif #ifdef CONFIG_GG2 - case GG2_ISA: break; + case ISA_TYPE_GG2: break; #endif #ifdef CONFIG_AMIGA_PCMCIA - case AG_ISA: break; + case ISA_TYPE_AG: break; #endif default: break; /* avoid warnings */ } diff --git a/include/asm-m68k/setup.h b/include/asm-m68k/setup.h index 2a8853cd655455b1cedbd639e4e8fcd0b146014f..4dfb3952b3753e02b8d0ec2b179ab3bb408ca437 100644 --- a/include/asm-m68k/setup.h +++ b/include/asm-m68k/setup.h @@ -248,7 +248,7 @@ extern unsigned long m68k_machtype; #ifndef __ASSEMBLY__ extern unsigned long m68k_cputype; extern unsigned long m68k_fputype; -extern unsigned long m68k_mmutype; /* Not really used yet */ +extern unsigned long m68k_mmutype; #ifdef CONFIG_VME extern unsigned long vme_brdtype; #endif diff --git a/include/asm-m68k/uaccess.h b/include/asm-m68k/uaccess.h index 5c1264cf0c6507f3dc5dbe3cb3715dd99f647fc0..7107f3fbdbb66885bd000ec206648b5013bbcaf9 100644 --- a/include/asm-m68k/uaccess.h +++ b/include/asm-m68k/uaccess.h @@ -14,7 +14,11 @@ #define VERIFY_WRITE 1 /* We let the MMU do all checking */ -#define access_ok(type,addr,size) 1 +static inline int access_ok(int type, const void __user *addr, + unsigned long size) +{ + return 1; +} /* * The exception table consists of pairs of addresses: the first is the diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h index c2bd126c3b4eda2613c73e26335bb0f8694abd9d..642724734eba3e2dee33fe01cdd7fb12e8648aa9 100644 --- a/include/asm-mips/bitops.h +++ b/include/asm-mips/bitops.h @@ -558,11 +558,13 @@ static inline void __clear_bit_unlock(unsigned long nr, volatile unsigned long * __clear_bit(nr, addr); } +#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) + /* * Return the bit position (0..63) of the most significant 1 bit in a word * Returns -1 if no 1 bit exists */ -static inline int __ilog2(unsigned long x) +static inline unsigned long __fls(unsigned long x) { int lz; @@ -591,13 +593,6 @@ static inline int __ilog2(unsigned long x) return 63 - lz; } -static inline unsigned long __fls(unsigned long x) -{ - return __ilog2(x); -} - -#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) - /* * __ffs - find first bit in word. * @word: The word to search @@ -607,7 +602,7 @@ static inline unsigned long __fls(unsigned long x) */ static inline unsigned long __ffs(unsigned long word) { - return __ilog2(word & -word); + return __fls(word & -word); } /* @@ -654,6 +649,7 @@ static inline int ffs(int word) #else #include +#include #include #include #include diff --git a/include/asm-mips/compiler.h b/include/asm-mips/compiler.h index aa6b876bbd78d153042af014979eea2af04b768a..71f5c5cfc58abbd9b893a90e19dadb132eb93260 100644 --- a/include/asm-mips/compiler.h +++ b/include/asm-mips/compiler.h @@ -9,10 +9,10 @@ #define _ASM_COMPILER_H #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) -#define GCC_IMM_ASM "n" +#define GCC_IMM_ASM() "n" #define GCC_REG_ACCUM "$0" #else -#define GCC_IMM_ASM "rn" +#define GCC_IMM_ASM() "rn" #define GCC_REG_ACCUM "accum" #endif diff --git a/include/asm-mips/mach-au1x00/au1000.h b/include/asm-mips/mach-au1x00/au1000.h index a05555165d05b14192c8ed7f19411a49382dbfbf..363a14ee0ae5d2718435e5db2c57432a684075f6 100644 --- a/include/asm-mips/mach-au1x00/au1000.h +++ b/include/asm-mips/mach-au1x00/au1000.h @@ -40,8 +40,8 @@ #include #include -#include -#include +#include +#include /* cpu pipeline flush */ void static inline au_sync(void) @@ -63,32 +63,32 @@ void static inline au_sync_delay(int ms) void static inline au_writeb(u8 val, unsigned long reg) { - *(volatile u8 *)(reg) = val; + *(volatile u8 *)reg = val; } void static inline au_writew(u16 val, unsigned long reg) { - *(volatile u16 *)(reg) = val; + *(volatile u16 *)reg = val; } void static inline au_writel(u32 val, unsigned long reg) { - *(volatile u32 *)(reg) = val; + *(volatile u32 *)reg = val; } static inline u8 au_readb(unsigned long reg) { - return (*(volatile u8 *)reg); + return *(volatile u8 *)reg; } static inline u16 au_readw(unsigned long reg) { - return (*(volatile u16 *)reg); + return *(volatile u16 *)reg; } static inline u32 au_readl(unsigned long reg) { - return (*(volatile u32 *)reg); + return *(volatile u32 *)reg; } @@ -117,76 +117,77 @@ extern struct au1xxx_irqmap au1xxx_irq_map[]; #endif /* !defined (_LANGUAGE_ASSEMBLY) */ /* - * SDRAM Register Offsets + * SDRAM register offsets */ -#if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1100) -#define MEM_SDMODE0 (0x0000) -#define MEM_SDMODE1 (0x0004) -#define MEM_SDMODE2 (0x0008) -#define MEM_SDADDR0 (0x000C) -#define MEM_SDADDR1 (0x0010) -#define MEM_SDADDR2 (0x0014) -#define MEM_SDREFCFG (0x0018) -#define MEM_SDPRECMD (0x001C) -#define MEM_SDAUTOREF (0x0020) -#define MEM_SDWRMD0 (0x0024) -#define MEM_SDWRMD1 (0x0028) -#define MEM_SDWRMD2 (0x002C) -#define MEM_SDSLEEP (0x0030) -#define MEM_SDSMCKE (0x0034) +#if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1500) || \ + defined(CONFIG_SOC_AU1100) +#define MEM_SDMODE0 0x0000 +#define MEM_SDMODE1 0x0004 +#define MEM_SDMODE2 0x0008 +#define MEM_SDADDR0 0x000C +#define MEM_SDADDR1 0x0010 +#define MEM_SDADDR2 0x0014 +#define MEM_SDREFCFG 0x0018 +#define MEM_SDPRECMD 0x001C +#define MEM_SDAUTOREF 0x0020 +#define MEM_SDWRMD0 0x0024 +#define MEM_SDWRMD1 0x0028 +#define MEM_SDWRMD2 0x002C +#define MEM_SDSLEEP 0x0030 +#define MEM_SDSMCKE 0x0034 /* * MEM_SDMODE register content definitions */ -#define MEM_SDMODE_F (1<<22) -#define MEM_SDMODE_SR (1<<21) -#define MEM_SDMODE_BS (1<<20) -#define MEM_SDMODE_RS (3<<18) -#define MEM_SDMODE_CS (7<<15) -#define MEM_SDMODE_TRAS (15<<11) -#define MEM_SDMODE_TMRD (3<<9) -#define MEM_SDMODE_TWR (3<<7) -#define MEM_SDMODE_TRP (3<<5) -#define MEM_SDMODE_TRCD (3<<3) -#define MEM_SDMODE_TCL (7<<0) - -#define MEM_SDMODE_BS_2Bank (0<<20) -#define MEM_SDMODE_BS_4Bank (1<<20) -#define MEM_SDMODE_RS_11Row (0<<18) -#define MEM_SDMODE_RS_12Row (1<<18) -#define MEM_SDMODE_RS_13Row (2<<18) -#define MEM_SDMODE_RS_N(N) ((N)<<18) -#define MEM_SDMODE_CS_7Col (0<<15) -#define MEM_SDMODE_CS_8Col (1<<15) -#define MEM_SDMODE_CS_9Col (2<<15) -#define MEM_SDMODE_CS_10Col (3<<15) -#define MEM_SDMODE_CS_11Col (4<<15) -#define MEM_SDMODE_CS_N(N) ((N)<<15) -#define MEM_SDMODE_TRAS_N(N) ((N)<<11) -#define MEM_SDMODE_TMRD_N(N) ((N)<<9) -#define MEM_SDMODE_TWR_N(N) ((N)<<7) -#define MEM_SDMODE_TRP_N(N) ((N)<<5) -#define MEM_SDMODE_TRCD_N(N) ((N)<<3) -#define MEM_SDMODE_TCL_N(N) ((N)<<0) +#define MEM_SDMODE_F (1 << 22) +#define MEM_SDMODE_SR (1 << 21) +#define MEM_SDMODE_BS (1 << 20) +#define MEM_SDMODE_RS (3 << 18) +#define MEM_SDMODE_CS (7 << 15) +#define MEM_SDMODE_TRAS (15 << 11) +#define MEM_SDMODE_TMRD (3 << 9) +#define MEM_SDMODE_TWR (3 << 7) +#define MEM_SDMODE_TRP (3 << 5) +#define MEM_SDMODE_TRCD (3 << 3) +#define MEM_SDMODE_TCL (7 << 0) + +#define MEM_SDMODE_BS_2Bank (0 << 20) +#define MEM_SDMODE_BS_4Bank (1 << 20) +#define MEM_SDMODE_RS_11Row (0 << 18) +#define MEM_SDMODE_RS_12Row (1 << 18) +#define MEM_SDMODE_RS_13Row (2 << 18) +#define MEM_SDMODE_RS_N(N) ((N) << 18) +#define MEM_SDMODE_CS_7Col (0 << 15) +#define MEM_SDMODE_CS_8Col (1 << 15) +#define MEM_SDMODE_CS_9Col (2 << 15) +#define MEM_SDMODE_CS_10Col (3 << 15) +#define MEM_SDMODE_CS_11Col (4 << 15) +#define MEM_SDMODE_CS_N(N) ((N) << 15) +#define MEM_SDMODE_TRAS_N(N) ((N) << 11) +#define MEM_SDMODE_TMRD_N(N) ((N) << 9) +#define MEM_SDMODE_TWR_N(N) ((N) << 7) +#define MEM_SDMODE_TRP_N(N) ((N) << 5) +#define MEM_SDMODE_TRCD_N(N) ((N) << 3) +#define MEM_SDMODE_TCL_N(N) ((N) << 0) /* * MEM_SDADDR register contents definitions */ -#define MEM_SDADDR_E (1<<20) -#define MEM_SDADDR_CSBA (0x03FF<<10) -#define MEM_SDADDR_CSMASK (0x03FF<<0) -#define MEM_SDADDR_CSBA_N(N) ((N)&(0x03FF<<22)>>12) -#define MEM_SDADDR_CSMASK_N(N) ((N)&(0x03FF<<22)>>22) +#define MEM_SDADDR_E (1 << 20) +#define MEM_SDADDR_CSBA (0x03FF << 10) +#define MEM_SDADDR_CSMASK (0x03FF << 0) +#define MEM_SDADDR_CSBA_N(N) ((N) & (0x03FF << 22) >> 12) +#define MEM_SDADDR_CSMASK_N(N) ((N)&(0x03FF << 22) >> 22) /* * MEM_SDREFCFG register content definitions */ -#define MEM_SDREFCFG_TRC (15<<28) -#define MEM_SDREFCFG_TRPM (3<<26) -#define MEM_SDREFCFG_E (1<<25) -#define MEM_SDREFCFG_RE (0x1ffffff<<0) -#define MEM_SDREFCFG_TRC_N(N) ((N)<>2)&0x3) -#define MAC_TX_BUFF0_LEN 0x8 -#define MAC_TX_BUFF1_STATUS 0x10 -#define MAC_TX_BUFF1_ADDR 0x14 -#define MAC_TX_BUFF1_LEN 0x18 -#define MAC_TX_BUFF2_STATUS 0x20 -#define MAC_TX_BUFF2_ADDR 0x24 -#define MAC_TX_BUFF2_LEN 0x28 -#define MAC_TX_BUFF3_STATUS 0x30 -#define MAC_TX_BUFF3_ADDR 0x34 -#define MAC_TX_BUFF3_LEN 0x38 - -#define MAC0_RX_DMA_ADDR 0xB4004100 -#define MAC1_RX_DMA_ADDR 0xB4004300 +#define MAC_TX_BUFF0_STATUS 0x0 +# define TX_FRAME_ABORTED (1 << 0) +# define TX_JAB_TIMEOUT (1 << 1) +# define TX_NO_CARRIER (1 << 2) +# define TX_LOSS_CARRIER (1 << 3) +# define TX_EXC_DEF (1 << 4) +# define TX_LATE_COLL_ABORT (1 << 5) +# define TX_EXC_COLL (1 << 6) +# define TX_UNDERRUN (1 << 7) +# define TX_DEFERRED (1 << 8) +# define TX_LATE_COLL (1 << 9) +# define TX_COLL_CNT_MASK (0xF << 10) +# define TX_PKT_RETRY (1 << 31) +#define MAC_TX_BUFF0_ADDR 0x4 +# define TX_DMA_ENABLE (1 << 0) +# define TX_T_DONE (1 << 1) +# define TX_GET_DMA_BUFFER(X) (((X) >> 2) & 0x3) +#define MAC_TX_BUFF0_LEN 0x8 +#define MAC_TX_BUFF1_STATUS 0x10 +#define MAC_TX_BUFF1_ADDR 0x14 +#define MAC_TX_BUFF1_LEN 0x18 +#define MAC_TX_BUFF2_STATUS 0x20 +#define MAC_TX_BUFF2_ADDR 0x24 +#define MAC_TX_BUFF2_LEN 0x28 +#define MAC_TX_BUFF3_STATUS 0x30 +#define MAC_TX_BUFF3_ADDR 0x34 +#define MAC_TX_BUFF3_LEN 0x38 + +#define MAC0_RX_DMA_ADDR 0xB4004100 +#define MAC1_RX_DMA_ADDR 0xB4004300 /* offsets from MAC_RX_RING_ADDR */ -#define MAC_RX_BUFF0_STATUS 0x0 -# define RX_FRAME_LEN_MASK 0x3fff -# define RX_WDOG_TIMER (1<<14) -# define RX_RUNT (1<<15) -# define RX_OVERLEN (1<<16) -# define RX_COLL (1<<17) -# define RX_ETHER (1<<18) -# define RX_MII_ERROR (1<<19) -# define RX_DRIBBLING (1<<20) -# define RX_CRC_ERROR (1<<21) -# define RX_VLAN1 (1<<22) -# define RX_VLAN2 (1<<23) -# define RX_LEN_ERROR (1<<24) -# define RX_CNTRL_FRAME (1<<25) -# define RX_U_CNTRL_FRAME (1<<26) -# define RX_MCAST_FRAME (1<<27) -# define RX_BCAST_FRAME (1<<28) -# define RX_FILTER_FAIL (1<<29) -# define RX_PACKET_FILTER (1<<30) -# define RX_MISSED_FRAME (1<<31) +#define MAC_RX_BUFF0_STATUS 0x0 +# define RX_FRAME_LEN_MASK 0x3fff +# define RX_WDOG_TIMER (1 << 14) +# define RX_RUNT (1 << 15) +# define RX_OVERLEN (1 << 16) +# define RX_COLL (1 << 17) +# define RX_ETHER (1 << 18) +# define RX_MII_ERROR (1 << 19) +# define RX_DRIBBLING (1 << 20) +# define RX_CRC_ERROR (1 << 21) +# define RX_VLAN1 (1 << 22) +# define RX_VLAN2 (1 << 23) +# define RX_LEN_ERROR (1 << 24) +# define RX_CNTRL_FRAME (1 << 25) +# define RX_U_CNTRL_FRAME (1 << 26) +# define RX_MCAST_FRAME (1 << 27) +# define RX_BCAST_FRAME (1 << 28) +# define RX_FILTER_FAIL (1 << 29) +# define RX_PACKET_FILTER (1 << 30) +# define RX_MISSED_FRAME (1 << 31) # define RX_ERROR (RX_WDOG_TIMER | RX_RUNT | RX_OVERLEN | \ - RX_COLL | RX_MII_ERROR | RX_CRC_ERROR | \ - RX_LEN_ERROR | RX_U_CNTRL_FRAME | RX_MISSED_FRAME) -#define MAC_RX_BUFF0_ADDR 0x4 -# define RX_DMA_ENABLE (1<<0) -# define RX_T_DONE (1<<1) -# define RX_GET_DMA_BUFFER(X) (((X)>>2)&0x3) -# define RX_SET_BUFF_ADDR(X) ((X)&0xffffffc0) -#define MAC_RX_BUFF1_STATUS 0x10 -#define MAC_RX_BUFF1_ADDR 0x14 -#define MAC_RX_BUFF2_STATUS 0x20 -#define MAC_RX_BUFF2_ADDR 0x24 -#define MAC_RX_BUFF3_STATUS 0x30 -#define MAC_RX_BUFF3_ADDR 0x34 - + RX_COLL | RX_MII_ERROR | RX_CRC_ERROR | \ + RX_LEN_ERROR | RX_U_CNTRL_FRAME | RX_MISSED_FRAME) +#define MAC_RX_BUFF0_ADDR 0x4 +# define RX_DMA_ENABLE (1 << 0) +# define RX_T_DONE (1 << 1) +# define RX_GET_DMA_BUFFER(X) (((X) >> 2) & 0x3) +# define RX_SET_BUFF_ADDR(X) ((X) & 0xffffffc0) +#define MAC_RX_BUFF1_STATUS 0x10 +#define MAC_RX_BUFF1_ADDR 0x14 +#define MAC_RX_BUFF2_STATUS 0x20 +#define MAC_RX_BUFF2_ADDR 0x24 +#define MAC_RX_BUFF3_STATUS 0x30 +#define MAC_RX_BUFF3_ADDR 0x34 /* UARTS 0-3 */ -#define UART_BASE UART0_ADDR +#define UART_BASE UART0_ADDR #ifdef CONFIG_SOC_AU1200 -#define UART_DEBUG_BASE UART1_ADDR +#define UART_DEBUG_BASE UART1_ADDR #else -#define UART_DEBUG_BASE UART3_ADDR +#define UART_DEBUG_BASE UART3_ADDR #endif #define UART_RX 0 /* Receive buffer */ @@ -1294,341 +1293,337 @@ enum soc_au1200_ints { #define UART_MSR_DCTS 0x01 /* Delta CTS */ #define UART_MSR_ANY_DELTA 0x0F /* Any of the delta bits! */ - - /* SSIO */ -#define SSI0_STATUS 0xB1600000 -# define SSI_STATUS_BF (1<<4) -# define SSI_STATUS_OF (1<<3) -# define SSI_STATUS_UF (1<<2) -# define SSI_STATUS_D (1<<1) -# define SSI_STATUS_B (1<<0) -#define SSI0_INT 0xB1600004 -# define SSI_INT_OI (1<<3) -# define SSI_INT_UI (1<<2) -# define SSI_INT_DI (1<<1) -#define SSI0_INT_ENABLE 0xB1600008 -# define SSI_INTE_OIE (1<<3) -# define SSI_INTE_UIE (1<<2) -# define SSI_INTE_DIE (1<<1) -#define SSI0_CONFIG 0xB1600020 -# define SSI_CONFIG_AO (1<<24) -# define SSI_CONFIG_DO (1<<23) -# define SSI_CONFIG_ALEN_BIT 20 -# define SSI_CONFIG_ALEN_MASK (0x7<<20) -# define SSI_CONFIG_DLEN_BIT 16 -# define SSI_CONFIG_DLEN_MASK (0x7<<16) -# define SSI_CONFIG_DD (1<<11) -# define SSI_CONFIG_AD (1<<10) -# define SSI_CONFIG_BM_BIT 8 -# define SSI_CONFIG_BM_MASK (0x3<<8) -# define SSI_CONFIG_CE (1<<7) -# define SSI_CONFIG_DP (1<<6) -# define SSI_CONFIG_DL (1<<5) -# define SSI_CONFIG_EP (1<<4) -#define SSI0_ADATA 0xB1600024 -# define SSI_AD_D (1<<24) -# define SSI_AD_ADDR_BIT 16 -# define SSI_AD_ADDR_MASK (0xff<<16) -# define SSI_AD_DATA_BIT 0 -# define SSI_AD_DATA_MASK (0xfff<<0) -#define SSI0_CLKDIV 0xB1600028 -#define SSI0_CONTROL 0xB1600100 -# define SSI_CONTROL_CD (1<<1) -# define SSI_CONTROL_E (1<<0) +#define SSI0_STATUS 0xB1600000 +# define SSI_STATUS_BF (1 << 4) +# define SSI_STATUS_OF (1 << 3) +# define SSI_STATUS_UF (1 << 2) +# define SSI_STATUS_D (1 << 1) +# define SSI_STATUS_B (1 << 0) +#define SSI0_INT 0xB1600004 +# define SSI_INT_OI (1 << 3) +# define SSI_INT_UI (1 << 2) +# define SSI_INT_DI (1 << 1) +#define SSI0_INT_ENABLE 0xB1600008 +# define SSI_INTE_OIE (1 << 3) +# define SSI_INTE_UIE (1 << 2) +# define SSI_INTE_DIE (1 << 1) +#define SSI0_CONFIG 0xB1600020 +# define SSI_CONFIG_AO (1 << 24) +# define SSI_CONFIG_DO (1 << 23) +# define SSI_CONFIG_ALEN_BIT 20 +# define SSI_CONFIG_ALEN_MASK (0x7 << 20) +# define SSI_CONFIG_DLEN_BIT 16 +# define SSI_CONFIG_DLEN_MASK (0x7 << 16) +# define SSI_CONFIG_DD (1 << 11) +# define SSI_CONFIG_AD (1 << 10) +# define SSI_CONFIG_BM_BIT 8 +# define SSI_CONFIG_BM_MASK (0x3 << 8) +# define SSI_CONFIG_CE (1 << 7) +# define SSI_CONFIG_DP (1 << 6) +# define SSI_CONFIG_DL (1 << 5) +# define SSI_CONFIG_EP (1 << 4) +#define SSI0_ADATA 0xB1600024 +# define SSI_AD_D (1 << 24) +# define SSI_AD_ADDR_BIT 16 +# define SSI_AD_ADDR_MASK (0xff << 16) +# define SSI_AD_DATA_BIT 0 +# define SSI_AD_DATA_MASK (0xfff << 0) +#define SSI0_CLKDIV 0xB1600028 +#define SSI0_CONTROL 0xB1600100 +# define SSI_CONTROL_CD (1 << 1) +# define SSI_CONTROL_E (1 << 0) /* SSI1 */ -#define SSI1_STATUS 0xB1680000 -#define SSI1_INT 0xB1680004 -#define SSI1_INT_ENABLE 0xB1680008 -#define SSI1_CONFIG 0xB1680020 -#define SSI1_ADATA 0xB1680024 -#define SSI1_CLKDIV 0xB1680028 -#define SSI1_ENABLE 0xB1680100 +#define SSI1_STATUS 0xB1680000 +#define SSI1_INT 0xB1680004 +#define SSI1_INT_ENABLE 0xB1680008 +#define SSI1_CONFIG 0xB1680020 +#define SSI1_ADATA 0xB1680024 +#define SSI1_CLKDIV 0xB1680028 +#define SSI1_ENABLE 0xB1680100 /* * Register content definitions */ -#define SSI_STATUS_BF (1<<4) -#define SSI_STATUS_OF (1<<3) -#define SSI_STATUS_UF (1<<2) -#define SSI_STATUS_D (1<<1) -#define SSI_STATUS_B (1<<0) +#define SSI_STATUS_BF (1 << 4) +#define SSI_STATUS_OF (1 << 3) +#define SSI_STATUS_UF (1 << 2) +#define SSI_STATUS_D (1 << 1) +#define SSI_STATUS_B (1 << 0) /* SSI_INT */ -#define SSI_INT_OI (1<<3) -#define SSI_INT_UI (1<<2) -#define SSI_INT_DI (1<<1) +#define SSI_INT_OI (1 << 3) +#define SSI_INT_UI (1 << 2) +#define SSI_INT_DI (1 << 1) /* SSI_INTEN */ -#define SSI_INTEN_OIE (1<<3) -#define SSI_INTEN_UIE (1<<2) -#define SSI_INTEN_DIE (1<<1) - -#define SSI_CONFIG_AO (1<<24) -#define SSI_CONFIG_DO (1<<23) -#define SSI_CONFIG_ALEN (7<<20) -#define SSI_CONFIG_DLEN (15<<16) -#define SSI_CONFIG_DD (1<<11) -#define SSI_CONFIG_AD (1<<10) -#define SSI_CONFIG_BM (3<<8) -#define SSI_CONFIG_CE (1<<7) -#define SSI_CONFIG_DP (1<<6) -#define SSI_CONFIG_DL (1<<5) -#define SSI_CONFIG_EP (1<<4) -#define SSI_CONFIG_ALEN_N(N) ((N-1)<<20) -#define SSI_CONFIG_DLEN_N(N) ((N-1)<<16) -#define SSI_CONFIG_BM_HI (0<<8) -#define SSI_CONFIG_BM_LO (1<<8) -#define SSI_CONFIG_BM_CY (2<<8) - -#define SSI_ADATA_D (1<<24) -#define SSI_ADATA_ADDR (0xFF<<16) -#define SSI_ADATA_DATA (0x0FFF) -#define SSI_ADATA_ADDR_N(N) (N<<16) - -#define SSI_ENABLE_CD (1<<1) -#define SSI_ENABLE_E (1<<0) - +#define SSI_INTEN_OIE (1 << 3) +#define SSI_INTEN_UIE (1 << 2) +#define SSI_INTEN_DIE (1 << 1) + +#define SSI_CONFIG_AO (1 << 24) +#define SSI_CONFIG_DO (1 << 23) +#define SSI_CONFIG_ALEN (7 << 20) +#define SSI_CONFIG_DLEN (15 << 16) +#define SSI_CONFIG_DD (1 << 11) +#define SSI_CONFIG_AD (1 << 10) +#define SSI_CONFIG_BM (3 << 8) +#define SSI_CONFIG_CE (1 << 7) +#define SSI_CONFIG_DP (1 << 6) +#define SSI_CONFIG_DL (1 << 5) +#define SSI_CONFIG_EP (1 << 4) +#define SSI_CONFIG_ALEN_N(N) ((N-1) << 20) +#define SSI_CONFIG_DLEN_N(N) ((N-1) << 16) +#define SSI_CONFIG_BM_HI (0 << 8) +#define SSI_CONFIG_BM_LO (1 << 8) +#define SSI_CONFIG_BM_CY (2 << 8) + +#define SSI_ADATA_D (1 << 24) +#define SSI_ADATA_ADDR (0xFF << 16) +#define SSI_ADATA_DATA 0x0FFF +#define SSI_ADATA_ADDR_N(N) (N << 16) + +#define SSI_ENABLE_CD (1 << 1) +#define SSI_ENABLE_E (1 << 0) /* IrDA Controller */ -#define IRDA_BASE 0xB0300000 -#define IR_RING_PTR_STATUS (IRDA_BASE+0x00) -#define IR_RING_BASE_ADDR_H (IRDA_BASE+0x04) -#define IR_RING_BASE_ADDR_L (IRDA_BASE+0x08) -#define IR_RING_SIZE (IRDA_BASE+0x0C) -#define IR_RING_PROMPT (IRDA_BASE+0x10) -#define IR_RING_ADDR_CMPR (IRDA_BASE+0x14) -#define IR_INT_CLEAR (IRDA_BASE+0x18) -#define IR_CONFIG_1 (IRDA_BASE+0x20) -# define IR_RX_INVERT_LED (1<<0) -# define IR_TX_INVERT_LED (1<<1) -# define IR_ST (1<<2) -# define IR_SF (1<<3) -# define IR_SIR (1<<4) -# define IR_MIR (1<<5) -# define IR_FIR (1<<6) -# define IR_16CRC (1<<7) -# define IR_TD (1<<8) -# define IR_RX_ALL (1<<9) -# define IR_DMA_ENABLE (1<<10) -# define IR_RX_ENABLE (1<<11) -# define IR_TX_ENABLE (1<<12) -# define IR_LOOPBACK (1<<14) -# define IR_SIR_MODE (IR_SIR | IR_DMA_ENABLE | \ - IR_RX_ALL | IR_RX_ENABLE | IR_SF | IR_16CRC) -#define IR_SIR_FLAGS (IRDA_BASE+0x24) -#define IR_ENABLE (IRDA_BASE+0x28) -# define IR_RX_STATUS (1<<9) -# define IR_TX_STATUS (1<<10) -#define IR_READ_PHY_CONFIG (IRDA_BASE+0x2C) -#define IR_WRITE_PHY_CONFIG (IRDA_BASE+0x30) -#define IR_MAX_PKT_LEN (IRDA_BASE+0x34) -#define IR_RX_BYTE_CNT (IRDA_BASE+0x38) -#define IR_CONFIG_2 (IRDA_BASE+0x3C) -# define IR_MODE_INV (1<<0) -# define IR_ONE_PIN (1<<1) -#define IR_INTERFACE_CONFIG (IRDA_BASE+0x40) +#define IRDA_BASE 0xB0300000 +#define IR_RING_PTR_STATUS (IRDA_BASE + 0x00) +#define IR_RING_BASE_ADDR_H (IRDA_BASE + 0x04) +#define IR_RING_BASE_ADDR_L (IRDA_BASE + 0x08) +#define IR_RING_SIZE (IRDA_BASE + 0x0C) +#define IR_RING_PROMPT (IRDA_BASE + 0x10) +#define IR_RING_ADDR_CMPR (IRDA_BASE + 0x14) +#define IR_INT_CLEAR (IRDA_BASE + 0x18) +#define IR_CONFIG_1 (IRDA_BASE + 0x20) +# define IR_RX_INVERT_LED (1 << 0) +# define IR_TX_INVERT_LED (1 << 1) +# define IR_ST (1 << 2) +# define IR_SF (1 << 3) +# define IR_SIR (1 << 4) +# define IR_MIR (1 << 5) +# define IR_FIR (1 << 6) +# define IR_16CRC (1 << 7) +# define IR_TD (1 << 8) +# define IR_RX_ALL (1 << 9) +# define IR_DMA_ENABLE (1 << 10) +# define IR_RX_ENABLE (1 << 11) +# define IR_TX_ENABLE (1 << 12) +# define IR_LOOPBACK (1 << 14) +# define IR_SIR_MODE (IR_SIR | IR_DMA_ENABLE | \ + IR_RX_ALL | IR_RX_ENABLE | IR_SF | IR_16CRC) +#define IR_SIR_FLAGS (IRDA_BASE + 0x24) +#define IR_ENABLE (IRDA_BASE + 0x28) +# define IR_RX_STATUS (1 << 9) +# define IR_TX_STATUS (1 << 10) +#define IR_READ_PHY_CONFIG (IRDA_BASE + 0x2C) +#define IR_WRITE_PHY_CONFIG (IRDA_BASE + 0x30) +#define IR_MAX_PKT_LEN (IRDA_BASE + 0x34) +#define IR_RX_BYTE_CNT (IRDA_BASE + 0x38) +#define IR_CONFIG_2 (IRDA_BASE + 0x3C) +# define IR_MODE_INV (1 << 0) +# define IR_ONE_PIN (1 << 1) +#define IR_INTERFACE_CONFIG (IRDA_BASE + 0x40) /* GPIO */ -#define SYS_PINFUNC 0xB190002C -# define SYS_PF_USB (1<<15) /* 2nd USB device/host */ -# define SYS_PF_U3 (1<<14) /* GPIO23/U3TXD */ -# define SYS_PF_U2 (1<<13) /* GPIO22/U2TXD */ -# define SYS_PF_U1 (1<<12) /* GPIO21/U1TXD */ -# define SYS_PF_SRC (1<<11) /* GPIO6/SROMCKE */ -# define SYS_PF_CK5 (1<<10) /* GPIO3/CLK5 */ -# define SYS_PF_CK4 (1<<9) /* GPIO2/CLK4 */ -# define SYS_PF_IRF (1<<8) /* GPIO15/IRFIRSEL */ -# define SYS_PF_UR3 (1<<7) /* GPIO[14:9]/UART3 */ -# define SYS_PF_I2D (1<<6) /* GPIO8/I2SDI */ -# define SYS_PF_I2S (1<<5) /* I2S/GPIO[29:31] */ -# define SYS_PF_NI2 (1<<4) /* NI2/GPIO[24:28] */ -# define SYS_PF_U0 (1<<3) /* U0TXD/GPIO20 */ -# define SYS_PF_RD (1<<2) /* IRTXD/GPIO19 */ -# define SYS_PF_A97 (1<<1) /* AC97/SSL1 */ -# define SYS_PF_S0 (1<<0) /* SSI_0/GPIO[16:18] */ - -/* Au1100 Only */ -# define SYS_PF_PC (1<<18) /* PCMCIA/GPIO[207:204] */ -# define SYS_PF_LCD (1<<17) /* extern lcd/GPIO[203:200] */ -# define SYS_PF_CS (1<<16) /* EXTCLK0/32khz to gpio2 */ -# define SYS_PF_EX0 (1<<9) /* gpio2/clock */ - -/* Au1550 Only. Redefines lots of pins */ -# define SYS_PF_PSC2_MASK (7 << 17) -# define SYS_PF_PSC2_AC97 (0) -# define SYS_PF_PSC2_SPI (0) -# define SYS_PF_PSC2_I2S (1 << 17) -# define SYS_PF_PSC2_SMBUS (3 << 17) -# define SYS_PF_PSC2_GPIO (7 << 17) -# define SYS_PF_PSC3_MASK (7 << 20) -# define SYS_PF_PSC3_AC97 (0) -# define SYS_PF_PSC3_SPI (0) -# define SYS_PF_PSC3_I2S (1 << 20) -# define SYS_PF_PSC3_SMBUS (3 << 20) -# define SYS_PF_PSC3_GPIO (7 << 20) -# define SYS_PF_PSC1_S1 (1 << 1) -# define SYS_PF_MUST_BE_SET ((1 << 5) | (1 << 2)) - -/* Au1200 Only */ +#define SYS_PINFUNC 0xB190002C +# define SYS_PF_USB (1 << 15) /* 2nd USB device/host */ +# define SYS_PF_U3 (1 << 14) /* GPIO23/U3TXD */ +# define SYS_PF_U2 (1 << 13) /* GPIO22/U2TXD */ +# define SYS_PF_U1 (1 << 12) /* GPIO21/U1TXD */ +# define SYS_PF_SRC (1 << 11) /* GPIO6/SROMCKE */ +# define SYS_PF_CK5 (1 << 10) /* GPIO3/CLK5 */ +# define SYS_PF_CK4 (1 << 9) /* GPIO2/CLK4 */ +# define SYS_PF_IRF (1 << 8) /* GPIO15/IRFIRSEL */ +# define SYS_PF_UR3 (1 << 7) /* GPIO[14:9]/UART3 */ +# define SYS_PF_I2D (1 << 6) /* GPIO8/I2SDI */ +# define SYS_PF_I2S (1 << 5) /* I2S/GPIO[29:31] */ +# define SYS_PF_NI2 (1 << 4) /* NI2/GPIO[24:28] */ +# define SYS_PF_U0 (1 << 3) /* U0TXD/GPIO20 */ +# define SYS_PF_RD (1 << 2) /* IRTXD/GPIO19 */ +# define SYS_PF_A97 (1 << 1) /* AC97/SSL1 */ +# define SYS_PF_S0 (1 << 0) /* SSI_0/GPIO[16:18] */ + +/* Au1100 only */ +# define SYS_PF_PC (1 << 18) /* PCMCIA/GPIO[207:204] */ +# define SYS_PF_LCD (1 << 17) /* extern lcd/GPIO[203:200] */ +# define SYS_PF_CS (1 << 16) /* EXTCLK0/32KHz to gpio2 */ +# define SYS_PF_EX0 (1 << 9) /* GPIO2/clock */ + +/* Au1550 only. Redefines lots of pins */ +# define SYS_PF_PSC2_MASK (7 << 17) +# define SYS_PF_PSC2_AC97 0 +# define SYS_PF_PSC2_SPI 0 +# define SYS_PF_PSC2_I2S (1 << 17) +# define SYS_PF_PSC2_SMBUS (3 << 17) +# define SYS_PF_PSC2_GPIO (7 << 17) +# define SYS_PF_PSC3_MASK (7 << 20) +# define SYS_PF_PSC3_AC97 0 +# define SYS_PF_PSC3_SPI 0 +# define SYS_PF_PSC3_I2S (1 << 20) +# define SYS_PF_PSC3_SMBUS (3 << 20) +# define SYS_PF_PSC3_GPIO (7 << 20) +# define SYS_PF_PSC1_S1 (1 << 1) +# define SYS_PF_MUST_BE_SET ((1 << 5) | (1 << 2)) + +/* Au1200 only */ #ifdef CONFIG_SOC_AU1200 -#define SYS_PINFUNC_DMA (1<<31) -#define SYS_PINFUNC_S0A (1<<30) -#define SYS_PINFUNC_S1A (1<<29) -#define SYS_PINFUNC_LP0 (1<<28) -#define SYS_PINFUNC_LP1 (1<<27) -#define SYS_PINFUNC_LD16 (1<<26) -#define SYS_PINFUNC_LD8 (1<<25) -#define SYS_PINFUNC_LD1 (1<<24) -#define SYS_PINFUNC_LD0 (1<<23) -#define SYS_PINFUNC_P1A (3<<21) -#define SYS_PINFUNC_P1B (1<<20) -#define SYS_PINFUNC_FS3 (1<<19) -#define SYS_PINFUNC_P0A (3<<17) -#define SYS_PINFUNC_CS (1<<16) -#define SYS_PINFUNC_CIM (1<<15) -#define SYS_PINFUNC_P1C (1<<14) -#define SYS_PINFUNC_U1T (1<<12) -#define SYS_PINFUNC_U1R (1<<11) -#define SYS_PINFUNC_EX1 (1<<10) -#define SYS_PINFUNC_EX0 (1<<9) -#define SYS_PINFUNC_U0R (1<<8) -#define SYS_PINFUNC_MC (1<<7) -#define SYS_PINFUNC_S0B (1<<6) -#define SYS_PINFUNC_S0C (1<<5) -#define SYS_PINFUNC_P0B (1<<4) -#define SYS_PINFUNC_U0T (1<<3) -#define SYS_PINFUNC_S1B (1<<2) +#define SYS_PINFUNC_DMA (1 << 31) +#define SYS_PINFUNC_S0A (1 << 30) +#define SYS_PINFUNC_S1A (1 << 29) +#define SYS_PINFUNC_LP0 (1 << 28) +#define SYS_PINFUNC_LP1 (1 << 27) +#define SYS_PINFUNC_LD16 (1 << 26) +#define SYS_PINFUNC_LD8 (1 << 25) +#define SYS_PINFUNC_LD1 (1 << 24) +#define SYS_PINFUNC_LD0 (1 << 23) +#define SYS_PINFUNC_P1A (3 << 21) +#define SYS_PINFUNC_P1B (1 << 20) +#define SYS_PINFUNC_FS3 (1 << 19) +#define SYS_PINFUNC_P0A (3 << 17) +#define SYS_PINFUNC_CS (1 << 16) +#define SYS_PINFUNC_CIM (1 << 15) +#define SYS_PINFUNC_P1C (1 << 14) +#define SYS_PINFUNC_U1T (1 << 12) +#define SYS_PINFUNC_U1R (1 << 11) +#define SYS_PINFUNC_EX1 (1 << 10) +#define SYS_PINFUNC_EX0 (1 << 9) +#define SYS_PINFUNC_U0R (1 << 8) +#define SYS_PINFUNC_MC (1 << 7) +#define SYS_PINFUNC_S0B (1 << 6) +#define SYS_PINFUNC_S0C (1 << 5) +#define SYS_PINFUNC_P0B (1 << 4) +#define SYS_PINFUNC_U0T (1 << 3) +#define SYS_PINFUNC_S1B (1 << 2) #endif -#define SYS_TRIOUTRD 0xB1900100 -#define SYS_TRIOUTCLR 0xB1900100 -#define SYS_OUTPUTRD 0xB1900108 -#define SYS_OUTPUTSET 0xB1900108 -#define SYS_OUTPUTCLR 0xB190010C -#define SYS_PINSTATERD 0xB1900110 -#define SYS_PININPUTEN 0xB1900110 +#define SYS_TRIOUTRD 0xB1900100 +#define SYS_TRIOUTCLR 0xB1900100 +#define SYS_OUTPUTRD 0xB1900108 +#define SYS_OUTPUTSET 0xB1900108 +#define SYS_OUTPUTCLR 0xB190010C +#define SYS_PINSTATERD 0xB1900110 +#define SYS_PININPUTEN 0xB1900110 /* GPIO2, Au1500, Au1550 only */ -#define GPIO2_BASE 0xB1700000 -#define GPIO2_DIR (GPIO2_BASE + 0) -#define GPIO2_OUTPUT (GPIO2_BASE + 8) -#define GPIO2_PINSTATE (GPIO2_BASE + 0xC) -#define GPIO2_INTENABLE (GPIO2_BASE + 0x10) -#define GPIO2_ENABLE (GPIO2_BASE + 0x14) +#define GPIO2_BASE 0xB1700000 +#define GPIO2_DIR (GPIO2_BASE + 0) +#define GPIO2_OUTPUT (GPIO2_BASE + 8) +#define GPIO2_PINSTATE (GPIO2_BASE + 0xC) +#define GPIO2_INTENABLE (GPIO2_BASE + 0x10) +#define GPIO2_ENABLE (GPIO2_BASE + 0x14) /* Power Management */ -#define SYS_SCRATCH0 0xB1900018 -#define SYS_SCRATCH1 0xB190001C -#define SYS_WAKEMSK 0xB1900034 -#define SYS_ENDIAN 0xB1900038 -#define SYS_POWERCTRL 0xB190003C -#define SYS_WAKESRC 0xB190005C -#define SYS_SLPPWR 0xB1900078 -#define SYS_SLEEP 0xB190007C +#define SYS_SCRATCH0 0xB1900018 +#define SYS_SCRATCH1 0xB190001C +#define SYS_WAKEMSK 0xB1900034 +#define SYS_ENDIAN 0xB1900038 +#define SYS_POWERCTRL 0xB190003C +#define SYS_WAKESRC 0xB190005C +#define SYS_SLPPWR 0xB1900078 +#define SYS_SLEEP 0xB190007C /* Clock Controller */ -#define SYS_FREQCTRL0 0xB1900020 -# define SYS_FC_FRDIV2_BIT 22 -# define SYS_FC_FRDIV2_MASK (0xff << SYS_FC_FRDIV2_BIT) -# define SYS_FC_FE2 (1<<21) -# define SYS_FC_FS2 (1<<20) -# define SYS_FC_FRDIV1_BIT 12 -# define SYS_FC_FRDIV1_MASK (0xff << SYS_FC_FRDIV1_BIT) -# define SYS_FC_FE1 (1<<11) -# define SYS_FC_FS1 (1<<10) -# define SYS_FC_FRDIV0_BIT 2 -# define SYS_FC_FRDIV0_MASK (0xff << SYS_FC_FRDIV0_BIT) -# define SYS_FC_FE0 (1<<1) -# define SYS_FC_FS0 (1<<0) -#define SYS_FREQCTRL1 0xB1900024 -# define SYS_FC_FRDIV5_BIT 22 -# define SYS_FC_FRDIV5_MASK (0xff << SYS_FC_FRDIV5_BIT) -# define SYS_FC_FE5 (1<<21) -# define SYS_FC_FS5 (1<<20) -# define SYS_FC_FRDIV4_BIT 12 -# define SYS_FC_FRDIV4_MASK (0xff << SYS_FC_FRDIV4_BIT) -# define SYS_FC_FE4 (1<<11) -# define SYS_FC_FS4 (1<<10) -# define SYS_FC_FRDIV3_BIT 2 -# define SYS_FC_FRDIV3_MASK (0xff << SYS_FC_FRDIV3_BIT) -# define SYS_FC_FE3 (1<<1) -# define SYS_FC_FS3 (1<<0) -#define SYS_CLKSRC 0xB1900028 -# define SYS_CS_ME1_BIT 27 -# define SYS_CS_ME1_MASK (0x7< * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -31,7 +30,7 @@ #ifndef __ASM_AU1000_DMA_H #define __ASM_AU1000_DMA_H -#include /* need byte IO */ +#include /* need byte IO */ #include /* And spinlocks */ #include #include @@ -50,36 +49,36 @@ #define DMA_DAH_MASK (0x0f << 20) #define DMA_DID_BIT 16 #define DMA_DID_MASK (0x0f << DMA_DID_BIT) -#define DMA_DS (1<<15) -#define DMA_BE (1<<13) -#define DMA_DR (1<<12) -#define DMA_TS8 (1<<11) +#define DMA_DS (1 << 15) +#define DMA_BE (1 << 13) +#define DMA_DR (1 << 12) +#define DMA_TS8 (1 << 11) #define DMA_DW_BIT 9 #define DMA_DW_MASK (0x03 << DMA_DW_BIT) #define DMA_DW8 (0 << DMA_DW_BIT) #define DMA_DW16 (1 << DMA_DW_BIT) #define DMA_DW32 (2 << DMA_DW_BIT) -#define DMA_NC (1<<8) -#define DMA_IE (1<<7) -#define DMA_HALT (1<<6) -#define DMA_GO (1<<5) -#define DMA_AB (1<<4) -#define DMA_D1 (1<<3) -#define DMA_BE1 (1<<2) -#define DMA_D0 (1<<1) -#define DMA_BE0 (1<<0) - -#define DMA_PERIPHERAL_ADDR 0x00000008 -#define DMA_BUFFER0_START 0x0000000C -#define DMA_BUFFER1_START 0x00000014 -#define DMA_BUFFER0_COUNT 0x00000010 -#define DMA_BUFFER1_COUNT 0x00000018 -#define DMA_BAH_BIT 16 -#define DMA_BAH_MASK (0x0f << DMA_BAH_BIT) -#define DMA_COUNT_BIT 0 -#define DMA_COUNT_MASK (0xffff << DMA_COUNT_BIT) - -/* DMA Device ID's follow */ +#define DMA_NC (1 << 8) +#define DMA_IE (1 << 7) +#define DMA_HALT (1 << 6) +#define DMA_GO (1 << 5) +#define DMA_AB (1 << 4) +#define DMA_D1 (1 << 3) +#define DMA_BE1 (1 << 2) +#define DMA_D0 (1 << 1) +#define DMA_BE0 (1 << 0) + +#define DMA_PERIPHERAL_ADDR 0x00000008 +#define DMA_BUFFER0_START 0x0000000C +#define DMA_BUFFER1_START 0x00000014 +#define DMA_BUFFER0_COUNT 0x00000010 +#define DMA_BUFFER1_COUNT 0x00000018 +#define DMA_BAH_BIT 16 +#define DMA_BAH_MASK (0x0f << DMA_BAH_BIT) +#define DMA_COUNT_BIT 0 +#define DMA_COUNT_MASK (0xffff << DMA_COUNT_BIT) + +/* DMA Device IDs follow */ enum { DMA_ID_UART0_TX = 0, DMA_ID_UART0_RX, @@ -110,7 +109,8 @@ enum { }; struct dma_chan { - int dev_id; // this channel is allocated if >=0, free otherwise + int dev_id; /* this channel is allocated if >= 0, */ + /* free otherwise */ unsigned int io; const char *dev_str; int irq; @@ -132,23 +132,23 @@ extern int au1000_dma_read_proc(char *buf, char **start, off_t fpos, extern void dump_au1000_dma_channel(unsigned int dmanr); extern spinlock_t au1000_dma_spin_lock; - -static __inline__ struct dma_chan *get_dma_chan(unsigned int dmanr) +static inline struct dma_chan *get_dma_chan(unsigned int dmanr) { - if (dmanr >= NUM_AU1000_DMA_CHANNELS - || au1000_dma_table[dmanr].dev_id < 0) + if (dmanr >= NUM_AU1000_DMA_CHANNELS || + au1000_dma_table[dmanr].dev_id < 0) return NULL; return &au1000_dma_table[dmanr]; } -static __inline__ unsigned long claim_dma_lock(void) +static inline unsigned long claim_dma_lock(void) { unsigned long flags; + spin_lock_irqsave(&au1000_dma_spin_lock, flags); return flags; } -static __inline__ void release_dma_lock(unsigned long flags) +static inline void release_dma_lock(unsigned long flags) { spin_unlock_irqrestore(&au1000_dma_spin_lock, flags); } @@ -156,48 +156,53 @@ static __inline__ void release_dma_lock(unsigned long flags) /* * Set the DMA buffer enable bits in the mode register. */ -static __inline__ void enable_dma_buffer0(unsigned int dmanr) +static inline void enable_dma_buffer0(unsigned int dmanr) { struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) return; au_writel(DMA_BE0, chan->io + DMA_MODE_SET); } -static __inline__ void enable_dma_buffer1(unsigned int dmanr) + +static inline void enable_dma_buffer1(unsigned int dmanr) { struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) return; au_writel(DMA_BE1, chan->io + DMA_MODE_SET); } -static __inline__ void enable_dma_buffers(unsigned int dmanr) +static inline void enable_dma_buffers(unsigned int dmanr) { struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) return; au_writel(DMA_BE0 | DMA_BE1, chan->io + DMA_MODE_SET); } -static __inline__ void start_dma(unsigned int dmanr) +static inline void start_dma(unsigned int dmanr) { struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) return; - au_writel(DMA_GO, chan->io + DMA_MODE_SET); } #define DMA_HALT_POLL 0x5000 -static __inline__ void halt_dma(unsigned int dmanr) +static inline void halt_dma(unsigned int dmanr) { struct dma_chan *chan = get_dma_chan(dmanr); int i; + if (!chan) return; - au_writel(DMA_GO, chan->io + DMA_MODE_CLEAR); - // poll the halt bit + + /* Poll the halt bit */ for (i = 0; i < DMA_HALT_POLL; i++) if (au_readl(chan->io + DMA_MODE_READ) & DMA_HALT) break; @@ -205,55 +210,57 @@ static __inline__ void halt_dma(unsigned int dmanr) printk(KERN_INFO "halt_dma: HALT poll expired!\n"); } - -static __inline__ void disable_dma(unsigned int dmanr) +static inline void disable_dma(unsigned int dmanr) { struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) return; halt_dma(dmanr); - // now we can disable the buffers + /* Now we can disable the buffers */ au_writel(~DMA_GO, chan->io + DMA_MODE_CLEAR); } -static __inline__ int dma_halted(unsigned int dmanr) +static inline int dma_halted(unsigned int dmanr) { struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) return 1; return (au_readl(chan->io + DMA_MODE_READ) & DMA_HALT) ? 1 : 0; } -/* initialize a DMA channel */ -static __inline__ void init_dma(unsigned int dmanr) +/* Initialize a DMA channel. */ +static inline void init_dma(unsigned int dmanr) { struct dma_chan *chan = get_dma_chan(dmanr); u32 mode; + if (!chan) return; disable_dma(dmanr); - // set device FIFO address - au_writel(CPHYSADDR(chan->fifo_addr), - chan->io + DMA_PERIPHERAL_ADDR); + /* Set device FIFO address */ + au_writel(CPHYSADDR(chan->fifo_addr), chan->io + DMA_PERIPHERAL_ADDR); mode = chan->mode | (chan->dev_id << DMA_DID_BIT); if (chan->irq) mode |= DMA_IE; au_writel(~mode, chan->io + DMA_MODE_CLEAR); - au_writel(mode, chan->io + DMA_MODE_SET); + au_writel(mode, chan->io + DMA_MODE_SET); } /* - * set mode for a specific DMA channel + * Set mode for a specific DMA channel */ -static __inline__ void set_dma_mode(unsigned int dmanr, unsigned int mode) +static inline void set_dma_mode(unsigned int dmanr, unsigned int mode) { struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) return; /* @@ -266,36 +273,37 @@ static __inline__ void set_dma_mode(unsigned int dmanr, unsigned int mode) chan->mode |= mode; } -static __inline__ unsigned int get_dma_mode(unsigned int dmanr) +static inline unsigned int get_dma_mode(unsigned int dmanr) { struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) return 0; return chan->mode; } -static __inline__ int get_dma_active_buffer(unsigned int dmanr) +static inline int get_dma_active_buffer(unsigned int dmanr) { struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) return -1; return (au_readl(chan->io + DMA_MODE_READ) & DMA_AB) ? 1 : 0; } - /* - * set the device FIFO address for a specific DMA channel - only + * Set the device FIFO address for a specific DMA channel - only * applicable to GPO4 and GPO5. All the other devices have fixed * FIFO addresses. */ -static __inline__ void set_dma_fifo_addr(unsigned int dmanr, - unsigned int a) +static inline void set_dma_fifo_addr(unsigned int dmanr, unsigned int a) { struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) return; - if (chan->mode & DMA_DS) /* second bank of device ids */ + if (chan->mode & DMA_DS) /* second bank of device IDs */ return; if (chan->dev_id != DMA_ID_GP04 && chan->dev_id != DMA_ID_GP05) @@ -307,16 +315,19 @@ static __inline__ void set_dma_fifo_addr(unsigned int dmanr, /* * Clear the DMA buffer done bits in the mode register. */ -static __inline__ void clear_dma_done0(unsigned int dmanr) +static inline void clear_dma_done0(unsigned int dmanr) { struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) return; au_writel(DMA_D0, chan->io + DMA_MODE_CLEAR); } -static __inline__ void clear_dma_done1(unsigned int dmanr) + +static inline void clear_dma_done1(unsigned int dmanr) { struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) return; au_writel(DMA_D1, chan->io + DMA_MODE_CLEAR); @@ -325,16 +336,17 @@ static __inline__ void clear_dma_done1(unsigned int dmanr) /* * This does nothing - not applicable to Au1000 DMA. */ -static __inline__ void set_dma_page(unsigned int dmanr, char pagenr) +static inline void set_dma_page(unsigned int dmanr, char pagenr) { } /* * Set Buffer 0 transfer address for specific DMA channel. */ -static __inline__ void set_dma_addr0(unsigned int dmanr, unsigned int a) +static inline void set_dma_addr0(unsigned int dmanr, unsigned int a) { struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) return; au_writel(a, chan->io + DMA_BUFFER0_START); @@ -343,9 +355,10 @@ static __inline__ void set_dma_addr0(unsigned int dmanr, unsigned int a) /* * Set Buffer 1 transfer address for specific DMA channel. */ -static __inline__ void set_dma_addr1(unsigned int dmanr, unsigned int a) +static inline void set_dma_addr1(unsigned int dmanr, unsigned int a) { struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) return; au_writel(a, chan->io + DMA_BUFFER1_START); @@ -355,10 +368,10 @@ static __inline__ void set_dma_addr1(unsigned int dmanr, unsigned int a) /* * Set Buffer 0 transfer size (max 64k) for a specific DMA channel. */ -static __inline__ void set_dma_count0(unsigned int dmanr, - unsigned int count) +static inline void set_dma_count0(unsigned int dmanr, unsigned int count) { struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) return; count &= DMA_COUNT_MASK; @@ -368,10 +381,10 @@ static __inline__ void set_dma_count0(unsigned int dmanr, /* * Set Buffer 1 transfer size (max 64k) for a specific DMA channel. */ -static __inline__ void set_dma_count1(unsigned int dmanr, - unsigned int count) +static inline void set_dma_count1(unsigned int dmanr, unsigned int count) { struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) return; count &= DMA_COUNT_MASK; @@ -381,10 +394,10 @@ static __inline__ void set_dma_count1(unsigned int dmanr, /* * Set both buffer transfer sizes (max 64k) for a specific DMA channel. */ -static __inline__ void set_dma_count(unsigned int dmanr, - unsigned int count) +static inline void set_dma_count(unsigned int dmanr, unsigned int count) { struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) return; count &= DMA_COUNT_MASK; @@ -396,35 +409,36 @@ static __inline__ void set_dma_count(unsigned int dmanr, * Returns which buffer has its done bit set in the mode register. * Returns -1 if neither or both done bits set. */ -static __inline__ unsigned int get_dma_buffer_done(unsigned int dmanr) +static inline unsigned int get_dma_buffer_done(unsigned int dmanr) { struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) return 0; - - return au_readl(chan->io + DMA_MODE_READ) & (DMA_D0 | DMA_D1); + return au_readl(chan->io + DMA_MODE_READ) & (DMA_D0 | DMA_D1); } /* * Returns the DMA channel's Buffer Done IRQ number. */ -static __inline__ int get_dma_done_irq(unsigned int dmanr) +static inline int get_dma_done_irq(unsigned int dmanr) { struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) return -1; - return chan->irq; } /* * Get DMA residue count. Returns the number of _bytes_ left to transfer. */ -static __inline__ int get_dma_residue(unsigned int dmanr) +static inline int get_dma_residue(unsigned int dmanr) { int curBufCntReg, count; struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) return 0; @@ -442,4 +456,3 @@ static __inline__ int get_dma_residue(unsigned int dmanr) } #endif /* __ASM_AU1000_DMA_H */ - diff --git a/include/asm-mips/mach-au1x00/au1000_gpio.h b/include/asm-mips/mach-au1x00/au1000_gpio.h index 298f92012e8eedc40ac39b05e83165e524a72020..d8c96fda5549fd7309f41cb60846d9135e0f0da5 100644 --- a/include/asm-mips/mach-au1x00/au1000_gpio.h +++ b/include/asm-mips/mach-au1x00/au1000_gpio.h @@ -2,12 +2,12 @@ * FILE NAME au1000_gpio.h * * BRIEF MODULE DESCRIPTION - * API to Alchemy Au1000 GPIO device. + * API to Alchemy Au1xx0 GPIO device. * * Author: MontaVista Software, Inc. - * Steve Longerbeam + * Steve Longerbeam * - * Copyright 2001 MontaVista Software Inc. + * Copyright 2001, 2008 MontaVista Software Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -37,12 +37,12 @@ #define AU1000GPIO_IOC_MAGIC 'A' -#define AU1000GPIO_IN _IOR (AU1000GPIO_IOC_MAGIC, 0, int) -#define AU1000GPIO_SET _IOW (AU1000GPIO_IOC_MAGIC, 1, int) -#define AU1000GPIO_CLEAR _IOW (AU1000GPIO_IOC_MAGIC, 2, int) -#define AU1000GPIO_OUT _IOW (AU1000GPIO_IOC_MAGIC, 3, int) -#define AU1000GPIO_TRISTATE _IOW (AU1000GPIO_IOC_MAGIC, 4, int) -#define AU1000GPIO_AVAIL_MASK _IOR (AU1000GPIO_IOC_MAGIC, 5, int) +#define AU1000GPIO_IN _IOR(AU1000GPIO_IOC_MAGIC, 0, int) +#define AU1000GPIO_SET _IOW(AU1000GPIO_IOC_MAGIC, 1, int) +#define AU1000GPIO_CLEAR _IOW(AU1000GPIO_IOC_MAGIC, 2, int) +#define AU1000GPIO_OUT _IOW(AU1000GPIO_IOC_MAGIC, 3, int) +#define AU1000GPIO_TRISTATE _IOW(AU1000GPIO_IOC_MAGIC, 4, int) +#define AU1000GPIO_AVAIL_MASK _IOR(AU1000GPIO_IOC_MAGIC, 5, int) #ifdef __KERNEL__ extern u32 get_au1000_avail_gpio_mask(void); diff --git a/include/asm-mips/mach-au1x00/au1550_spi.h b/include/asm-mips/mach-au1x00/au1550_spi.h index c2f0466523ec6f8bafbcadb2a676aa5bccf79de3..40e6c489833a06ae628460dfbe11326d2541cc6b 100644 --- a/include/asm-mips/mach-au1x00/au1550_spi.h +++ b/include/asm-mips/mach-au1x00/au1550_spi.h @@ -1,5 +1,5 @@ /* - * au1550_spi.h - au1550 psc spi controller driver - platform data struct + * au1550_spi.h - Au1550 PSC SPI controller driver - platform data structure */ #ifndef _AU1550_SPI_H_ diff --git a/include/asm-mips/mach-au1x00/au1xxx.h b/include/asm-mips/mach-au1x00/au1xxx.h index 947135941033ec94ac2649579551063340e99055..1b3655090ed3adb6c5074166bb4a3f9d191ed112 100644 --- a/include/asm-mips/mach-au1x00/au1xxx.h +++ b/include/asm-mips/mach-au1x00/au1xxx.h @@ -23,10 +23,10 @@ #ifndef _AU1XXX_H_ #define _AU1XXX_H_ - #include -#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || defined(CONFIG_MIPS_DB1500) || defined(CONFIG_MIPS_DB1550) +#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || \ + defined(CONFIG_MIPS_DB1500) || defined(CONFIG_MIPS_DB1550) #include #elif defined(CONFIG_MIPS_PB1550) diff --git a/include/asm-mips/mach-au1x00/au1xxx_dbdma.h b/include/asm-mips/mach-au1x00/au1xxx_dbdma.h index 93d507cea518351302ac4304eea3da7109193c3c..ad17d7ce516abcad29e894f4cdd8172ad8892dd0 100644 --- a/include/asm-mips/mach-au1x00/au1xxx_dbdma.h +++ b/include/asm-mips/mach-au1x00/au1xxx_dbdma.h @@ -28,17 +28,18 @@ * 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* Specifics for the Au1xxx Descriptor-Based DMA Controllers, first - * seen in the AU1550 part. +/* + * Specifics for the Au1xxx Descriptor-Based DMA Controller, + * first seen in the AU1550 part. */ #ifndef _AU1000_DBDMA_H_ #define _AU1000_DBDMA_H_ - #ifndef _LANGUAGE_ASSEMBLY -/* The DMA base addresses. - * The Channels are every 256 bytes (0x0100) from the channel 0 base. +/* + * The DMA base addresses. + * The channels are every 256 bytes (0x0100) from the channel 0 base. * Interrupt status/enable is bits 15:0 for channels 15 to zero. */ #define DDMA_GLOBAL_BASE 0xb4003000 @@ -51,16 +52,14 @@ typedef volatile struct dbdma_global { u32 ddma_inten; } dbdma_global_t; -/* General Configuration. -*/ +/* General Configuration. */ #define DDMA_CONFIG_AF (1 << 2) #define DDMA_CONFIG_AH (1 << 1) #define DDMA_CONFIG_AL (1 << 0) #define DDMA_THROTTLE_EN (1 << 31) -/* The structure of a DMA Channel. -*/ +/* The structure of a DMA Channel. */ typedef volatile struct au1xxx_dma_channel { u32 ddma_cfg; /* See below */ u32 ddma_desptr; /* 32-byte aligned pointer to descriptor */ @@ -69,8 +68,7 @@ typedef volatile struct au1xxx_dma_channel { u32 ddma_irq; /* If bit 0 set, interrupt pending */ u32 ddma_stat; /* See below */ u32 ddma_bytecnt; /* Byte count, valid only when chan idle */ - /* Remainder, up to the 256 byte boundary, is reserved. - */ + /* Remainder, up to the 256 byte boundary, is reserved. */ } au1x_dma_chan_t; #define DDMA_CFG_SED (1 << 9) /* source DMA level/edge detect */ @@ -84,7 +82,8 @@ typedef volatile struct au1xxx_dma_channel { #define DDMA_CFG_DBE (1 << 1) /* Destination big endian */ #define DDMA_CFG_EN (1 << 0) /* Channel enable */ -/* Always set when descriptor processing done, regardless of +/* + * Always set when descriptor processing done, regardless of * interrupt enable state. Reflected in global intstat, don't * clear this until global intstat is read/used. */ @@ -94,7 +93,8 @@ typedef volatile struct au1xxx_dma_channel { #define DDMA_STAT_V (1 << 1) /* Descriptor valid */ #define DDMA_STAT_H (1 << 0) /* Channel Halted */ -/* "Standard" DDMA Descriptor. +/* + * "Standard" DDMA Descriptor. * Must be 32-byte aligned. */ typedef volatile struct au1xxx_ddma_desc { @@ -106,8 +106,9 @@ typedef volatile struct au1xxx_ddma_desc { u32 dscr_dest1; /* See below */ u32 dscr_stat; /* completion status */ u32 dscr_nxtptr; /* Next descriptor pointer (mostly) */ - /* First 32bytes are HW specific!!! - Lets have some SW data following.. make sure its 32bytes + /* + * First 32 bytes are HW specific!!! + * Lets have some SW data following -- make sure it's 32 bytes. */ u32 sw_status; u32 sw_context; @@ -130,10 +131,9 @@ typedef volatile struct au1xxx_ddma_desc { #define DSCR_CMD0_CV (0x1 << 2) /* Clear Valid when done */ #define DSCR_CMD0_ST_MASK (0x3 << 0) /* Status instruction */ -#define SW_STATUS_INUSE (1<<0) +#define SW_STATUS_INUSE (1 << 0) -/* Command 0 device IDs. -*/ +/* Command 0 device IDs. */ #ifdef CONFIG_SOC_AU1550 #define DSCR_CMD0_UART0_TX 0 #define DSCR_CMD0_UART0_RX 1 @@ -198,16 +198,15 @@ typedef volatile struct au1xxx_ddma_desc { #define DSCR_CMD0_THROTTLE 30 #define DSCR_CMD0_ALWAYS 31 #define DSCR_NDEV_IDS 32 -/* THis macro is used to find/create custom device types */ -#define DSCR_DEV2CUSTOM_ID(x, d) (((((x)&0xFFFF)<<8)|0x32000000)|((d)&0xFF)) -#define DSCR_CUSTOM2DEV_ID(x) ((x)&0xFF) - +/* This macro is used to find/create custom device types */ +#define DSCR_DEV2CUSTOM_ID(x, d) (((((x) & 0xFFFF) << 8) | 0x32000000) | \ + ((d) & 0xFF)) +#define DSCR_CUSTOM2DEV_ID(x) ((x) & 0xFF) #define DSCR_CMD0_SID(x) (((x) & 0x1f) << 25) #define DSCR_CMD0_DID(x) (((x) & 0x1f) << 20) -/* Source/Destination transfer width. -*/ +/* Source/Destination transfer width. */ #define DSCR_CMD0_BYTE 0 #define DSCR_CMD0_HALFWORD 1 #define DSCR_CMD0_WORD 2 @@ -215,16 +214,14 @@ typedef volatile struct au1xxx_ddma_desc { #define DSCR_CMD0_SW(x) (((x) & 0x3) << 18) #define DSCR_CMD0_DW(x) (((x) & 0x3) << 16) -/* DDMA Descriptor Type. -*/ +/* DDMA Descriptor Type. */ #define DSCR_CMD0_STANDARD 0 #define DSCR_CMD0_LITERAL 1 #define DSCR_CMD0_CMP_BRANCH 2 #define DSCR_CMD0_DT(x) (((x) & 0x3) << 13) -/* Status Instruction. -*/ +/* Status Instruction. */ #define DSCR_CMD0_ST_NOCHANGE 0 /* Don't change */ #define DSCR_CMD0_ST_CURRENT 1 /* Write current status */ #define DSCR_CMD0_ST_CMD0 2 /* Write cmd0 with V cleared */ @@ -232,23 +229,20 @@ typedef volatile struct au1xxx_ddma_desc { #define DSCR_CMD0_ST(x) (((x) & 0x3) << 0) -/* Descriptor Command 1 -*/ +/* Descriptor Command 1. */ #define DSCR_CMD1_SUPTR_MASK (0xf << 28) /* upper 4 bits of src addr */ #define DSCR_CMD1_DUPTR_MASK (0xf << 24) /* upper 4 bits of dest addr */ #define DSCR_CMD1_FL_MASK (0x3 << 22) /* Flag bits */ #define DSCR_CMD1_BC_MASK (0x3fffff) /* Byte count */ -/* Flag description. -*/ +/* Flag description. */ #define DSCR_CMD1_FL_MEM_STRIDE0 0 #define DSCR_CMD1_FL_MEM_STRIDE1 1 #define DSCR_CMD1_FL_MEM_STRIDE2 2 #define DSCR_CMD1_FL(x) (((x) & 0x3) << 22) -/* Source1, 1-dimensional stride. -*/ +/* Source1, 1-dimensional stride. */ #define DSCR_SRC1_STS_MASK (3 << 30) /* Src xfer size */ #define DSCR_SRC1_SAM_MASK (3 << 28) /* Src xfer movement */ #define DSCR_SRC1_SB_MASK (0x3fff << 14) /* Block size */ @@ -256,8 +250,7 @@ typedef volatile struct au1xxx_ddma_desc { #define DSCR_SRC1_SS_MASK (0x3fff << 0) /* Stride */ #define DSCR_SRC1_SS(x) (((x) & 0x3fff) << 0) -/* Dest1, 1-dimensional stride. -*/ +/* Dest1, 1-dimensional stride. */ #define DSCR_DEST1_DTS_MASK (3 << 30) /* Dest xfer size */ #define DSCR_DEST1_DAM_MASK (3 << 28) /* Dest xfer movement */ #define DSCR_DEST1_DB_MASK (0x3fff << 14) /* Block size */ @@ -279,29 +272,27 @@ typedef volatile struct au1xxx_ddma_desc { #define DSCR_SRC1_SAM(x) (((x) & 3) << 28) #define DSCR_DEST1_DAM(x) (((x) & 3) << 28) -/* The next descriptor pointer. -*/ +/* The next descriptor pointer. */ #define DSCR_NXTPTR_MASK (0x07ffffff) #define DSCR_NXTPTR(x) ((x) >> 5) #define DSCR_GET_NXTPTR(x) ((x) << 5) #define DSCR_NXTPTR_MS (1 << 27) -/* The number of DBDMA channels. -*/ +/* The number of DBDMA channels. */ #define NUM_DBDMA_CHANS 16 /* - * Ddma API definitions + * DDMA API definitions * FIXME: may not fit to this header file */ typedef struct dbdma_device_table { - u32 dev_id; - u32 dev_flags; - u32 dev_tsize; - u32 dev_devwidth; - u32 dev_physaddr; /* If FIFO */ - u32 dev_intlevel; - u32 dev_intpolarity; + u32 dev_id; + u32 dev_flags; + u32 dev_tsize; + u32 dev_devwidth; + u32 dev_physaddr; /* If FIFO */ + u32 dev_intlevel; + u32 dev_intpolarity; } dbdev_tab_t; @@ -316,44 +307,41 @@ typedef struct dbdma_chan_config { au1x_ddma_desc_t *chan_desc_base; au1x_ddma_desc_t *get_ptr, *put_ptr, *cur_ptr; void *chan_callparam; - void (*chan_callback)(int, void *); + void (*chan_callback)(int, void *); } chan_tab_t; #define DEV_FLAGS_INUSE (1 << 0) #define DEV_FLAGS_ANYUSE (1 << 1) #define DEV_FLAGS_OUT (1 << 2) #define DEV_FLAGS_IN (1 << 3) -#define DEV_FLAGS_BURSTABLE (1 << 4) +#define DEV_FLAGS_BURSTABLE (1 << 4) #define DEV_FLAGS_SYNC (1 << 5) -/* end Ddma API definitions */ +/* end DDMA API definitions */ -/* External functions for drivers to use. -*/ -/* Use this to allocate a dbdma channel. The device ids are one of the - * DSCR_CMD0 devices IDs, which is usually redefined to a more - * meaningful name. The 'callback' is called during dma completion +/* + * External functions for drivers to use. + * Use this to allocate a DBDMA channel. The device IDs are one of + * the DSCR_CMD0 devices IDs, which is usually redefined to a more + * meaningful name. The 'callback' is called during DMA completion * interrupt. */ extern u32 au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid, - void (*callback)(int, void *), void *callparam); + void (*callback)(int, void *), + void *callparam); #define DBDMA_MEM_CHAN DSCR_CMD0_ALWAYS -/* Set the device width of a in/out fifo. -*/ +/* Set the device width of an in/out FIFO. */ u32 au1xxx_dbdma_set_devwidth(u32 chanid, int bits); -/* Allocate a ring of descriptors for dbdma. -*/ +/* Allocate a ring of descriptors for DBDMA. */ u32 au1xxx_dbdma_ring_alloc(u32 chanid, int entries); -/* Put buffers on source/destination descriptors. -*/ +/* Put buffers on source/destination descriptors. */ u32 _au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags); u32 _au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes, u32 flags); -/* Get a buffer from the destination descriptor. -*/ +/* Get a buffer from the destination descriptor. */ u32 au1xxx_dbdma_get_dest(u32 chanid, void **buf, int *nbytes); void au1xxx_dbdma_stop(u32 chanid); @@ -364,29 +352,34 @@ u32 au1xxx_get_dma_residue(u32 chanid); void au1xxx_dbdma_chan_free(u32 chanid); void au1xxx_dbdma_dump(u32 chanid); -u32 au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr ); +u32 au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr); -u32 au1xxx_ddma_add_device( dbdev_tab_t *dev ); -void * au1xxx_ddma_get_nextptr_virt(au1x_ddma_desc_t *dp); +u32 au1xxx_ddma_add_device(dbdev_tab_t *dev); +void *au1xxx_ddma_get_nextptr_virt(au1x_ddma_desc_t *dp); /* - Some compatibilty macros -- - Needed to make changes to API without breaking existing drivers -*/ -#define au1xxx_dbdma_put_source(chanid, buf, nbytes)_au1xxx_dbdma_put_source(chanid, buf, nbytes, DDMA_FLAGS_IE) -#define au1xxx_dbdma_put_source_flags(chanid, buf, nbytes, flags) _au1xxx_dbdma_put_source(chanid, buf, nbytes, flags) -#define put_source_flags(chanid, buf, nbytes, flags) au1xxx_dbdma_put_source_flags(chanid, buf, nbytes, flags) - - -#define au1xxx_dbdma_put_dest(chanid, buf, nbytes) _au1xxx_dbdma_put_dest(chanid, buf, nbytes, DDMA_FLAGS_IE) -#define au1xxx_dbdma_put_dest_flags(chanid, buf, nbytes, flags) _au1xxx_dbdma_put_dest(chanid, buf, nbytes, flags) -#define put_dest_flags(chanid, buf, nbytes, flags) au1xxx_dbdma_put_dest_flags(chanid, buf, nbytes, flags) + * Some compatibilty macros -- needed to make changes to API + * without breaking existing drivers. + */ +#define au1xxx_dbdma_put_source(chanid, buf, nbytes) \ + _au1xxx_dbdma_put_source(chanid, buf, nbytes, DDMA_FLAGS_IE) +#define au1xxx_dbdma_put_source_flags(chanid, buf, nbytes, flags) \ + _au1xxx_dbdma_put_source(chanid, buf, nbytes, flags) +#define put_source_flags(chanid, buf, nbytes, flags) \ + au1xxx_dbdma_put_source_flags(chanid, buf, nbytes, flags) + +#define au1xxx_dbdma_put_dest(chanid, buf, nbytes) \ + _au1xxx_dbdma_put_dest(chanid, buf, nbytes, DDMA_FLAGS_IE) +#define au1xxx_dbdma_put_dest_flags(chanid, buf, nbytes, flags) \ + _au1xxx_dbdma_put_dest(chanid, buf, nbytes, flags) +#define put_dest_flags(chanid, buf, nbytes, flags) \ + au1xxx_dbdma_put_dest_flags(chanid, buf, nbytes, flags) /* * Flags for the put_source/put_dest functions. */ -#define DDMA_FLAGS_IE (1<<0) -#define DDMA_FLAGS_NOIE (1<<1) +#define DDMA_FLAGS_IE (1 << 0) +#define DDMA_FLAGS_NOIE (1 << 1) #endif /* _LANGUAGE_ASSEMBLY */ #endif /* _AU1000_DBDMA_H_ */ diff --git a/include/asm-mips/mach-au1x00/au1xxx_ide.h b/include/asm-mips/mach-au1x00/au1xxx_ide.h index b493a5e46c639598f9066f0591a6d983b0073c57..60638b8969ba47e86ceab2f8b7a5bff730cec503 100644 --- a/include/asm-mips/mach-au1x00/au1xxx_ide.h +++ b/include/asm-mips/mach-au1x00/au1xxx_ide.h @@ -31,167 +31,164 @@ */ #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA - #define DMA_WAIT_TIMEOUT 100 - #define NUM_DESCRIPTORS PRD_ENTRIES +#define DMA_WAIT_TIMEOUT 100 +#define NUM_DESCRIPTORS PRD_ENTRIES #else /* CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA */ - #define NUM_DESCRIPTORS 2 +#define NUM_DESCRIPTORS 2 #endif #ifndef AU1XXX_ATA_RQSIZE - #define AU1XXX_ATA_RQSIZE 128 +#define AU1XXX_ATA_RQSIZE 128 #endif /* Disable Burstable-Support for DBDMA */ #ifndef CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON - #define CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON 0 +#define CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON 0 #endif #ifdef CONFIG_PM /* -* This will enable the device to be powered up when write() or read() -* is called. If this is not defined, the driver will return -EBUSY. -*/ + * This will enable the device to be powered up when write() or read() + * is called. If this is not defined, the driver will return -EBUSY. + */ #define WAKE_ON_ACCESS 1 -typedef struct -{ - spinlock_t lock; /* Used to block on state transitions */ - au1xxx_power_dev_t *dev; /* Power Managers device structure */ - unsigned stopped; /* USed to signaling device is stopped */ +typedef struct { + spinlock_t lock; /* Used to block on state transitions */ + au1xxx_power_dev_t *dev; /* Power Managers device structure */ + unsigned stopped; /* Used to signal device is stopped */ } pm_state; #endif - -typedef struct -{ - u32 tx_dev_id, rx_dev_id, target_dev_id; - u32 tx_chan, rx_chan; - void *tx_desc_head, *rx_desc_head; - ide_hwif_t *hwif; +typedef struct { + u32 tx_dev_id, rx_dev_id, target_dev_id; + u32 tx_chan, rx_chan; + void *tx_desc_head, *rx_desc_head; + ide_hwif_t *hwif; #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA - ide_drive_t *drive; - struct dbdma_cmd *dma_table_cpu; - dma_addr_t dma_table_dma; + ide_drive_t *drive; + struct dbdma_cmd *dma_table_cpu; + dma_addr_t dma_table_dma; #endif int irq; u32 regbase; #ifdef CONFIG_PM - pm_state pm; + pm_state pm; #endif } _auide_hwif; -/******************************************************************************* -* PIO Mode timing calculation : * -* * -* Static Bus Spec ATA Spec * -* Tcsoe = t1 * -* Toecs = t9 * -* Twcs = t9 * -* Tcsh = t2i | t2 * -* Tcsoff = t2i | t2 * -* Twp = t2 * -* Tcsw = t1 * -* Tpm = 0 * -* Ta = t1+t2 * -*******************************************************************************/ +/******************************************************************************/ +/* PIO Mode timing calculation : */ +/* */ +/* Static Bus Spec ATA Spec */ +/* Tcsoe = t1 */ +/* Toecs = t9 */ +/* Twcs = t9 */ +/* Tcsh = t2i | t2 */ +/* Tcsoff = t2i | t2 */ +/* Twp = t2 */ +/* Tcsw = t1 */ +/* Tpm = 0 */ +/* Ta = t1+t2 */ +/******************************************************************************/ -#define TCSOE_MASK (0x07<<29) -#define TOECS_MASK (0x07<<26) -#define TWCS_MASK (0x07<<28) -#define TCSH_MASK (0x0F<<24) -#define TCSOFF_MASK (0x07<<20) -#define TWP_MASK (0x3F<<14) -#define TCSW_MASK (0x0F<<10) -#define TPM_MASK (0x0F<<6) -#define TA_MASK (0x3F<<0) -#define TS_MASK (1<<8) +#define TCSOE_MASK (0x07 << 29) +#define TOECS_MASK (0x07 << 26) +#define TWCS_MASK (0x07 << 28) +#define TCSH_MASK (0x0F << 24) +#define TCSOFF_MASK (0x07 << 20) +#define TWP_MASK (0x3F << 14) +#define TCSW_MASK (0x0F << 10) +#define TPM_MASK (0x0F << 6) +#define TA_MASK (0x3F << 0) +#define TS_MASK (1 << 8) /* Timing parameters PIO mode 0 */ -#define SBC_IDE_PIO0_TCSOE (0x04<<29) -#define SBC_IDE_PIO0_TOECS (0x01<<26) -#define SBC_IDE_PIO0_TWCS (0x02<<28) -#define SBC_IDE_PIO0_TCSH (0x08<<24) -#define SBC_IDE_PIO0_TCSOFF (0x07<<20) -#define SBC_IDE_PIO0_TWP (0x10<<14) -#define SBC_IDE_PIO0_TCSW (0x04<<10) -#define SBC_IDE_PIO0_TPM (0x0<<6) -#define SBC_IDE_PIO0_TA (0x15<<0) +#define SBC_IDE_PIO0_TCSOE (0x04 << 29) +#define SBC_IDE_PIO0_TOECS (0x01 << 26) +#define SBC_IDE_PIO0_TWCS (0x02 << 28) +#define SBC_IDE_PIO0_TCSH (0x08 << 24) +#define SBC_IDE_PIO0_TCSOFF (0x07 << 20) +#define SBC_IDE_PIO0_TWP (0x10 << 14) +#define SBC_IDE_PIO0_TCSW (0x04 << 10) +#define SBC_IDE_PIO0_TPM (0x00 << 6) +#define SBC_IDE_PIO0_TA (0x15 << 0) /* Timing parameters PIO mode 1 */ -#define SBC_IDE_PIO1_TCSOE (0x03<<29) -#define SBC_IDE_PIO1_TOECS (0x01<<26) -#define SBC_IDE_PIO1_TWCS (0x01<<28) -#define SBC_IDE_PIO1_TCSH (0x06<<24) -#define SBC_IDE_PIO1_TCSOFF (0x06<<20) -#define SBC_IDE_PIO1_TWP (0x08<<14) -#define SBC_IDE_PIO1_TCSW (0x03<<10) -#define SBC_IDE_PIO1_TPM (0x00<<6) -#define SBC_IDE_PIO1_TA (0x0B<<0) +#define SBC_IDE_PIO1_TCSOE (0x03 << 29) +#define SBC_IDE_PIO1_TOECS (0x01 << 26) +#define SBC_IDE_PIO1_TWCS (0x01 << 28) +#define SBC_IDE_PIO1_TCSH (0x06 << 24) +#define SBC_IDE_PIO1_TCSOFF (0x06 << 20) +#define SBC_IDE_PIO1_TWP (0x08 << 14) +#define SBC_IDE_PIO1_TCSW (0x03 << 10) +#define SBC_IDE_PIO1_TPM (0x00 << 6) +#define SBC_IDE_PIO1_TA (0x0B << 0) /* Timing parameters PIO mode 2 */ -#define SBC_IDE_PIO2_TCSOE (0x05<<29) -#define SBC_IDE_PIO2_TOECS (0x01<<26) -#define SBC_IDE_PIO2_TWCS (0x01<<28) -#define SBC_IDE_PIO2_TCSH (0x07<<24) -#define SBC_IDE_PIO2_TCSOFF (0x07<<20) -#define SBC_IDE_PIO2_TWP (0x1F<<14) -#define SBC_IDE_PIO2_TCSW (0x05<<10) -#define SBC_IDE_PIO2_TPM (0x00<<6) -#define SBC_IDE_PIO2_TA (0x22<<0) +#define SBC_IDE_PIO2_TCSOE (0x05 << 29) +#define SBC_IDE_PIO2_TOECS (0x01 << 26) +#define SBC_IDE_PIO2_TWCS (0x01 << 28) +#define SBC_IDE_PIO2_TCSH (0x07 << 24) +#define SBC_IDE_PIO2_TCSOFF (0x07 << 20) +#define SBC_IDE_PIO2_TWP (0x1F << 14) +#define SBC_IDE_PIO2_TCSW (0x05 << 10) +#define SBC_IDE_PIO2_TPM (0x00 << 6) +#define SBC_IDE_PIO2_TA (0x22 << 0) /* Timing parameters PIO mode 3 */ -#define SBC_IDE_PIO3_TCSOE (0x05<<29) -#define SBC_IDE_PIO3_TOECS (0x01<<26) -#define SBC_IDE_PIO3_TWCS (0x01<<28) -#define SBC_IDE_PIO3_TCSH (0x0D<<24) -#define SBC_IDE_PIO3_TCSOFF (0x0D<<20) -#define SBC_IDE_PIO3_TWP (0x15<<14) -#define SBC_IDE_PIO3_TCSW (0x05<<10) -#define SBC_IDE_PIO3_TPM (0x00<<6) -#define SBC_IDE_PIO3_TA (0x1A<<0) +#define SBC_IDE_PIO3_TCSOE (0x05 << 29) +#define SBC_IDE_PIO3_TOECS (0x01 << 26) +#define SBC_IDE_PIO3_TWCS (0x01 << 28) +#define SBC_IDE_PIO3_TCSH (0x0D << 24) +#define SBC_IDE_PIO3_TCSOFF (0x0D << 20) +#define SBC_IDE_PIO3_TWP (0x15 << 14) +#define SBC_IDE_PIO3_TCSW (0x05 << 10) +#define SBC_IDE_PIO3_TPM (0x00 << 6) +#define SBC_IDE_PIO3_TA (0x1A << 0) /* Timing parameters PIO mode 4 */ -#define SBC_IDE_PIO4_TCSOE (0x04<<29) -#define SBC_IDE_PIO4_TOECS (0x01<<26) -#define SBC_IDE_PIO4_TWCS (0x01<<28) -#define SBC_IDE_PIO4_TCSH (0x04<<24) -#define SBC_IDE_PIO4_TCSOFF (0x04<<20) -#define SBC_IDE_PIO4_TWP (0x0D<<14) -#define SBC_IDE_PIO4_TCSW (0x03<<10) -#define SBC_IDE_PIO4_TPM (0x00<<6) -#define SBC_IDE_PIO4_TA (0x12<<0) +#define SBC_IDE_PIO4_TCSOE (0x04 << 29) +#define SBC_IDE_PIO4_TOECS (0x01 << 26) +#define SBC_IDE_PIO4_TWCS (0x01 << 28) +#define SBC_IDE_PIO4_TCSH (0x04 << 24) +#define SBC_IDE_PIO4_TCSOFF (0x04 << 20) +#define SBC_IDE_PIO4_TWP (0x0D << 14) +#define SBC_IDE_PIO4_TCSW (0x03 << 10) +#define SBC_IDE_PIO4_TPM (0x00 << 6) +#define SBC_IDE_PIO4_TA (0x12 << 0) /* Timing parameters MDMA mode 0 */ -#define SBC_IDE_MDMA0_TCSOE (0x03<<29) -#define SBC_IDE_MDMA0_TOECS (0x01<<26) -#define SBC_IDE_MDMA0_TWCS (0x01<<28) -#define SBC_IDE_MDMA0_TCSH (0x07<<24) -#define SBC_IDE_MDMA0_TCSOFF (0x07<<20) -#define SBC_IDE_MDMA0_TWP (0x0C<<14) -#define SBC_IDE_MDMA0_TCSW (0x03<<10) -#define SBC_IDE_MDMA0_TPM (0x00<<6) -#define SBC_IDE_MDMA0_TA (0x0F<<0) +#define SBC_IDE_MDMA0_TCSOE (0x03 << 29) +#define SBC_IDE_MDMA0_TOECS (0x01 << 26) +#define SBC_IDE_MDMA0_TWCS (0x01 << 28) +#define SBC_IDE_MDMA0_TCSH (0x07 << 24) +#define SBC_IDE_MDMA0_TCSOFF (0x07 << 20) +#define SBC_IDE_MDMA0_TWP (0x0C << 14) +#define SBC_IDE_MDMA0_TCSW (0x03 << 10) +#define SBC_IDE_MDMA0_TPM (0x00 << 6) +#define SBC_IDE_MDMA0_TA (0x0F << 0) /* Timing parameters MDMA mode 1 */ -#define SBC_IDE_MDMA1_TCSOE (0x05<<29) -#define SBC_IDE_MDMA1_TOECS (0x01<<26) -#define SBC_IDE_MDMA1_TWCS (0x01<<28) -#define SBC_IDE_MDMA1_TCSH (0x05<<24) -#define SBC_IDE_MDMA1_TCSOFF (0x05<<20) -#define SBC_IDE_MDMA1_TWP (0x0F<<14) -#define SBC_IDE_MDMA1_TCSW (0x05<<10) -#define SBC_IDE_MDMA1_TPM (0x00<<6) -#define SBC_IDE_MDMA1_TA (0x15<<0) +#define SBC_IDE_MDMA1_TCSOE (0x05 << 29) +#define SBC_IDE_MDMA1_TOECS (0x01 << 26) +#define SBC_IDE_MDMA1_TWCS (0x01 << 28) +#define SBC_IDE_MDMA1_TCSH (0x05 << 24) +#define SBC_IDE_MDMA1_TCSOFF (0x05 << 20) +#define SBC_IDE_MDMA1_TWP (0x0F << 14) +#define SBC_IDE_MDMA1_TCSW (0x05 << 10) +#define SBC_IDE_MDMA1_TPM (0x00 << 6) +#define SBC_IDE_MDMA1_TA (0x15 << 0) /* Timing parameters MDMA mode 2 */ -#define SBC_IDE_MDMA2_TCSOE (0x04<<29) -#define SBC_IDE_MDMA2_TOECS (0x01<<26) -#define SBC_IDE_MDMA2_TWCS (0x01<<28) -#define SBC_IDE_MDMA2_TCSH (0x04<<24) -#define SBC_IDE_MDMA2_TCSOFF (0x04<<20) -#define SBC_IDE_MDMA2_TWP (0x0D<<14) -#define SBC_IDE_MDMA2_TCSW (0x04<<10) -#define SBC_IDE_MDMA2_TPM (0x00<<6) -#define SBC_IDE_MDMA2_TA (0x12<<0) +#define SBC_IDE_MDMA2_TCSOE (0x04 << 29) +#define SBC_IDE_MDMA2_TOECS (0x01 << 26) +#define SBC_IDE_MDMA2_TWCS (0x01 << 28) +#define SBC_IDE_MDMA2_TCSH (0x04 << 24) +#define SBC_IDE_MDMA2_TCSOFF (0x04 << 20) +#define SBC_IDE_MDMA2_TWP (0x0D << 14) +#define SBC_IDE_MDMA2_TCSW (0x04 << 10) +#define SBC_IDE_MDMA2_TPM (0x00 << 6) +#define SBC_IDE_MDMA2_TA (0x12 << 0) #define SBC_IDE_TIMING(mode) \ - SBC_IDE_##mode##_TWCS | \ - SBC_IDE_##mode##_TCSH | \ - SBC_IDE_##mode##_TCSOFF | \ - SBC_IDE_##mode##_TWP | \ - SBC_IDE_##mode##_TCSW | \ - SBC_IDE_##mode##_TPM | \ - SBC_IDE_##mode##_TA + (SBC_IDE_##mode##_TWCS | \ + SBC_IDE_##mode##_TCSH | \ + SBC_IDE_##mode##_TCSOFF | \ + SBC_IDE_##mode##_TWP | \ + SBC_IDE_##mode##_TCSW | \ + SBC_IDE_##mode##_TPM | \ + SBC_IDE_##mode##_TA) diff --git a/include/asm-mips/mach-au1x00/au1xxx_psc.h b/include/asm-mips/mach-au1x00/au1xxx_psc.h index 1bd4e27caf6b70ee4ecbc1b2df29846e124e9969..dae4eca2417e847fd47a3eb8f2009814f8c07a77 100644 --- a/include/asm-mips/mach-au1x00/au1xxx_psc.h +++ b/include/asm-mips/mach-au1x00/au1xxx_psc.h @@ -33,7 +33,6 @@ #ifndef _AU1000_PSC_H_ #define _AU1000_PSC_H_ - /* The PSC base addresses. */ #ifdef CONFIG_SOC_AU1550 #define PSC0_BASE_ADDR 0xb1a00000 @@ -47,8 +46,8 @@ #define PSC1_BASE_ADDR 0xb1b00000 #endif -/* The PSC select and control registers are common to - * all protocols. +/* + * The PSC select and control registers are common to all protocols. */ #define PSC_SEL_OFFSET 0x00000000 #define PSC_CTRL_OFFSET 0x00000004 @@ -59,18 +58,17 @@ #define PSC_SEL_CLK_SERCLK (2 << 4) #define PSC_SEL_PS_MASK 0x00000007 -#define PSC_SEL_PS_DISABLED (0) -#define PSC_SEL_PS_SPIMODE (2) -#define PSC_SEL_PS_I2SMODE (3) -#define PSC_SEL_PS_AC97MODE (4) -#define PSC_SEL_PS_SMBUSMODE (5) - -#define PSC_CTRL_DISABLE (0) -#define PSC_CTRL_SUSPEND (2) -#define PSC_CTRL_ENABLE (3) - -/* AC97 Registers. -*/ +#define PSC_SEL_PS_DISABLED 0 +#define PSC_SEL_PS_SPIMODE 2 +#define PSC_SEL_PS_I2SMODE 3 +#define PSC_SEL_PS_AC97MODE 4 +#define PSC_SEL_PS_SMBUSMODE 5 + +#define PSC_CTRL_DISABLE 0 +#define PSC_CTRL_SUSPEND 2 +#define PSC_CTRL_ENABLE 3 + +/* AC97 Registers. */ #define PSC_AC97CFG_OFFSET 0x00000008 #define PSC_AC97MSK_OFFSET 0x0000000c #define PSC_AC97PCR_OFFSET 0x00000010 @@ -95,8 +93,7 @@ #define PSC_AC97GPO (AC97_PSC_BASE + PSC_AC97GPO_OFFSET) #define PSC_AC97GPI (AC97_PSC_BASE + PSC_AC97GPI_OFFSET) -/* AC97 Config Register. -*/ +/* AC97 Config Register. */ #define PSC_AC97CFG_RT_MASK (3 << 30) #define PSC_AC97CFG_RT_FIFO1 (0 << 30) #define PSC_AC97CFG_RT_FIFO2 (1 << 30) @@ -118,20 +115,19 @@ #define PSC_AC97CFG_RXSLOT_MASK (0x3ff << 1) #define PSC_AC97CFG_GE_ENABLE (1) -/* Enable slots 3-12. -*/ +/* Enable slots 3-12. */ #define PSC_AC97CFG_TXSLOT_ENA(x) (1 << (((x) - 3) + 11)) #define PSC_AC97CFG_RXSLOT_ENA(x) (1 << (((x) - 3) + 1)) -/* The word length equation is ((x) * 2) + 2, so choose 'x' appropriately. +/* + * The word length equation is ((x) * 2) + 2, so choose 'x' appropriately. * The only sensible numbers are 7, 9, or possibly 11. Nah, just do the * arithmetic in the macro. */ -#define PSC_AC97CFG_SET_LEN(x) (((((x)-2)/2) & 0xf) << 21) +#define PSC_AC97CFG_SET_LEN(x) (((((x) - 2) / 2) & 0xf) << 21) #define PSC_AC97CFG_GET_LEN(x) (((((x) >> 21) & 0xf) * 2) + 2) -/* AC97 Mask Register. -*/ +/* AC97 Mask Register. */ #define PSC_AC97MSK_GR (1 << 25) #define PSC_AC97MSK_CD (1 << 24) #define PSC_AC97MSK_RR (1 << 13) @@ -148,8 +144,7 @@ PSC_AC97MSK_TO | PSC_AC97MSK_TU | \ PSC_AC97MSK_RD | PSC_AC97MSK_TD) -/* AC97 Protocol Control Register. -*/ +/* AC97 Protocol Control Register. */ #define PSC_AC97PCR_RC (1 << 6) #define PSC_AC97PCR_RP (1 << 5) #define PSC_AC97PCR_RS (1 << 4) @@ -157,8 +152,7 @@ #define PSC_AC97PCR_TP (1 << 1) #define PSC_AC97PCR_TS (1 << 0) -/* AC97 Status register (read only). -*/ +/* AC97 Status register (read only). */ #define PSC_AC97STAT_CB (1 << 26) #define PSC_AC97STAT_CP (1 << 25) #define PSC_AC97STAT_CR (1 << 24) @@ -174,8 +168,7 @@ #define PSC_AC97STAT_DR (1 << 1) #define PSC_AC97STAT_SR (1 << 0) -/* AC97 Event Register. -*/ +/* AC97 Event Register. */ #define PSC_AC97EVNT_GR (1 << 25) #define PSC_AC97EVNT_CD (1 << 24) #define PSC_AC97EVNT_RR (1 << 13) @@ -187,22 +180,18 @@ #define PSC_AC97EVNT_RD (1 << 5) #define PSC_AC97EVNT_TD (1 << 4) -/* CODEC Command Register. -*/ +/* CODEC Command Register. */ #define PSC_AC97CDC_RD (1 << 25) #define PSC_AC97CDC_ID_MASK (3 << 23) #define PSC_AC97CDC_INDX_MASK (0x7f << 16) -#define PSC_AC97CDC_ID(x) (((x) & 0x3) << 23) +#define PSC_AC97CDC_ID(x) (((x) & 0x03) << 23) #define PSC_AC97CDC_INDX(x) (((x) & 0x7f) << 16) -/* AC97 Reset Control Register. -*/ +/* AC97 Reset Control Register. */ #define PSC_AC97RST_RST (1 << 1) #define PSC_AC97RST_SNC (1 << 0) - -/* PSC in I2S Mode. -*/ +/* PSC in I2S Mode. */ typedef struct psc_i2s { u32 psc_sel; u32 psc_ctrl; @@ -215,8 +204,7 @@ typedef struct psc_i2s { u32 psc_i2sudf; } psc_i2s_t; -/* I2S Config Register. -*/ +/* I2S Config Register. */ #define PSC_I2SCFG_RT_MASK (3 << 30) #define PSC_I2SCFG_RT_FIFO1 (0 << 30) #define PSC_I2SCFG_RT_FIFO2 (1 << 30) @@ -247,8 +235,7 @@ typedef struct psc_i2s { #define PSC_I2SCFG_MLJ (1 << 10) #define PSC_I2SCFG_XM (1 << 9) -/* The word length equation is simply LEN+1. - */ +/* The word length equation is simply LEN+1. */ #define PSC_I2SCFG_SET_LEN(x) ((((x) - 1) & 0x1f) << 4) #define PSC_I2SCFG_GET_LEN(x) ((((x) >> 4) & 0x1f) + 1) @@ -256,8 +243,7 @@ typedef struct psc_i2s { #define PSC_I2SCFG_MLF (1 << 1) #define PSC_I2SCFG_MS (1 << 0) -/* I2S Mask Register. -*/ +/* I2S Mask Register. */ #define PSC_I2SMSK_RR (1 << 13) #define PSC_I2SMSK_RO (1 << 12) #define PSC_I2SMSK_RU (1 << 11) @@ -271,8 +257,7 @@ typedef struct psc_i2s { PSC_I2SMSK_TO | PSC_I2SMSK_TU | \ PSC_I2SMSK_RD | PSC_I2SMSK_TD) -/* I2S Protocol Control Register. -*/ +/* I2S Protocol Control Register. */ #define PSC_I2SPCR_RC (1 << 6) #define PSC_I2SPCR_RP (1 << 5) #define PSC_I2SPCR_RS (1 << 4) @@ -280,8 +265,7 @@ typedef struct psc_i2s { #define PSC_I2SPCR_TP (1 << 1) #define PSC_I2SPCR_TS (1 << 0) -/* I2S Status register (read only). -*/ +/* I2S Status register (read only). */ #define PSC_I2SSTAT_RF (1 << 13) #define PSC_I2SSTAT_RE (1 << 12) #define PSC_I2SSTAT_RR (1 << 11) @@ -294,8 +278,7 @@ typedef struct psc_i2s { #define PSC_I2SSTAT_DR (1 << 1) #define PSC_I2SSTAT_SR (1 << 0) -/* I2S Event Register. -*/ +/* I2S Event Register. */ #define PSC_I2SEVNT_RR (1 << 13) #define PSC_I2SEVNT_RO (1 << 12) #define PSC_I2SEVNT_RU (1 << 11) @@ -305,8 +288,7 @@ typedef struct psc_i2s { #define PSC_I2SEVNT_RD (1 << 5) #define PSC_I2SEVNT_TD (1 << 4) -/* PSC in SPI Mode. -*/ +/* PSC in SPI Mode. */ typedef struct psc_spi { u32 psc_sel; u32 psc_ctrl; @@ -318,8 +300,7 @@ typedef struct psc_spi { u32 psc_spitxrx; } psc_spi_t; -/* SPI Config Register. -*/ +/* SPI Config Register. */ #define PSC_SPICFG_RT_MASK (3 << 30) #define PSC_SPICFG_RT_FIFO1 (0 << 30) #define PSC_SPICFG_RT_FIFO2 (1 << 30) @@ -355,8 +336,7 @@ typedef struct psc_spi { #define PSC_SPICFG_MLF (1 << 1) #define PSC_SPICFG_MO (1 << 0) -/* SPI Mask Register. -*/ +/* SPI Mask Register. */ #define PSC_SPIMSK_MM (1 << 16) #define PSC_SPIMSK_RR (1 << 13) #define PSC_SPIMSK_RO (1 << 12) @@ -371,16 +351,14 @@ typedef struct psc_spi { PSC_SPIMSK_TU | PSC_SPIMSK_SD | \ PSC_SPIMSK_MD) -/* SPI Protocol Control Register. -*/ +/* SPI Protocol Control Register. */ #define PSC_SPIPCR_RC (1 << 6) #define PSC_SPIPCR_SP (1 << 5) #define PSC_SPIPCR_SS (1 << 4) #define PSC_SPIPCR_TC (1 << 2) #define PSC_SPIPCR_MS (1 << 0) -/* SPI Status register (read only). -*/ +/* SPI Status register (read only). */ #define PSC_SPISTAT_RF (1 << 13) #define PSC_SPISTAT_RE (1 << 12) #define PSC_SPISTAT_RR (1 << 11) @@ -393,8 +371,7 @@ typedef struct psc_spi { #define PSC_SPISTAT_DR (1 << 1) #define PSC_SPISTAT_SR (1 << 0) -/* SPI Event Register. -*/ +/* SPI Event Register. */ #define PSC_SPIEVNT_MM (1 << 16) #define PSC_SPIEVNT_RR (1 << 13) #define PSC_SPIEVNT_RO (1 << 12) @@ -405,13 +382,11 @@ typedef struct psc_spi { #define PSC_SPIEVNT_SD (1 << 5) #define PSC_SPIEVNT_MD (1 << 4) -/* Transmit register control. -*/ +/* Transmit register control. */ #define PSC_SPITXRX_LC (1 << 29) #define PSC_SPITXRX_SR (1 << 28) -/* PSC in SMBus (I2C) Mode. -*/ +/* PSC in SMBus (I2C) Mode. */ typedef struct psc_smb { u32 psc_sel; u32 psc_ctrl; @@ -424,8 +399,7 @@ typedef struct psc_smb { u32 psc_smbtmr; } psc_smb_t; -/* SMBus Config Register. -*/ +/* SMBus Config Register. */ #define PSC_SMBCFG_RT_MASK (3 << 30) #define PSC_SMBCFG_RT_FIFO1 (0 << 30) #define PSC_SMBCFG_RT_FIFO2 (1 << 30) @@ -452,8 +426,7 @@ typedef struct psc_smb { #define PSC_SMBCFG_SET_SLV(x) (((x) & 0x7f) << 1) -/* SMBus Mask Register. -*/ +/* SMBus Mask Register. */ #define PSC_SMBMSK_DN (1 << 30) #define PSC_SMBMSK_AN (1 << 29) #define PSC_SMBMSK_AL (1 << 28) @@ -471,13 +444,11 @@ typedef struct psc_smb { PSC_SMBMSK_TU | PSC_SMBMSK_SD | \ PSC_SMBMSK_MD) -/* SMBus Protocol Control Register. -*/ +/* SMBus Protocol Control Register. */ #define PSC_SMBPCR_DC (1 << 2) #define PSC_SMBPCR_MS (1 << 0) -/* SMBus Status register (read only). -*/ +/* SMBus Status register (read only). */ #define PSC_SMBSTAT_BB (1 << 28) #define PSC_SMBSTAT_RF (1 << 13) #define PSC_SMBSTAT_RE (1 << 12) @@ -491,8 +462,7 @@ typedef struct psc_smb { #define PSC_SMBSTAT_DR (1 << 1) #define PSC_SMBSTAT_SR (1 << 0) -/* SMBus Event Register. -*/ +/* SMBus Event Register. */ #define PSC_SMBEVNT_DN (1 << 30) #define PSC_SMBEVNT_AN (1 << 29) #define PSC_SMBEVNT_AL (1 << 28) @@ -510,15 +480,13 @@ typedef struct psc_smb { PSC_SMBEVNT_TU | PSC_SMBEVNT_SD | \ PSC_SMBEVNT_MD) -/* Transmit register control. -*/ +/* Transmit register control. */ #define PSC_SMBTXRX_RSR (1 << 28) #define PSC_SMBTXRX_STP (1 << 29) -#define PSC_SMBTXRX_DATAMASK (0xff) +#define PSC_SMBTXRX_DATAMASK 0xff -/* SMBus protocol timers register. -*/ -#define PSC_SMBTMR_SET_TH(x) (((x) & 0x3) << 30) +/* SMBus protocol timers register. */ +#define PSC_SMBTMR_SET_TH(x) (((x) & 0x03) << 30) #define PSC_SMBTMR_SET_PS(x) (((x) & 0x1f) << 25) #define PSC_SMBTMR_SET_PU(x) (((x) & 0x1f) << 20) #define PSC_SMBTMR_SET_SH(x) (((x) & 0x1f) << 15) @@ -526,5 +494,4 @@ typedef struct psc_smb { #define PSC_SMBTMR_SET_CL(x) (((x) & 0x1f) << 5) #define PSC_SMBTMR_SET_CH(x) (((x) & 0x1f) << 0) - #endif /* _AU1000_PSC_H_ */ diff --git a/include/asm-mips/mach-db1x00/db1200.h b/include/asm-mips/mach-db1x00/db1200.h index eedd048a7261d958c3eda305267b2a5c0f74f37c..27f26102b1bb374d982527b95bedc1e8b848aa72 100644 --- a/include/asm-mips/mach-db1x00/db1200.h +++ b/include/asm-mips/mach-db1x00/db1200.h @@ -1,6 +1,6 @@ /* - * AMD Alchemy DB1200 Referrence Board - * Board Registers defines. + * AMD Alchemy DBAu1200 Reference Board + * Board register defines. * * ######################################################################## * @@ -27,26 +27,25 @@ #include #include -// This is defined in au1000.h with bogus value -#undef AU1X00_EXTERNAL_INT +#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX +#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX +#define DBDMA_I2S_TX_CHAN DSCR_CMD0_PSC1_TX +#define DBDMA_I2S_RX_CHAN DSCR_CMD0_PSC1_RX -#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX -#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX -#define DBDMA_I2S_TX_CHAN DSCR_CMD0_PSC1_TX -#define DBDMA_I2S_RX_CHAN DSCR_CMD0_PSC1_RX - -/* SPI and SMB are muxed on the Pb1200 board. - Refer to board documentation. +/* + * SPI and SMB are muxed on the DBAu1200 board. + * Refer to board documentation. */ -#define SPI_PSC_BASE PSC0_BASE_ADDR -#define SMBUS_PSC_BASE PSC0_BASE_ADDR -/* AC97 and I2S are muxed on the Pb1200 board. - Refer to board documentation. +#define SPI_PSC_BASE PSC0_BASE_ADDR +#define SMBUS_PSC_BASE PSC0_BASE_ADDR +/* + * AC'97 and I2S are muxed on the DBAu1200 board. + * Refer to board documentation. */ -#define AC97_PSC_BASE PSC1_BASE_ADDR +#define AC97_PSC_BASE PSC1_BASE_ADDR #define I2S_PSC_BASE PSC1_BASE_ADDR -#define BCSR_KSEG1_ADDR 0xB9800000 +#define BCSR_KSEG1_ADDR 0xB9800000 typedef volatile struct { @@ -102,9 +101,9 @@ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR; #define BCSR_STATUS_SWAPBOOT 0x0040 #define BCSR_STATUS_FLASHBUSY 0x0100 #define BCSR_STATUS_IDECBLID 0x0200 -#define BCSR_STATUS_SD0WP 0x0400 -#define BCSR_STATUS_U0RXD 0x1000 -#define BCSR_STATUS_U1RXD 0x2000 +#define BCSR_STATUS_SD0WP 0x0400 +#define BCSR_STATUS_U0RXD 0x1000 +#define BCSR_STATUS_U1RXD 0x2000 #define BCSR_SWITCHES_OCTAL 0x00FF #define BCSR_SWITCHES_DIP_1 0x0080 @@ -122,8 +121,8 @@ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR; #define BCSR_RESETS_DC 0x0004 #define BCSR_RESETS_IDE 0x0008 #define BCSR_RESETS_TV 0x0010 -/* not resets but in the same register */ -#define BCSR_RESETS_PWMR1mUX 0x0800 +/* Not resets but in the same register */ +#define BCSR_RESETS_PWMR1MUX 0x0800 #define BCSR_RESETS_PCS0MUX 0x1000 #define BCSR_RESETS_PCS1MUX 0x2000 #define BCSR_RESETS_SPISEL 0x4000 @@ -160,7 +159,7 @@ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR; #define BCSR_INT_PC0STSCHG 0x0008 #define BCSR_INT_PC1 0x0010 #define BCSR_INT_PC1STSCHG 0x0020 -#define BCSR_INT_DC 0x0040 +#define BCSR_INT_DC 0x0040 #define BCSR_INT_FLASHBUSY 0x0080 #define BCSR_INT_PC0INSERT 0x0100 #define BCSR_INT_PC0EJECT 0x0200 @@ -179,10 +178,10 @@ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR; #define IDE_DDMA_REQ DSCR_CMD0_DMA_REQ1 #define IDE_RQSIZE 128 -#define NAND_PHYS_ADDR 0x20000000 +#define NAND_PHYS_ADDR 0x20000000 /* - * External Interrupts for Pb1200 as of 8/6/2004. + * External Interrupts for DBAu1200 as of 8/6/2004. * Bit positions in the CPLD registers can be calculated by taking * the interrupt define and subtracting the DB1200_INT_BEGIN value. * @@ -211,23 +210,21 @@ enum external_pb1200_ints { }; -/* For drivers/pcmcia/au1000_db1x00.c */ - -/* PCMCIA Db1x00 specific defines */ - -#define PCMCIA_MAX_SOCK 1 -#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1) +/* + * DBAu1200 specific PCMCIA defines for drivers/pcmcia/au1000_db1x00.c + */ +#define PCMCIA_MAX_SOCK 1 +#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1) /* VPP/VCC */ -#define SET_VCC_VPP(VCC, VPP, SLOT)\ - ((((VCC)<<2) | ((VPP)<<0)) << ((SLOT)*8)) +#define SET_VCC_VPP(VCC, VPP, SLOT) \ + ((((VCC) << 2) | ((VPP) << 0)) << ((SLOT) * 8)) -#define BOARD_PC0_INT DB1200_PC0_INT -#define BOARD_PC1_INT DB1200_PC1_INT -#define BOARD_CARD_INSERTED(SOCKET) bcsr->sig_status & (1<<(8+(2*SOCKET))) +#define BOARD_PC0_INT DB1200_PC0_INT +#define BOARD_PC1_INT DB1200_PC1_INT +#define BOARD_CARD_INSERTED(SOCKET) bcsr->sig_status & (1 << (8 + (2 * SOCKET))) -/* Nand chip select */ +/* NAND chip select */ #define NAND_CS 1 #endif /* __ASM_DB1200_H */ - diff --git a/include/asm-mips/mach-db1x00/db1x00.h b/include/asm-mips/mach-db1x00/db1x00.h index e7a88ba358333800231730ad3f3b8bc318dfd889..612ae90dbcb8ea29451d7cd2034ef3c3a3fd2b5d 100644 --- a/include/asm-mips/mach-db1x00/db1x00.h +++ b/include/asm-mips/mach-db1x00/db1x00.h @@ -1,9 +1,8 @@ /* - * AMD Alchemy DB1x00 Reference Boards + * AMD Alchemy DBAu1x00 Reference Boards * - * Copyright 2001 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com + * Copyright 2001, 2008 MontaVista Software Inc. + * Author: MontaVista Software, Inc. * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org) * * ######################################################################## @@ -32,26 +31,26 @@ #ifdef CONFIG_MIPS_DB1550 -#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX -#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX -#define DBDMA_I2S_TX_CHAN DSCR_CMD0_PSC3_TX -#define DBDMA_I2S_RX_CHAN DSCR_CMD0_PSC3_RX +#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX +#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX +#define DBDMA_I2S_TX_CHAN DSCR_CMD0_PSC3_TX +#define DBDMA_I2S_RX_CHAN DSCR_CMD0_PSC3_RX -#define SPI_PSC_BASE PSC0_BASE_ADDR -#define AC97_PSC_BASE PSC1_BASE_ADDR -#define SMBUS_PSC_BASE PSC2_BASE_ADDR -#define I2S_PSC_BASE PSC3_BASE_ADDR +#define SPI_PSC_BASE PSC0_BASE_ADDR +#define AC97_PSC_BASE PSC1_BASE_ADDR +#define SMBUS_PSC_BASE PSC2_BASE_ADDR +#define I2S_PSC_BASE PSC3_BASE_ADDR -#define BCSR_KSEG1_ADDR 0xAF000000 -#define NAND_PHYS_ADDR 0x20000000 +#define BCSR_KSEG1_ADDR 0xAF000000 +#define NAND_PHYS_ADDR 0x20000000 #else #define BCSR_KSEG1_ADDR 0xAE000000 #endif /* - * Overlay data structure of the Db1x00 board registers. - * Registers located at physical 0E0000xx, KSEG1 0xAE0000xx + * Overlay data structure of the DBAu1x00 board registers. + * Registers are located at physical 0E0000xx, KSEG1 0xAE0000xx. */ typedef volatile struct { @@ -138,18 +137,19 @@ typedef volatile struct #define BCSR_SWRESET_RESET 0x0080 -/* PCMCIA Db1x00 specific defines */ -#define PCMCIA_MAX_SOCK 1 -#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1) +/* PCMCIA DBAu1x00 specific defines */ +#define PCMCIA_MAX_SOCK 1 +#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1) /* VPP/VCC */ #define SET_VCC_VPP(VCC, VPP, SLOT)\ - ((((VCC)<<2) | ((VPP)<<0)) << ((SLOT)*8)) + ((((VCC) << 2) | ((VPP) << 0)) << ((SLOT) * 8)) -/* SD controller macros */ /* - * Detect card. + * SD controller macros */ + +/* Detect card. */ #define mmc_card_inserted(_n_, _res_) \ do { \ BCSR * const bcsr = (BCSR *)0xAE000000; \ @@ -176,10 +176,10 @@ typedef volatile struct unsigned long mmc_pwr, mmc_wp, board_specific; \ if ((_n_)) { \ mmc_pwr = BCSR_BOARD_SD1_PWR; \ - mmc_wp = BCSR_BOARD_SD1_WP; \ + mmc_wp = BCSR_BOARD_SD1_WP; \ } else { \ mmc_pwr = BCSR_BOARD_SD0_PWR; \ - mmc_wp = BCSR_BOARD_SD0_WP; \ + mmc_wp = BCSR_BOARD_SD0_WP; \ } \ board_specific = au_readl((unsigned long)(&bcsr->specific)); \ if (!(board_specific & mmc_wp)) {/* low means card present */ \ @@ -190,17 +190,19 @@ typedef volatile struct } while (0) -/* NAND defines */ -/* Timing values as described in databook, * ns value stripped of +/* + * NAND defines + * + * Timing values as described in databook, * ns value stripped of the * lower 2 bits. - * These defines are here rather than an SOC1550 generic file because + * These defines are here rather than an Au1550 generic file because * the parts chosen on another board may be different and may require * different timings. */ -#define NAND_T_H (18 >> 2) -#define NAND_T_PUL (30 >> 2) -#define NAND_T_SU (30 >> 2) -#define NAND_T_WH (30 >> 2) +#define NAND_T_H (18 >> 2) +#define NAND_T_PUL (30 >> 2) +#define NAND_T_SU (30 >> 2) +#define NAND_T_WH (30 >> 2) /* Bitfield shift amounts */ #define NAND_T_H_SHIFT 0 @@ -208,16 +210,15 @@ typedef volatile struct #define NAND_T_SU_SHIFT 8 #define NAND_T_WH_SHIFT 12 -#define NAND_TIMING ((NAND_T_H & 0xF) << NAND_T_H_SHIFT) | \ - ((NAND_T_PUL & 0xF) << NAND_T_PUL_SHIFT) | \ - ((NAND_T_SU & 0xF) << NAND_T_SU_SHIFT) | \ - ((NAND_T_WH & 0xF) << NAND_T_WH_SHIFT) -#define NAND_CS 1 +#define NAND_TIMING (((NAND_T_H & 0xF) << NAND_T_H_SHIFT) | \ + ((NAND_T_PUL & 0xF) << NAND_T_PUL_SHIFT) | \ + ((NAND_T_SU & 0xF) << NAND_T_SU_SHIFT) | \ + ((NAND_T_WH & 0xF) << NAND_T_WH_SHIFT)) +#define NAND_CS 1 -/* should be done by yamon */ -#define NAND_STCFG 0x00400005 /* 8-bit NAND */ -#define NAND_STTIME 0x00007774 /* valid for 396MHz SD=2 only */ -#define NAND_STADDR 0x12000FFF /* physical address 0x20000000 */ +/* Should be done by YAMON */ +#define NAND_STCFG 0x00400005 /* 8-bit NAND */ +#define NAND_STTIME 0x00007774 /* valid for 396 MHz SD=2 only */ +#define NAND_STADDR 0x12000FFF /* physical address 0x20000000 */ #endif /* __ASM_DB1X00_H */ - diff --git a/include/asm-mips/mach-pb1x00/pb1000.h b/include/asm-mips/mach-pb1x00/pb1000.h index b52e0e7ee3fb7502ee0ac847ee6e2505aa61eec5..6d1ff9060e4486d049d85ee66996436c58f6bfd0 100644 --- a/include/asm-mips/mach-pb1x00/pb1000.h +++ b/include/asm-mips/mach-pb1x00/pb1000.h @@ -1,9 +1,8 @@ /* - * Alchemy Semi PB1000 Referrence Board + * Alchemy Semi Pb1000 Referrence Board * - * Copyright 2001 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com + * Copyright 2001, 2008 MontaVista Software Inc. + * Author: MontaVista Software, Inc. * * ######################################################################## * @@ -28,145 +27,61 @@ #define __ASM_PB1000_H /* PCMCIA PB1000 specific defines */ -#define PCMCIA_MAX_SOCK 1 -#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1) - -#define PB1000_PCR 0xBE000000 -# define PCR_SLOT_0_VPP0 (1<<0) -# define PCR_SLOT_0_VPP1 (1<<1) -# define PCR_SLOT_0_VCC0 (1<<2) -# define PCR_SLOT_0_VCC1 (1<<3) -# define PCR_SLOT_0_RST (1<<4) - -# define PCR_SLOT_1_VPP0 (1<<8) -# define PCR_SLOT_1_VPP1 (1<<9) -# define PCR_SLOT_1_VCC0 (1<<10) -# define PCR_SLOT_1_VCC1 (1<<11) -# define PCR_SLOT_1_RST (1<<12) - -#define PB1000_MDR 0xBE000004 -# define MDR_PI (1<<5) /* pcmcia int latch */ -# define MDR_EPI (1<<14) /* enable pcmcia int */ -# define MDR_CPI (1<<15) /* clear pcmcia int */ - -#define PB1000_ACR1 0xBE000008 -# define ACR1_SLOT_0_CD1 (1<<0) /* card detect 1 */ -# define ACR1_SLOT_0_CD2 (1<<1) /* card detect 2 */ -# define ACR1_SLOT_0_READY (1<<2) /* ready */ -# define ACR1_SLOT_0_STATUS (1<<3) /* status change */ -# define ACR1_SLOT_0_VS1 (1<<4) /* voltage sense 1 */ -# define ACR1_SLOT_0_VS2 (1<<5) /* voltage sense 2 */ -# define ACR1_SLOT_0_INPACK (1<<6) /* inpack pin status */ -# define ACR1_SLOT_1_CD1 (1<<8) /* card detect 1 */ -# define ACR1_SLOT_1_CD2 (1<<9) /* card detect 2 */ -# define ACR1_SLOT_1_READY (1<<10) /* ready */ -# define ACR1_SLOT_1_STATUS (1<<11) /* status change */ -# define ACR1_SLOT_1_VS1 (1<<12) /* voltage sense 1 */ -# define ACR1_SLOT_1_VS2 (1<<13) /* voltage sense 2 */ -# define ACR1_SLOT_1_INPACK (1<<14) /* inpack pin status */ - -#define CPLD_AUX0 0xBE00000C -#define CPLD_AUX1 0xBE000010 -#define CPLD_AUX2 0xBE000014 +#define PCMCIA_MAX_SOCK 1 +#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1) + +#define PB1000_PCR 0xBE000000 +# define PCR_SLOT_0_VPP0 (1 << 0) +# define PCR_SLOT_0_VPP1 (1 << 1) +# define PCR_SLOT_0_VCC0 (1 << 2) +# define PCR_SLOT_0_VCC1 (1 << 3) +# define PCR_SLOT_0_RST (1 << 4) +# define PCR_SLOT_1_VPP0 (1 << 8) +# define PCR_SLOT_1_VPP1 (1 << 9) +# define PCR_SLOT_1_VCC0 (1 << 10) +# define PCR_SLOT_1_VCC1 (1 << 11) +# define PCR_SLOT_1_RST (1 << 12) + +#define PB1000_MDR 0xBE000004 +# define MDR_PI (1 << 5) /* PCMCIA int latch */ +# define MDR_EPI (1 << 14) /* enable PCMCIA int */ +# define MDR_CPI (1 << 15) /* clear PCMCIA int */ + +#define PB1000_ACR1 0xBE000008 +# define ACR1_SLOT_0_CD1 (1 << 0) /* card detect 1 */ +# define ACR1_SLOT_0_CD2 (1 << 1) /* card detect 2 */ +# define ACR1_SLOT_0_READY (1 << 2) /* ready */ +# define ACR1_SLOT_0_STATUS (1 << 3) /* status change */ +# define ACR1_SLOT_0_VS1 (1 << 4) /* voltage sense 1 */ +# define ACR1_SLOT_0_VS2 (1 << 5) /* voltage sense 2 */ +# define ACR1_SLOT_0_INPACK (1 << 6) /* inpack pin status */ +# define ACR1_SLOT_1_CD1 (1 << 8) /* card detect 1 */ +# define ACR1_SLOT_1_CD2 (1 << 9) /* card detect 2 */ +# define ACR1_SLOT_1_READY (1 << 10) /* ready */ +# define ACR1_SLOT_1_STATUS (1 << 11) /* status change */ +# define ACR1_SLOT_1_VS1 (1 << 12) /* voltage sense 1 */ +# define ACR1_SLOT_1_VS2 (1 << 13) /* voltage sense 2 */ +# define ACR1_SLOT_1_INPACK (1 << 14) /* inpack pin status */ + +#define CPLD_AUX0 0xBE00000C +#define CPLD_AUX1 0xBE000010 +#define CPLD_AUX2 0xBE000014 /* Voltage levels */ /* VPPEN1 - VPPEN0 */ -#define VPP_GND ((0<<1) | (0<<0)) -#define VPP_5V ((1<<1) | (0<<0)) -#define VPP_3V ((0<<1) | (1<<0)) -#define VPP_12V ((0<<1) | (1<<0)) -#define VPP_HIZ ((1<<1) | (1<<0)) +#define VPP_GND ((0 << 1) | (0 << 0)) +#define VPP_5V ((1 << 1) | (0 << 0)) +#define VPP_3V ((0 << 1) | (1 << 0)) +#define VPP_12V ((0 << 1) | (1 << 0)) +#define VPP_HIZ ((1 << 1) | (1 << 0)) /* VCCEN1 - VCCEN0 */ -#define VCC_3V ((0<<1) | (1<<0)) -#define VCC_5V ((1<<1) | (0<<0)) -#define VCC_HIZ ((0<<1) | (0<<0)) +#define VCC_3V ((0 << 1) | (1 << 0)) +#define VCC_5V ((1 << 1) | (0 << 0)) +#define VCC_HIZ ((0 << 1) | (0 << 0)) /* VPP/VCC */ -#define SET_VCC_VPP(VCC, VPP, SLOT)\ - ((((VCC)<<2) | ((VPP)<<0)) << ((SLOT)*8)) - - -/* PCI PB1000 specific defines */ -/* The reason these defines are here instead of au1000.h is because - * the Au1000 does not have a PCI bus controller so the PCI implementation - * on the some of the older Pb1000 boards was very board specific. - */ -#define PCI_CONFIG_BASE 0xBA020000 /* the only external slot */ - -#define SDRAM_DEVID 0xBA010000 -#define SDRAM_CMD 0xBA010004 -#define SDRAM_CLASS 0xBA010008 -#define SDRAM_MISC 0xBA01000C -#define SDRAM_MBAR 0xBA010010 - -#define PCI_IO_DATA_PORT 0xBA800000 - -#define PCI_IO_ADDR 0xBE00001C -#define PCI_INT_ACK 0xBBC00000 -#define PCI_IO_READ 0xBBC00020 -#define PCI_IO_WRITE 0xBBC00030 - -#define PCI_BRIDGE_CONFIG 0xBE000018 - -#define PCI_IO_START 0x10000000 -#define PCI_IO_END 0x1000ffff -#define PCI_MEM_START 0x18000000 -#define PCI_MEM_END 0x18ffffff - -#define PCI_FIRST_DEVFN 0 -#define PCI_LAST_DEVFN 1 - -static inline u8 au_pci_io_readb(u32 addr) -{ - writel(addr, PCI_IO_ADDR); - writel((readl(PCI_BRIDGE_CONFIG) & 0xffffcfff) | (1<<12), PCI_BRIDGE_CONFIG); - return (readl(PCI_IO_DATA_PORT) & 0xff); -} - -static inline u16 au_pci_io_readw(u32 addr) -{ - writel(addr, PCI_IO_ADDR); - writel((readl(PCI_BRIDGE_CONFIG) & 0xffffcfff) | (1<<13), PCI_BRIDGE_CONFIG); - return (readl(PCI_IO_DATA_PORT) & 0xffff); -} - -static inline u32 au_pci_io_readl(u32 addr) -{ - writel(addr, PCI_IO_ADDR); - writel((readl(PCI_BRIDGE_CONFIG) & 0xffffcfff), PCI_BRIDGE_CONFIG); - return readl(PCI_IO_DATA_PORT); -} - -static inline void au_pci_io_writeb(u8 val, u32 addr) -{ - writel(addr, PCI_IO_ADDR); - writel((readl(PCI_BRIDGE_CONFIG) & 0xffffcfff) | (1<<12), PCI_BRIDGE_CONFIG); - writel(val, PCI_IO_DATA_PORT); -} - -static inline void au_pci_io_writew(u16 val, u32 addr) -{ - writel(addr, PCI_IO_ADDR); - writel((readl(PCI_BRIDGE_CONFIG) & 0xffffcfff) | (1<<13), PCI_BRIDGE_CONFIG); - writel(val, PCI_IO_DATA_PORT); -} - -static inline void au_pci_io_writel(u32 val, u32 addr) -{ - writel(addr, PCI_IO_ADDR); - writel(readl(PCI_BRIDGE_CONFIG) & 0xffffcfff, PCI_BRIDGE_CONFIG); - writel(val, PCI_IO_DATA_PORT); -} - -static inline void set_sdram_extbyte(void) -{ - writel(readl(PCI_BRIDGE_CONFIG) & 0xffffff00, PCI_BRIDGE_CONFIG); -} - -static inline void set_slot_extbyte(void) -{ - writel((readl(PCI_BRIDGE_CONFIG) & 0xffffbf00) | 0x18, PCI_BRIDGE_CONFIG); -} +#define SET_VCC_VPP(VCC, VPP, SLOT) \ + ((((VCC) << 2) | ((VPP) << 0)) << ((SLOT) * 8)) #endif /* __ASM_PB1000_H */ diff --git a/include/asm-mips/mach-pb1x00/pb1100.h b/include/asm-mips/mach-pb1x00/pb1100.h index 63aa3926b297f68db9aa26feb7ac1922f1802b4a..b1a60f1cbd021446bf6c91625e2f0e17f7e8b474 100644 --- a/include/asm-mips/mach-pb1x00/pb1100.h +++ b/include/asm-mips/mach-pb1x00/pb1100.h @@ -1,9 +1,8 @@ /* - * Alchemy Semi PB1100 Referrence Board + * Alchemy Semi Pb1100 Referrence Board * - * Copyright 2001 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com + * Copyright 2001, 2008 MontaVista Software Inc. + * Author: MontaVista Software, Inc. * * ######################################################################## * @@ -27,59 +26,60 @@ #ifndef __ASM_PB1100_H #define __ASM_PB1100_H -#define PB1100_IDENT 0xAE000000 -#define BOARD_STATUS_REG 0xAE000004 -# define PB1100_ROM_SEL (1<<15) -# define PB1100_ROM_SIZ (1<<14) -# define PB1100_SWAP_BOOT (1<<13) -# define PB1100_FLASH_WP (1<<12) -# define PB1100_ROM_H_STS (1<<11) -# define PB1100_ROM_L_STS (1<<10) -# define PB1100_FLASH_H_STS (1<<9) -# define PB1100_FLASH_L_STS (1<<8) -# define PB1100_SRAM_SIZ (1<<7) -# define PB1100_TSC_BUSY (1<<6) -# define PB1100_PCMCIA_VS_MASK (3<<4) -# define PB1100_RS232_CD (1<<3) -# define PB1100_RS232_CTS (1<<2) -# define PB1100_RS232_DSR (1<<1) -# define PB1100_RS232_RI (1<<0) +#define PB1100_IDENT 0xAE000000 +#define BOARD_STATUS_REG 0xAE000004 +# define PB1100_ROM_SEL (1 << 15) +# define PB1100_ROM_SIZ (1 << 14) +# define PB1100_SWAP_BOOT (1 << 13) +# define PB1100_FLASH_WP (1 << 12) +# define PB1100_ROM_H_STS (1 << 11) +# define PB1100_ROM_L_STS (1 << 10) +# define PB1100_FLASH_H_STS (1 << 9) +# define PB1100_FLASH_L_STS (1 << 8) +# define PB1100_SRAM_SIZ (1 << 7) +# define PB1100_TSC_BUSY (1 << 6) +# define PB1100_PCMCIA_VS_MASK (3 << 4) +# define PB1100_RS232_CD (1 << 3) +# define PB1100_RS232_CTS (1 << 2) +# define PB1100_RS232_DSR (1 << 1) +# define PB1100_RS232_RI (1 << 0) -#define PB1100_IRDA_RS232 0xAE00000C -# define PB1100_IRDA_FULL (0<<14) /* full power */ -# define PB1100_IRDA_SHUTDOWN (1<<14) -# define PB1100_IRDA_TT (2<<14) /* 2/3 power */ -# define PB1100_IRDA_OT (3<<14) /* 1/3 power */ -# define PB1100_IRDA_FIR (1<<13) +#define PB1100_IRDA_RS232 0xAE00000C +# define PB1100_IRDA_FULL (0 << 14) /* full power */ +# define PB1100_IRDA_SHUTDOWN (1 << 14) +# define PB1100_IRDA_TT (2 << 14) /* 2/3 power */ +# define PB1100_IRDA_OT (3 << 14) /* 1/3 power */ +# define PB1100_IRDA_FIR (1 << 13) -#define PCMCIA_BOARD_REG 0xAE000010 -# define PB1100_SD_WP1_RO (1<<15) /* read only */ -# define PB1100_SD_WP0_RO (1<<14) /* read only */ -# define PB1100_SD_PWR1 (1<<11) /* applies power to SD1 */ -# define PB1100_SD_PWR0 (1<<10) /* applies power to SD0 */ -# define PB1100_SEL_SD_CONN1 (1<<9) -# define PB1100_SEL_SD_CONN0 (1<<8) -# define PC_DEASSERT_RST (1<<7) -# define PC_DRV_EN (1<<4) +#define PCMCIA_BOARD_REG 0xAE000010 +# define PB1100_SD_WP1_RO (1 << 15) /* read only */ +# define PB1100_SD_WP0_RO (1 << 14) /* read only */ +# define PB1100_SD_PWR1 (1 << 11) /* applies power to SD1 */ +# define PB1100_SD_PWR0 (1 << 10) /* applies power to SD0 */ +# define PB1100_SEL_SD_CONN1 (1 << 9) +# define PB1100_SEL_SD_CONN0 (1 << 8) +# define PC_DEASSERT_RST (1 << 7) +# define PC_DRV_EN (1 << 4) -#define PB1100_G_CONTROL 0xAE000014 /* graphics control */ +#define PB1100_G_CONTROL 0xAE000014 /* graphics control */ -#define PB1100_RST_VDDI 0xAE00001C -# define PB1100_SOFT_RESET (1<<15) /* clear to reset the board */ -# define PB1100_VDDI_MASK (0x1F) +#define PB1100_RST_VDDI 0xAE00001C +# define PB1100_SOFT_RESET (1 << 15) /* clear to reset the board */ +# define PB1100_VDDI_MASK 0x1F -#define PB1100_LEDS 0xAE000018 +#define PB1100_LEDS 0xAE000018 -/* 11:8 is 4 discreet LEDs. Clearing a bit illuminates the LED. - * 7:0 is the LED Display's decimal points. +/* + * 11:8 is 4 discreet LEDs. Clearing a bit illuminates the LED. + * 7:0 is the LED Display's decimal points. */ -#define PB1100_HEX_LED 0xAE000018 +#define PB1100_HEX_LED 0xAE000018 -/* PCMCIA PB1100 specific defines */ -#define PCMCIA_MAX_SOCK 0 -#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1) +/* PCMCIA Pb1100 specific defines */ +#define PCMCIA_MAX_SOCK 0 +#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1) /* VPP/VCC */ -#define SET_VCC_VPP(VCC, VPP) (((VCC)<<2) | ((VPP)<<0)) +#define SET_VCC_VPP(VCC, VPP) (((VCC) << 2) | ((VPP) << 0)) #endif /* __ASM_PB1100_H */ diff --git a/include/asm-mips/mach-pb1x00/pb1200.h b/include/asm-mips/mach-pb1x00/pb1200.h index e2c6bcac3b4279933ed4b1419f92f35f972f4ddb..c8618df88cb51abedc40b29cd4468f61d2505f6c 100644 --- a/include/asm-mips/mach-pb1x00/pb1200.h +++ b/include/asm-mips/mach-pb1x00/pb1200.h @@ -1,5 +1,5 @@ /* - * AMD Alchemy PB1200 Referrence Board + * AMD Alchemy Pb1200 Referrence Board * Board Registers defines. * * ######################################################################## @@ -27,21 +27,20 @@ #include #include -// This is defined in au1000.h with bogus value -#undef AU1X00_EXTERNAL_INT +#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX +#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX +#define DBDMA_I2S_TX_CHAN DSCR_CMD0_PSC1_TX +#define DBDMA_I2S_RX_CHAN DSCR_CMD0_PSC1_RX -#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX -#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX -#define DBDMA_I2S_TX_CHAN DSCR_CMD0_PSC1_TX -#define DBDMA_I2S_RX_CHAN DSCR_CMD0_PSC1_RX - -/* SPI and SMB are muxed on the Pb1200 board. - Refer to board documentation. +/* + * SPI and SMB are muxed on the Pb1200 board. + * Refer to board documentation. */ -#define SPI_PSC_BASE PSC0_BASE_ADDR -#define SMBUS_PSC_BASE PSC0_BASE_ADDR -/* AC97 and I2S are muxed on the Pb1200 board. - Refer to board documentation. +#define SPI_PSC_BASE PSC0_BASE_ADDR +#define SMBUS_PSC_BASE PSC0_BASE_ADDR +/* + * AC97 and I2S are muxed on the Pb1200 board. + * Refer to board documentation. */ #define AC97_PSC_BASE PSC1_BASE_ADDR #define I2S_PSC_BASE PSC1_BASE_ADDR @@ -102,10 +101,10 @@ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR; #define BCSR_STATUS_SWAPBOOT 0x0040 #define BCSR_STATUS_FLASHBUSY 0x0100 #define BCSR_STATUS_IDECBLID 0x0200 -#define BCSR_STATUS_SD0WP 0x0400 -#define BCSR_STATUS_SD1WP 0x0800 -#define BCSR_STATUS_U0RXD 0x1000 -#define BCSR_STATUS_U1RXD 0x2000 +#define BCSR_STATUS_SD0WP 0x0400 +#define BCSR_STATUS_SD1WP 0x0800 +#define BCSR_STATUS_U0RXD 0x1000 +#define BCSR_STATUS_U1RXD 0x2000 #define BCSR_SWITCHES_OCTAL 0x00FF #define BCSR_SWITCHES_DIP_1 0x0080 @@ -123,11 +122,11 @@ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR; #define BCSR_RESETS_DC 0x0004 #define BCSR_RESETS_IDE 0x0008 /* not resets but in the same register */ -#define BCSR_RESETS_WSCFSM 0x0800 +#define BCSR_RESETS_WSCFSM 0x0800 #define BCSR_RESETS_PCS0MUX 0x1000 #define BCSR_RESETS_PCS1MUX 0x2000 #define BCSR_RESETS_SPISEL 0x4000 -#define BCSR_RESETS_SD1MUX 0x8000 +#define BCSR_RESETS_SD1MUX 0x8000 #define BCSR_PCMCIA_PC0VPP 0x0003 #define BCSR_PCMCIA_PC0VCC 0x000C @@ -163,7 +162,7 @@ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR; #define BCSR_INT_PC0STSCHG 0x0008 #define BCSR_INT_PC1 0x0010 #define BCSR_INT_PC1STSCHG 0x0020 -#define BCSR_INT_DC 0x0040 +#define BCSR_INT_DC 0x0040 #define BCSR_INT_FLASHBUSY 0x0080 #define BCSR_INT_PC0INSERT 0x0100 #define BCSR_INT_PC0EJECT 0x0200 @@ -174,14 +173,6 @@ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR; #define BCSR_INT_SD1INSERT 0x4000 #define BCSR_INT_SD1EJECT 0x8000 -/* PCMCIA Db1x00 specific defines */ -#define PCMCIA_MAX_SOCK 1 -#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1) - -/* VPP/VCC */ -#define SET_VCC_VPP(VCC, VPP, SLOT)\ - ((((VCC)<<2) | ((VPP)<<0)) << ((SLOT)*8)) - #define SMC91C111_PHYS_ADDR 0x0D000300 #define SMC91C111_INT PB1200_ETH_INT @@ -192,18 +183,19 @@ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR; #define IDE_DDMA_REQ DSCR_CMD0_DMA_REQ1 #define IDE_RQSIZE 128 -#define NAND_PHYS_ADDR 0x1C000000 +#define NAND_PHYS_ADDR 0x1C000000 -/* Timing values as described in databook, * ns value stripped of +/* + * Timing values as described in databook, * ns value stripped of * lower 2 bits. - * These defines are here rather than an SOC1200 generic file because + * These defines are here rather than an Au1200 generic file because * the parts chosen on another board may be different and may require * different timings. */ -#define NAND_T_H (18 >> 2) -#define NAND_T_PUL (30 >> 2) -#define NAND_T_SU (30 >> 2) -#define NAND_T_WH (30 >> 2) +#define NAND_T_H (18 >> 2) +#define NAND_T_PUL (30 >> 2) +#define NAND_T_SU (30 >> 2) +#define NAND_T_WH (30 >> 2) /* Bitfield shift amounts */ #define NAND_T_H_SHIFT 0 @@ -211,11 +203,10 @@ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR; #define NAND_T_SU_SHIFT 8 #define NAND_T_WH_SHIFT 12 -#define NAND_TIMING ((NAND_T_H & 0xF) << NAND_T_H_SHIFT) | \ - ((NAND_T_PUL & 0xF) << NAND_T_PUL_SHIFT) | \ - ((NAND_T_SU & 0xF) << NAND_T_SU_SHIFT) | \ - ((NAND_T_WH & 0xF) << NAND_T_WH_SHIFT) - +#define NAND_TIMING (((NAND_T_H & 0xF) << NAND_T_H_SHIFT) | \ + ((NAND_T_PUL & 0xF) << NAND_T_PUL_SHIFT) | \ + ((NAND_T_SU & 0xF) << NAND_T_SU_SHIFT) | \ + ((NAND_T_WH & 0xF) << NAND_T_WH_SHIFT)) /* * External Interrupts for Pb1200 as of 8/6/2004. @@ -248,13 +239,21 @@ enum external_pb1200_ints { PB1200_INT_END = PB1200_INT_BEGIN + 15 }; -/* For drivers/pcmcia/au1000_db1x00.c */ -#define BOARD_PC0_INT PB1200_PC0_INT -#define BOARD_PC1_INT PB1200_PC1_INT -#define BOARD_CARD_INSERTED(SOCKET) bcsr->sig_status & (1<<(8+(2*SOCKET))) +/* + * Pb1200 specific PCMCIA defines for drivers/pcmcia/au1000_db1x00.c + */ +#define PCMCIA_MAX_SOCK 1 +#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1) -/* Nand chip select */ +/* VPP/VCC */ +#define SET_VCC_VPP(VCC, VPP, SLOT) \ + ((((VCC) << 2) | ((VPP) << 0)) << ((SLOT) * 8)) + +#define BOARD_PC0_INT PB1200_PC0_INT +#define BOARD_PC1_INT PB1200_PC1_INT +#define BOARD_CARD_INSERTED(SOCKET) bcsr->sig_status & (1 << (8 + (2 * SOCKET))) + +/* NAND chip select */ #define NAND_CS 1 #endif /* __ASM_PB1200_H */ - diff --git a/include/asm-mips/mach-pb1x00/pb1500.h b/include/asm-mips/mach-pb1x00/pb1500.h index ff6d40c87a25b0859e8782d35ca99e089faa25da..da51a2eb7b82659a792cabda87c0b46f37487752 100644 --- a/include/asm-mips/mach-pb1x00/pb1500.h +++ b/include/asm-mips/mach-pb1x00/pb1500.h @@ -1,9 +1,8 @@ /* - * Alchemy Semi PB1500 Referrence Board + * Alchemy Semi Pb1500 Referrence Board * - * Copyright 2001 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com + * Copyright 2001, 2008 MontaVista Software Inc. + * Author: MontaVista Software, Inc. * * ######################################################################## * @@ -27,25 +26,24 @@ #ifndef __ASM_PB1500_H #define __ASM_PB1500_H +#define IDENT_BOARD_REG 0xAE000000 +#define BOARD_STATUS_REG 0xAE000004 +#define PCI_BOARD_REG 0xAE000010 +#define PCMCIA_BOARD_REG 0xAE000010 +# define PC_DEASSERT_RST 0x80 +# define PC_DRV_EN 0x10 +#define PB1500_G_CONTROL 0xAE000014 +#define PB1500_RST_VDDI 0xAE00001C +#define PB1500_LEDS 0xAE000018 -#define IDENT_BOARD_REG 0xAE000000 -#define BOARD_STATUS_REG 0xAE000004 -#define PCI_BOARD_REG 0xAE000010 -#define PCMCIA_BOARD_REG 0xAE000010 - #define PC_DEASSERT_RST 0x80 - #define PC_DRV_EN 0x10 -#define PB1500_G_CONTROL 0xAE000014 -#define PB1500_RST_VDDI 0xAE00001C -#define PB1500_LEDS 0xAE000018 +#define PB1500_HEX_LED 0xAF000004 +#define PB1500_HEX_LED_BLANK 0xAF000008 -#define PB1500_HEX_LED 0xAF000004 -#define PB1500_HEX_LED_BLANK 0xAF000008 - -/* PCMCIA PB1500 specific defines */ -#define PCMCIA_MAX_SOCK 0 -#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1) +/* PCMCIA Pb1500 specific defines */ +#define PCMCIA_MAX_SOCK 0 +#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1) /* VPP/VCC */ -#define SET_VCC_VPP(VCC, VPP) (((VCC)<<2) | ((VPP)<<0)) +#define SET_VCC_VPP(VCC, VPP) (((VCC) << 2) | ((VPP) << 0)) #endif /* __ASM_PB1500_H */ diff --git a/include/asm-mips/mach-pb1x00/pb1550.h b/include/asm-mips/mach-pb1x00/pb1550.h index c2ab0e2df4ae1f20d3d1ec294ef8dfb7bea0455b..6704a11497dbd701cccb62bdc822625ade559ac6 100644 --- a/include/asm-mips/mach-pb1x00/pb1550.h +++ b/include/asm-mips/mach-pb1x00/pb1550.h @@ -30,15 +30,15 @@ #include #include -#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX -#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX -#define DBDMA_I2S_TX_CHAN DSCR_CMD0_PSC3_TX -#define DBDMA_I2S_RX_CHAN DSCR_CMD0_PSC3_RX +#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX +#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX +#define DBDMA_I2S_TX_CHAN DSCR_CMD0_PSC3_TX +#define DBDMA_I2S_RX_CHAN DSCR_CMD0_PSC3_RX -#define SPI_PSC_BASE PSC0_BASE_ADDR -#define AC97_PSC_BASE PSC1_BASE_ADDR -#define SMBUS_PSC_BASE PSC2_BASE_ADDR -#define I2S_PSC_BASE PSC3_BASE_ADDR +#define SPI_PSC_BASE PSC0_BASE_ADDR +#define AC97_PSC_BASE PSC1_BASE_ADDR +#define SMBUS_PSC_BASE PSC2_BASE_ADDR +#define I2S_PSC_BASE PSC3_BASE_ADDR #define BCSR_PHYS_ADDR 0xAF000000 @@ -129,12 +129,12 @@ static BCSR * const bcsr = (BCSR *)BCSR_PHYS_ADDR; #define BCSR_SYSTEM_POWEROFF 0x4000 #define BCSR_SYSTEM_RESET 0x8000 -#define PCMCIA_MAX_SOCK 1 -#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1) +#define PCMCIA_MAX_SOCK 1 +#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1) /* VPP/VCC */ -#define SET_VCC_VPP(VCC, VPP, SLOT)\ - ((((VCC)<<2) | ((VPP)<<0)) << ((SLOT)*8)) +#define SET_VCC_VPP(VCC, VPP, SLOT) \ + ((((VCC) << 2) | ((VPP) << 0)) << ((SLOT) * 8)) #if defined(CONFIG_MTD_PB1550_BOOT) && defined(CONFIG_MTD_PB1550_USER) #define PB1550_BOTH_BANKS @@ -144,16 +144,17 @@ static BCSR * const bcsr = (BCSR *)BCSR_PHYS_ADDR; #define PB1550_USER_ONLY #endif -/* Timing values as described in databook, * ns value stripped of +/* + * Timing values as described in databook, * ns value stripped of * lower 2 bits. * These defines are here rather than an SOC1550 generic file because * the parts chosen on another board may be different and may require * different timings. */ -#define NAND_T_H (18 >> 2) -#define NAND_T_PUL (30 >> 2) -#define NAND_T_SU (30 >> 2) -#define NAND_T_WH (30 >> 2) +#define NAND_T_H (18 >> 2) +#define NAND_T_PUL (30 >> 2) +#define NAND_T_SU (30 >> 2) +#define NAND_T_WH (30 >> 2) /* Bitfield shift amounts */ #define NAND_T_H_SHIFT 0 @@ -161,16 +162,16 @@ static BCSR * const bcsr = (BCSR *)BCSR_PHYS_ADDR; #define NAND_T_SU_SHIFT 8 #define NAND_T_WH_SHIFT 12 -#define NAND_TIMING ((NAND_T_H & 0xF) << NAND_T_H_SHIFT) | \ - ((NAND_T_PUL & 0xF) << NAND_T_PUL_SHIFT) | \ - ((NAND_T_SU & 0xF) << NAND_T_SU_SHIFT) | \ - ((NAND_T_WH & 0xF) << NAND_T_WH_SHIFT) +#define NAND_TIMING (((NAND_T_H & 0xF) << NAND_T_H_SHIFT) | \ + ((NAND_T_PUL & 0xF) << NAND_T_PUL_SHIFT) | \ + ((NAND_T_SU & 0xF) << NAND_T_SU_SHIFT) | \ + ((NAND_T_WH & 0xF) << NAND_T_WH_SHIFT)) #define NAND_CS 1 -/* should be done by yamon */ -#define NAND_STCFG 0x00400005 /* 8-bit NAND */ -#define NAND_STTIME 0x00007774 /* valid for 396MHz SD=2 only */ -#define NAND_STADDR 0x12000FFF /* physical address 0x20000000 */ +/* Should be done by YAMON */ +#define NAND_STCFG 0x00400005 /* 8-bit NAND */ +#define NAND_STTIME 0x00007774 /* valid for 396 MHz SD=2 only */ +#define NAND_STADDR 0x12000FFF /* physical address 0x20000000 */ #endif /* __ASM_PB1550_H */ diff --git a/include/asm-mips/rtlx.h b/include/asm-mips/rtlx.h index 65778c890a62ef4ed3b06a673d7ce552ca616e2a..20b666022dcbdd08c66519ef76a9543ed7dc5487 100644 --- a/include/asm-mips/rtlx.h +++ b/include/asm-mips/rtlx.h @@ -29,13 +29,13 @@ extern unsigned int rtlx_read_poll(int index, int can_sleep); extern unsigned int rtlx_write_poll(int index); enum rtlx_state { - RTLX_STATE_UNUSED, + RTLX_STATE_UNUSED = 0, RTLX_STATE_INITIALISED, RTLX_STATE_REMOTE_READY, RTLX_STATE_OPENED }; -#define RTLX_BUFFER_SIZE 1024 +#define RTLX_BUFFER_SIZE 2048 /* each channel supports read and write. linux (vpe0) reads lx_buffer and writes rt_buffer diff --git a/include/asm-mn10300/processor.h b/include/asm-mn10300/processor.h index f1b081f53468b0713aef094f3abaaab338c4a72f..73239271873da304c88fe396eda7074686c3185a 100644 --- a/include/asm-mn10300/processor.h +++ b/include/asm-mn10300/processor.h @@ -58,7 +58,7 @@ extern struct mn10300_cpuinfo boot_cpu_data; extern void identify_cpu(struct mn10300_cpuinfo *); extern void print_cpu_info(struct mn10300_cpuinfo *); extern void dodgy_tsc(void); -#define cpu_relax() do {} while (0) +#define cpu_relax() barrier() /* * User space process size: 1.75GB (default). diff --git a/include/asm-parisc/assembly.h b/include/asm-parisc/assembly.h index 5587f00238815d876c427cbfbba4b0e246d3f275..ffb208840ecc62bc4e618498bffb13a44493cb83 100644 --- a/include/asm-parisc/assembly.h +++ b/include/asm-parisc/assembly.h @@ -31,9 +31,8 @@ #define STREGM std,ma #define SHRREG shrd #define SHLREG shld -#define ADDIB addib,* -#define CMPB cmpb,* #define ANDCM andcm,* +#define COND(x) * ## x #define RP_OFFSET 16 #define FRAME_SIZE 128 #define CALLEE_REG_FRAME_SIZE 144 @@ -46,9 +45,8 @@ #define STREGM stwm #define SHRREG shr #define SHLREG shlw -#define ADDIB addib, -#define CMPB cmpb, #define ANDCM andcm +#define COND(x) x #define RP_OFFSET 20 #define FRAME_SIZE 64 #define CALLEE_REG_FRAME_SIZE 128 diff --git a/include/asm-parisc/ioctl.h b/include/asm-parisc/ioctl.h index 68338d2bda4e37d9b1172369add7eac80f0d3974..ec8efa02beda9e01d52b47f2239e09ac35efcf0f 100644 --- a/include/asm-parisc/ioctl.h +++ b/include/asm-parisc/ioctl.h @@ -32,21 +32,6 @@ * NOTE: This limits the max parameter size to 16kB -1 ! */ -#define _IOC_NRBITS 8 -#define _IOC_TYPEBITS 8 -#define _IOC_SIZEBITS 14 -#define _IOC_DIRBITS 2 - -#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1) -#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1) -#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1) -#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1) - -#define _IOC_NRSHIFT 0 -#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS) -#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS) -#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS) - /* * Direction bits. */ @@ -54,40 +39,6 @@ #define _IOC_WRITE 2U #define _IOC_READ 1U -#define _IOC(dir,type,nr,size) \ - (((dir) << _IOC_DIRSHIFT) | \ - ((type) << _IOC_TYPESHIFT) | \ - ((nr) << _IOC_NRSHIFT) | \ - ((size) << _IOC_SIZESHIFT)) - -/* provoke compile error for invalid uses of size argument */ -extern unsigned int __invalid_size_argument_for_IOC; -#define _IOC_TYPECHECK(t) \ - ((sizeof(t) == sizeof(t[1]) && \ - sizeof(t) < (1 << _IOC_SIZEBITS)) ? \ - sizeof(t) : __invalid_size_argument_for_IOC) - -/* used to create numbers */ -#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0) -#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size))) -#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size))) -#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size))) -#define _IOR_BAD(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size)) -#define _IOW_BAD(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size)) -#define _IOWR_BAD(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size)) - -/* used to decode ioctl numbers.. */ -#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) -#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK) -#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK) -#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK) - -/* ...and for the drivers/sound files... */ - -#define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT) -#define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT) -#define IOC_INOUT ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT) -#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT) -#define IOCSIZE_SHIFT (_IOC_SIZESHIFT) +#include #endif /* _ASM_PARISC_IOCTL_H */ diff --git a/include/asm-parisc/ioctls.h b/include/asm-parisc/ioctls.h index ee84e4172c3602b209ae58d38d680450a63b2abc..6747fad07a3ecd01a84f19b4d7fa962e1a7cbd16 100644 --- a/include/asm-parisc/ioctls.h +++ b/include/asm-parisc/ioctls.h @@ -46,6 +46,10 @@ #define TIOCSBRK 0x5427 /* BSD compatibility */ #define TIOCCBRK 0x5428 /* BSD compatibility */ #define TIOCGSID _IOR('T', 20, int) /* Return the session ID of FD */ +#define TCGETS2 _IOR('T',0x2A, struct termios2) +#define TCSETS2 _IOW('T',0x2B, struct termios2) +#define TCSETSW2 _IOW('T',0x2C, struct termios2) +#define TCSETSF2 _IOW('T',0x2D, struct termios2) #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ diff --git a/include/asm-parisc/termbits.h b/include/asm-parisc/termbits.h index e847fe979684fc0a73c45f42524911936dfe4cdb..d8bbc73b16b7f6915e85b8108d31e5b3199d9ca2 100644 --- a/include/asm-parisc/termbits.h +++ b/include/asm-parisc/termbits.h @@ -141,6 +141,7 @@ struct ktermios { #define HUPCL 0002000 #define CLOCAL 0004000 #define CBAUDEX 0010000 +#define BOTHER 0010000 #define B57600 0010001 #define B115200 0010002 #define B230400 0010003 @@ -156,10 +157,12 @@ struct ktermios { #define B3000000 0010015 #define B3500000 0010016 #define B4000000 0010017 -#define CIBAUD 002003600000 /* input baud rate (not used) */ +#define CIBAUD 002003600000 /* input baud rate */ #define CMSPAR 010000000000 /* mark or space (stick) parity */ #define CRTSCTS 020000000000 /* flow control */ +#define IBSHIFT 16 /* Shift from CBAUD to CIBAUD */ + /* c_lflag bits */ #define ISIG 0000001 diff --git a/include/asm-parisc/termios.h b/include/asm-parisc/termios.h index 5345b34204759d2dc257df39005757537fd4787a..a2a57a4548af7bd6d7c745a54d755d6a8fa0418e 100644 --- a/include/asm-parisc/termios.h +++ b/include/asm-parisc/termios.h @@ -80,8 +80,10 @@ struct termio { copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \ }) -#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios)) -#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios)) +#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios2)) +#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios2)) +#define user_termios_to_kernel_termios_1(k, u) copy_from_user(k, u, sizeof(struct termios)) +#define kernel_termios_to_user_termios_1(u, k) copy_to_user(u, k, sizeof(struct termios)) #endif /* __KERNEL__ */ diff --git a/include/asm-powerpc/mmu-hash64.h b/include/asm-powerpc/mmu-hash64.h index 0dff76776044dde1c5ced93d86079f875fb0a062..39c5c5f62bf5bd740fd92568aa030c4afaff84f3 100644 --- a/include/asm-powerpc/mmu-hash64.h +++ b/include/asm-powerpc/mmu-hash64.h @@ -177,6 +177,7 @@ extern struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT]; extern int mmu_linear_psize; extern int mmu_virtual_psize; extern int mmu_vmalloc_psize; +extern int mmu_vmemmap_psize; extern int mmu_io_psize; extern int mmu_kernel_ssize; extern int mmu_highuser_ssize; diff --git a/include/asm-powerpc/pgtable-ppc32.h b/include/asm-powerpc/pgtable-ppc32.h index 7c97b5a08d082782807d33467c5864ce0a2a6db6..c08e714d0c42880dd785df64a93f3b8ad3a1c838 100644 --- a/include/asm-powerpc/pgtable-ppc32.h +++ b/include/asm-powerpc/pgtable-ppc32.h @@ -209,6 +209,13 @@ extern int icache_44x_need_flush; * 0 1 2 3 4 ... 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 * - - - - - - U0 U1 U2 U3 W I M G E - UX UW UR SX SW SR * + * Newer 440 cores (440x6 as used on AMCC 460EX/460GT) have additional + * TLB2 storage attibute fields. Those are: + * + * TLB2: + * 0...10 11 12 13 14 15 16...31 + * no change WL1 IL1I IL1D IL2I IL2D no change + * * There are some constrains and options, to decide mapping software bits * into TLB entry. * diff --git a/include/asm-powerpc/pgtable-ppc64.h b/include/asm-powerpc/pgtable-ppc64.h index 27f18695f7d6627f18071b6870281a665a431fef..cc6a43ba41d0fd5d1bca0df28d4b5e310008cb05 100644 --- a/include/asm-powerpc/pgtable-ppc64.h +++ b/include/asm-powerpc/pgtable-ppc64.h @@ -65,15 +65,15 @@ #define VMALLOC_REGION_ID (REGION_ID(VMALLOC_START)) #define KERNEL_REGION_ID (REGION_ID(PAGE_OFFSET)) +#define VMEMMAP_REGION_ID (0xfUL) #define USER_REGION_ID (0UL) /* - * Defines the address of the vmemap area, in the top 16th of the - * kernel region. + * Defines the address of the vmemap area, in its own region */ -#define VMEMMAP_BASE (ASM_CONST(CONFIG_KERNEL_START) + \ - (0xfUL << (REGION_SHIFT - 4))) -#define vmemmap ((struct page *)VMEMMAP_BASE) +#define VMEMMAP_BASE (VMEMMAP_REGION_ID << REGION_SHIFT) +#define vmemmap ((struct page *)VMEMMAP_BASE) + /* * Common bits in a linux-style PTE. These match the bits in the diff --git a/include/asm-powerpc/spu.h b/include/asm-powerpc/spu.h index e3c845b0f76438af611c8450c36e4660b076207b..6abead6e681aacd732efc40c5fd0431824af8f37 100644 --- a/include/asm-powerpc/spu.h +++ b/include/asm-powerpc/spu.h @@ -100,6 +100,7 @@ /* Flag indicating progress during context switch. */ #define SPU_CONTEXT_SWITCH_PENDING 0UL +#define SPU_CONTEXT_FAULT_PENDING 1UL struct spu_context; struct spu_runqueue; @@ -128,9 +129,11 @@ struct spu { unsigned int irqs[3]; u32 node; u64 flags; - u64 dar; - u64 dsisr; u64 class_0_pending; + u64 class_0_dar; + u64 class_0_dsisr; + u64 class_1_dar; + u64 class_1_dsisr; size_t ls_size; unsigned int slb_replace; struct mm_struct *mm; @@ -143,7 +146,7 @@ struct spu { void (* wbox_callback)(struct spu *spu); void (* ibox_callback)(struct spu *spu); - void (* stop_callback)(struct spu *spu); + void (* stop_callback)(struct spu *spu, int irq); void (* mfc_callback)(struct spu *spu); char irq_c0[8]; diff --git a/include/asm-powerpc/spu_csa.h b/include/asm-powerpc/spu_csa.h index 0ab6bff86078e955dd10c3da1c282fe29773f33f..129ec148d4512b1a63ac6dbcbf3321ac07712ba9 100644 --- a/include/asm-powerpc/spu_csa.h +++ b/include/asm-powerpc/spu_csa.h @@ -254,7 +254,8 @@ struct spu_state { u64 spu_chnldata_RW[32]; u32 spu_mailbox_data[4]; u32 pu_mailbox_data[1]; - u64 dar, dsisr, class_0_pending; + u64 class_0_dar, class_0_dsisr, class_0_pending; + u64 class_1_dar, class_1_dsisr; unsigned long suspend_time; spinlock_t register_lock; }; diff --git a/include/asm-powerpc/uaccess.h b/include/asm-powerpc/uaccess.h index 8e798e3758bc38137ca15d2f0e23c954e0339c26..1a0736f8803fa8db84de6b428ae808c95b49b835 100644 --- a/include/asm-powerpc/uaccess.h +++ b/include/asm-powerpc/uaccess.h @@ -380,7 +380,7 @@ static inline unsigned long __copy_from_user_inatomic(void *to, const void __user *from, unsigned long n) { if (__builtin_constant_p(n) && (n <= 8)) { - unsigned long ret; + unsigned long ret = 1; switch (n) { case 1: @@ -406,7 +406,7 @@ static inline unsigned long __copy_to_user_inatomic(void __user *to, const void *from, unsigned long n) { if (__builtin_constant_p(n) && (n <= 8)) { - unsigned long ret; + unsigned long ret = 1; switch (n) { case 1: diff --git a/include/asm-ppc/system.h b/include/asm-ppc/system.h index 0593cb889d45306cf6dac6f5b837ccbca081935f..70ebd333c55b24f474a7349f43047566f198b67e 100644 --- a/include/asm-ppc/system.h +++ b/include/asm-ppc/system.h @@ -178,7 +178,7 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size } -extern inline void * xchg_ptr(void * m, void * val) +static inline void * xchg_ptr(void * m, void * val) { return (void *) xchg_u32(m, (unsigned long) val); } diff --git a/include/asm-s390/debug.h b/include/asm-s390/debug.h index 335baf4fc64f59991c2d37fb965e7de46006ef6b..9450ce6e32defae5e57a6cd8e138506b350e4b0f 100644 --- a/include/asm-s390/debug.h +++ b/include/asm-s390/debug.h @@ -120,10 +120,10 @@ debug_entry_t* debug_exception_common(debug_info_t* id, int level, /* Debug Feature API: */ -debug_info_t* debug_register(char* name, int pages, int nr_areas, +debug_info_t *debug_register(const char *name, int pages, int nr_areas, int buf_size); -debug_info_t *debug_register_mode(char *name, int pages, int nr_areas, +debug_info_t *debug_register_mode(const char *name, int pages, int nr_areas, int buf_size, mode_t mode, uid_t uid, gid_t gid); diff --git a/include/asm-s390/kvm_host.h b/include/asm-s390/kvm_host.h index f8204a4f2e0260917655a7877f126e9a53cd2186..18cbd8a39796c126fb9e1609f333c516d86a2e9d 100644 --- a/include/asm-s390/kvm_host.h +++ b/include/asm-s390/kvm_host.h @@ -104,6 +104,7 @@ struct sie_block { struct kvm_vcpu_stat { u32 exit_userspace; + u32 exit_null; u32 exit_external_request; u32 exit_external_interrupt; u32 exit_stop_request; diff --git a/include/asm-s390/page.h b/include/asm-s390/page.h index f0f4579eac13144b01f43eaf401428dfb2d8c5db..12fd9c4f0f154fe86baaed66c71103d24b15f65a 100644 --- a/include/asm-s390/page.h +++ b/include/asm-s390/page.h @@ -125,6 +125,17 @@ page_get_storage_key(unsigned long addr) return skey; } +#ifdef CONFIG_PAGE_STATES + +struct page; +void arch_free_page(struct page *page, int order); +void arch_alloc_page(struct page *page, int order); + +#define HAVE_ARCH_FREE_PAGE +#define HAVE_ARCH_ALLOC_PAGE + +#endif + #endif /* !__ASSEMBLY__ */ /* to align the pointer to the (next) page boundary */ diff --git a/include/asm-s390/ptrace.h b/include/asm-s390/ptrace.h index 441d7c260857845cd6e0e1b557277565c448a2cd..d7d4e2eb3e6f327b8528387d2f1a3822fc8820c6 100644 --- a/include/asm-s390/ptrace.h +++ b/include/asm-s390/ptrace.h @@ -471,6 +471,8 @@ struct task_struct; extern void user_enable_single_step(struct task_struct *); extern void user_disable_single_step(struct task_struct *); +#define __ARCH_WANT_COMPAT_SYS_PTRACE + #define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0) #define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN) #define regs_return_value(regs)((regs)->gprs[2]) diff --git a/include/asm-s390/system.h b/include/asm-s390/system.h index c819ae25a8425ddfd72136dda4d674bf0f8b0ac1..e0d4500d5f95c14478205c60269849a8d5852ace 100644 --- a/include/asm-s390/system.h +++ b/include/asm-s390/system.h @@ -116,6 +116,12 @@ extern void pfault_fini(void); #define pfault_fini() do { } while (0) #endif /* CONFIG_PFAULT */ +#ifdef CONFIG_PAGE_STATES +extern void cmma_init(void); +#else +static inline void cmma_init(void) { } +#endif + #define finish_arch_switch(prev) do { \ set_fs(current->thread.mm_segment); \ account_vtime(prev); \ diff --git a/include/asm-s390/types.h b/include/asm-s390/types.h index 78dda038dd47c3b60e153e78dab2e67ac5f16dda..0e959e20e9a310fa84812b824c5a64fb3229bf1d 100644 --- a/include/asm-s390/types.h +++ b/include/asm-s390/types.h @@ -10,9 +10,9 @@ #define _S390_TYPES_H #ifndef __s390x__ -# include -#else # include +#else +# include #endif #ifndef __ASSEMBLY__ diff --git a/include/asm-sh/cpu-sh3/dma.h b/include/asm-sh/cpu-sh3/dma.h index 092ff9d872c3e6cf352236e82e32466c116defb6..6813c3220a1d7a6693d2481d7dccda4cd7b3e76b 100644 --- a/include/asm-sh/cpu-sh3/dma.h +++ b/include/asm-sh/cpu-sh3/dma.h @@ -3,19 +3,19 @@ #if defined(CONFIG_CPU_SUBTYPE_SH7720) || \ - defined(CONFIG_CPU_SUBTYPE_SH7721) || \ - defined(CONFIG_CPU_SUBTYPE_SH7709) + defined(CONFIG_CPU_SUBTYPE_SH7721) #define SH_DMAC_BASE 0xa4010020 +#else +#define SH_DMAC_BASE 0xa4000020 +#endif +#if defined(CONFIG_CPU_SUBTYPE_SH7720) || defined(CONFIG_CPU_SUBTYPE_SH7709) #define DMTE0_IRQ 48 #define DMTE1_IRQ 49 #define DMTE2_IRQ 50 #define DMTE3_IRQ 51 #define DMTE4_IRQ 76 #define DMTE5_IRQ 77 - -#else -#define SH_DMAC_BASE 0xa4000020 #endif /* Definitions for the SuperH DMAC */ diff --git a/include/asm-sh/hw_irq.h b/include/asm-sh/hw_irq.h index c958fdaa00957ec835f2b7b1803baef4f5eb12d7..7438d1e21bc9b91feb4186d00ef996acb6dd50b6 100644 --- a/include/asm-sh/hw_irq.h +++ b/include/asm-sh/hw_irq.h @@ -79,6 +79,10 @@ struct intc_desc { struct intc_sense_reg *sense_regs; unsigned int nr_sense_regs; char *name; +#ifdef CONFIG_CPU_SH3 + struct intc_mask_reg *ack_regs; + unsigned int nr_ack_regs; +#endif }; #define _INTC_ARRAY(a) a, sizeof(a)/sizeof(*a) @@ -91,10 +95,25 @@ struct intc_desc symbol __initdata = { \ chipname, \ } +#ifdef CONFIG_CPU_SH3 +#define DECLARE_INTC_DESC_ACK(symbol, chipname, vectors, groups, \ + mask_regs, prio_regs, sense_regs, ack_regs) \ +struct intc_desc symbol __initdata = { \ + _INTC_ARRAY(vectors), _INTC_ARRAY(groups), \ + _INTC_ARRAY(mask_regs), _INTC_ARRAY(prio_regs), \ + _INTC_ARRAY(sense_regs), \ + chipname, \ + _INTC_ARRAY(ack_regs), \ +} +#endif + void __init register_intc_controller(struct intc_desc *desc); int intc_set_priority(unsigned int irq, unsigned int prio); void __init plat_irq_setup(void); +#ifdef CONFIG_CPU_SH3 +void __init plat_irq_setup_sh3(void); +#endif enum { IRQ_MODE_IRQ, IRQ_MODE_IRQ7654, IRQ_MODE_IRQ3210, IRQ_MODE_IRL7654_MASK, IRQ_MODE_IRL3210_MASK, diff --git a/include/asm-sh/io.h b/include/asm-sh/io.h index 356e50d067456ccbdd1cd9e2fefa37af5f5ee2b9..a4fbf0c84fb14aecf694379038d2d579c6607e2a 100644 --- a/include/asm-sh/io.h +++ b/include/asm-sh/io.h @@ -268,11 +268,6 @@ unsigned long long peek_real_address_q(unsigned long long addr); unsigned long long poke_real_address_q(unsigned long long addr, unsigned long long val); -/* arch/sh/mm/ioremap_64.c */ -unsigned long onchip_remap(unsigned long addr, unsigned long size, - const char *name); -extern void onchip_unmap(unsigned long vaddr); - #if !defined(CONFIG_MMU) #define virt_to_phys(address) ((unsigned long)(address)) #define phys_to_virt(address) ((void *)(address)) @@ -302,9 +297,16 @@ extern void onchip_unmap(unsigned long vaddr); void __iomem *__ioremap(unsigned long offset, unsigned long size, unsigned long flags); void __iounmap(void __iomem *addr); + +/* arch/sh/mm/ioremap_64.c */ +unsigned long onchip_remap(unsigned long addr, unsigned long size, + const char *name); +extern void onchip_unmap(unsigned long vaddr); #else #define __ioremap(offset, size, flags) ((void __iomem *)(offset)) #define __iounmap(addr) do { } while (0) +#define onchip_remap(addr, size, name) (addr) +#define onchip_unmap(addr) do { } while (0) #endif /* CONFIG_MMU */ static inline void __iomem * diff --git a/include/asm-sh/keyboard.h b/include/asm-sh/keyboard.h deleted file mode 100644 index 31dcc4fa5f2893d1286b4884b66231c925e37d4e..0000000000000000000000000000000000000000 --- a/include/asm-sh/keyboard.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef __ASM_SH_KEYBOARD_H -#define __ASM_SH_KEYBOARD_H -/* - * $Id: keyboard.h,v 1.1.1.1 2001/10/15 20:45:09 mrbrown Exp $ - */ - -#include -#include - -#ifdef CONFIG_SH_MPC1211 -#include -#endif -#endif diff --git a/include/asm-sh/kgdb.h b/include/asm-sh/kgdb.h index 4bc8cb187d119a8d66bff3995b9f7add0d79e09d..24e42078f36fa80e780cebd92204bacb62ab3e5e 100644 --- a/include/asm-sh/kgdb.h +++ b/include/asm-sh/kgdb.h @@ -66,18 +66,4 @@ extern int setjmp(jmp_buf __jmpb); /* Forced breakpoint */ #define breakpoint() __asm__ __volatile__("trapa #0x3c") -/* Taken from sh-stub.c of GDB 4.18 */ -static const char hexchars[] = "0123456789abcdef"; - -/* Get high hex bits */ -static inline char highhex(const int x) -{ - return hexchars[(x >> 4) & 0xf]; -} - -/* Get low hex bits */ -static inline char lowhex(const int x) -{ - return hexchars[x & 0xf]; -} #endif diff --git a/include/asm-sh/mmu_context.h b/include/asm-sh/mmu_context.h index fe58d00b250ce177e05512d4eaa8f1c9f8eb0273..87e812f68bb06d11c83b5ecca25b72d5cb35366b 100644 --- a/include/asm-sh/mmu_context.h +++ b/include/asm-sh/mmu_context.h @@ -27,6 +27,7 @@ /* ASID is 8-bit value, so it can't be 0x100 */ #define MMU_NO_ASID 0x100 +#ifdef CONFIG_MMU #define asid_cache(cpu) (cpu_data[cpu].asid_cache) #define cpu_context(cpu, mm) ((mm)->context.id[cpu]) @@ -38,7 +39,6 @@ */ #define MMU_VPN_MASK 0xfffff000 -#ifdef CONFIG_MMU #if defined(CONFIG_SUPERH32) #include "mmu_context_32.h" #else @@ -129,6 +129,8 @@ static inline void switch_mm(struct mm_struct *prev, #define destroy_context(mm) do { } while (0) #define set_asid(asid) do { } while (0) #define get_asid() (0) +#define cpu_asid(cpu, mm) ({ (void)cpu; 0; }) +#define switch_and_save_asid(asid) (0) #define set_TTB(pgd) do { } while (0) #define get_TTB() (0) #define activate_context(mm,cpu) do { } while (0) diff --git a/include/asm-sh/mmzone.h b/include/asm-sh/mmzone.h index 7969f381dff2122133ac1f8ad4a399dc2124bc82..2969253c40421a90d2da89b7856c35cf2405138d 100644 --- a/include/asm-sh/mmzone.h +++ b/include/asm-sh/mmzone.h @@ -41,6 +41,8 @@ void __init plat_mem_setup(void); /* arch/sh/kernel/setup.c */ void __init setup_bootmem_allocator(unsigned long start_pfn); +void __init __add_active_range(unsigned int nid, unsigned long start_pfn, + unsigned long end_pfn); #endif /* __KERNEL__ */ #endif /* __ASM_SH_MMZONE_H */ diff --git a/include/asm-sh/mpc1211/dma.h b/include/asm-sh/mpc1211/dma.h deleted file mode 100644 index e506d1aaa0d00c4637a6b28ddafe56b80065e80b..0000000000000000000000000000000000000000 --- a/include/asm-sh/mpc1211/dma.h +++ /dev/null @@ -1,303 +0,0 @@ -/* $Id: dma.h,v 1.7 1992/12/14 00:29:34 root Exp root $ - * linux/include/asm/dma.h: Defines for using and allocating dma channels. - * Written by Hennus Bergman, 1992. - * High DMA channel support & info by Hannu Savolainen - * and John Boyd, Nov. 1992. - */ - -#ifndef _ASM_MPC1211_DMA_H -#define _ASM_MPC1211_DMA_H - -#include /* And spinlocks */ -#include /* need byte IO */ -#include - - -#ifdef HAVE_REALLY_SLOW_DMA_CONTROLLER -#define dma_outb outb_p -#else -#define dma_outb outb -#endif - -#define dma_inb inb - -/* - * NOTES about DMA transfers: - * - * controller 1: channels 0-3, byte operations, ports 00-1F - * controller 2: channels 4-7, word operations, ports C0-DF - * - * - ALL registers are 8 bits only, regardless of transfer size - * - channel 4 is not used - cascades 1 into 2. - * - channels 0-3 are byte - addresses/counts are for physical bytes - * - channels 5-7 are word - addresses/counts are for physical words - * - transfers must not cross physical 64K (0-3) or 128K (5-7) boundaries - * - transfer count loaded to registers is 1 less than actual count - * - controller 2 offsets are all even (2x offsets for controller 1) - * - page registers for 5-7 don't use data bit 0, represent 128K pages - * - page registers for 0-3 use bit 0, represent 64K pages - * - * DMA transfers are limited to the lower 16MB of _physical_ memory. - * Note that addresses loaded into registers must be _physical_ addresses, - * not logical addresses (which may differ if paging is active). - * - * Address mapping for channels 0-3: - * - * A23 ... A16 A15 ... A8 A7 ... A0 (Physical addresses) - * | ... | | ... | | ... | - * | ... | | ... | | ... | - * | ... | | ... | | ... | - * P7 ... P0 A7 ... A0 A7 ... A0 - * | Page | Addr MSB | Addr LSB | (DMA registers) - * - * Address mapping for channels 5-7: - * - * A23 ... A17 A16 A15 ... A9 A8 A7 ... A1 A0 (Physical addresses) - * | ... | \ \ ... \ \ \ ... \ \ - * | ... | \ \ ... \ \ \ ... \ (not used) - * | ... | \ \ ... \ \ \ ... \ - * P7 ... P1 (0) A7 A6 ... A0 A7 A6 ... A0 - * | Page | Addr MSB | Addr LSB | (DMA registers) - * - * Again, channels 5-7 transfer _physical_ words (16 bits), so addresses - * and counts _must_ be word-aligned (the lowest address bit is _ignored_ at - * the hardware level, so odd-byte transfers aren't possible). - * - * Transfer count (_not # bytes_) is limited to 64K, represented as actual - * count - 1 : 64K => 0xFFFF, 1 => 0x0000. Thus, count is always 1 or more, - * and up to 128K bytes may be transferred on channels 5-7 in one operation. - * - */ - -#define MAX_DMA_CHANNELS 8 - -/* The maximum address that we can perform a DMA transfer to on this platform */ -#define MAX_DMA_ADDRESS (PAGE_OFFSET+0x10000000) - -/* 8237 DMA controllers */ -#define IO_DMA1_BASE 0x00 /* 8 bit slave DMA, channels 0..3 */ -#define IO_DMA2_BASE 0xC0 /* 16 bit master DMA, ch 4(=slave input)..7 */ - -/* DMA controller registers */ -#define DMA1_CMD_REG 0x08 /* command register (w) */ -#define DMA1_STAT_REG 0x08 /* status register (r) */ -#define DMA1_REQ_REG 0x09 /* request register (w) */ -#define DMA1_MASK_REG 0x0A /* single-channel mask (w) */ -#define DMA1_MODE_REG 0x0B /* mode register (w) */ -#define DMA1_CLEAR_FF_REG 0x0C /* clear pointer flip-flop (w) */ -#define DMA1_TEMP_REG 0x0D /* Temporary Register (r) */ -#define DMA1_RESET_REG 0x0D /* Master Clear (w) */ -#define DMA1_CLR_MASK_REG 0x0E /* Clear Mask */ -#define DMA1_MASK_ALL_REG 0x0F /* all-channels mask (w) */ - -#define DMA2_CMD_REG 0xD0 /* command register (w) */ -#define DMA2_STAT_REG 0xD0 /* status register (r) */ -#define DMA2_REQ_REG 0xD2 /* request register (w) */ -#define DMA2_MASK_REG 0xD4 /* single-channel mask (w) */ -#define DMA2_MODE_REG 0xD6 /* mode register (w) */ -#define DMA2_CLEAR_FF_REG 0xD8 /* clear pointer flip-flop (w) */ -#define DMA2_TEMP_REG 0xDA /* Temporary Register (r) */ -#define DMA2_RESET_REG 0xDA /* Master Clear (w) */ -#define DMA2_CLR_MASK_REG 0xDC /* Clear Mask */ -#define DMA2_MASK_ALL_REG 0xDE /* all-channels mask (w) */ - -#define DMA_ADDR_0 0x00 /* DMA address registers */ -#define DMA_ADDR_1 0x02 -#define DMA_ADDR_2 0x04 -#define DMA_ADDR_3 0x06 -#define DMA_ADDR_4 0xC0 -#define DMA_ADDR_5 0xC4 -#define DMA_ADDR_6 0xC8 -#define DMA_ADDR_7 0xCC - -#define DMA_CNT_0 0x01 /* DMA count registers */ -#define DMA_CNT_1 0x03 -#define DMA_CNT_2 0x05 -#define DMA_CNT_3 0x07 -#define DMA_CNT_4 0xC2 -#define DMA_CNT_5 0xC6 -#define DMA_CNT_6 0xCA -#define DMA_CNT_7 0xCE - -#define DMA_PAGE_0 0x87 /* DMA page registers */ -#define DMA_PAGE_1 0x83 -#define DMA_PAGE_2 0x81 -#define DMA_PAGE_3 0x82 -#define DMA_PAGE_5 0x8B -#define DMA_PAGE_6 0x89 -#define DMA_PAGE_7 0x8A - -#define DMA_MODE_READ 0x44 /* I/O to memory, no autoinit, increment, single mode */ -#define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */ -#define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */ - -#define DMA_AUTOINIT 0x10 - - -extern spinlock_t dma_spin_lock; - -static __inline__ unsigned long claim_dma_lock(void) -{ - unsigned long flags; - spin_lock_irqsave(&dma_spin_lock, flags); - return flags; -} - -static __inline__ void release_dma_lock(unsigned long flags) -{ - spin_unlock_irqrestore(&dma_spin_lock, flags); -} - -/* enable/disable a specific DMA channel */ -static __inline__ void enable_dma(unsigned int dmanr) -{ - if (dmanr<=3) - dma_outb(dmanr, DMA1_MASK_REG); - else - dma_outb(dmanr & 3, DMA2_MASK_REG); -} - -static __inline__ void disable_dma(unsigned int dmanr) -{ - if (dmanr<=3) - dma_outb(dmanr | 4, DMA1_MASK_REG); - else - dma_outb((dmanr & 3) | 4, DMA2_MASK_REG); -} - -/* Clear the 'DMA Pointer Flip Flop'. - * Write 0 for LSB/MSB, 1 for MSB/LSB access. - * Use this once to initialize the FF to a known state. - * After that, keep track of it. :-) - * --- In order to do that, the DMA routines below should --- - * --- only be used while holding the DMA lock ! --- - */ -static __inline__ void clear_dma_ff(unsigned int dmanr) -{ - if (dmanr<=3) - dma_outb(0, DMA1_CLEAR_FF_REG); - else - dma_outb(0, DMA2_CLEAR_FF_REG); -} - -/* set mode (above) for a specific DMA channel */ -static __inline__ void set_dma_mode(unsigned int dmanr, char mode) -{ - if (dmanr<=3) - dma_outb(mode | dmanr, DMA1_MODE_REG); - else - dma_outb(mode | (dmanr&3), DMA2_MODE_REG); -} - -/* Set only the page register bits of the transfer address. - * This is used for successive transfers when we know the contents of - * the lower 16 bits of the DMA current address register, but a 64k boundary - * may have been crossed. - */ -static __inline__ void set_dma_page(unsigned int dmanr, unsigned int pagenr) -{ - switch(dmanr) { - case 0: - dma_outb( pagenr & 0xff, DMA_PAGE_0); - dma_outb((pagenr >> 8) & 0xff, DMA_PAGE_0 + 0x400); - break; - case 1: - dma_outb( pagenr & 0xff, DMA_PAGE_1); - dma_outb((pagenr >> 8) & 0xff, DMA_PAGE_1 + 0x400); - break; - case 2: - dma_outb( pagenr & 0xff, DMA_PAGE_2); - dma_outb((pagenr >> 8) & 0xff, DMA_PAGE_2 + 0x400); - break; - case 3: - dma_outb( pagenr & 0xff, DMA_PAGE_3); - dma_outb((pagenr >> 8) & 0xff, DMA_PAGE_3 + 0x400); - break; - case 5: - dma_outb( pagenr & 0xfe, DMA_PAGE_5); - dma_outb((pagenr >> 8) & 0xff, DMA_PAGE_5 + 0x400); - break; - case 6: - dma_outb( pagenr & 0xfe, DMA_PAGE_6); - dma_outb((pagenr >> 8) & 0xff, DMA_PAGE_6 + 0x400); - break; - case 7: - dma_outb( pagenr & 0xfe, DMA_PAGE_7); - dma_outb((pagenr >> 8) & 0xff, DMA_PAGE_7 + 0x400); - break; - } -} - - -/* Set transfer address & page bits for specific DMA channel. - * Assumes dma flipflop is clear. - */ -static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a) -{ - set_dma_page(dmanr, a>>16); - if (dmanr <= 3) { - dma_outb( a & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE ); - dma_outb( (a>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE ); - } else { - dma_outb( (a>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE ); - dma_outb( (a>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE ); - } -} - - -/* Set transfer size (max 64k for DMA1..3, 128k for DMA5..7) for - * a specific DMA channel. - * You must ensure the parameters are valid. - * NOTE: from a manual: "the number of transfers is one more - * than the initial word count"! This is taken into account. - * Assumes dma flip-flop is clear. - * NOTE 2: "count" represents _bytes_ and must be even for channels 5-7. - */ -static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count) -{ - count--; - if (dmanr <= 3) { - dma_outb( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE ); - dma_outb( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE ); - } else { - dma_outb( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE ); - dma_outb( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE ); - } -} - - -/* Get DMA residue count. After a DMA transfer, this - * should return zero. Reading this while a DMA transfer is - * still in progress will return unpredictable results. - * If called before the channel has been used, it may return 1. - * Otherwise, it returns the number of _bytes_ left to transfer. - * - * Assumes DMA flip-flop is clear. - */ -static __inline__ int get_dma_residue(unsigned int dmanr) -{ - unsigned int io_port = (dmanr<=3)? ((dmanr&3)<<1) + 1 + IO_DMA1_BASE - : ((dmanr&3)<<2) + 2 + IO_DMA2_BASE; - - /* using short to get 16-bit wrap around */ - unsigned short count; - - count = 1 + dma_inb(io_port); - count += dma_inb(io_port) << 8; - return (dmanr<=3)? count : (count<<1); -} - - -/* These are in kernel/dma.c: */ -extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */ -extern void free_dma(unsigned int dmanr); /* release it again */ - -/* From PCI */ - -#ifdef CONFIG_PCI -extern int isa_dma_bridge_buggy; -#else -#define isa_dma_bridge_buggy (0) -#endif - -#endif /* _ASM_MPC1211_DMA_H */ diff --git a/include/asm-sh/mpc1211/io.h b/include/asm-sh/mpc1211/io.h deleted file mode 100644 index 6298370bec2ddf781429280b4625fc91611b55c6..0000000000000000000000000000000000000000 --- a/include/asm-sh/mpc1211/io.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * include/asm-sh/mpc1211/io.h - * - * Copyright 2001 Saito.K & Jeanne - * - * IO functions for an Interface MPC-1211 - */ - -#ifndef _ASM_SH_IO_MPC1211_H -#define _ASM_SH_IO_MPC1211_H - -#include - -extern int mpc1211_irq_demux(int irq); - -extern void init_mpc1211_IRQ(void); -extern void heartbeat_mpc1211(void); - -extern void mpc1211_rtc_gettimeofday(struct timeval *tv); -extern int mpc1211_rtc_settimeofday(const struct timeval *tv); - -#endif /* _ASM_SH_IO_MPC1211_H */ diff --git a/include/asm-sh/mpc1211/keyboard.h b/include/asm-sh/mpc1211/keyboard.h deleted file mode 100644 index 9020feee7b4c472327cb758555ba7f0c8db51c88..0000000000000000000000000000000000000000 --- a/include/asm-sh/mpc1211/keyboard.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * MPC1211 specific keybord definitions - * Taken from the old asm-i386/keybord.h for PC/AT-style definitions - * created 3 Nov 1996 by Geert Uytterhoeven. - */ - -#ifdef __KERNEL__ - -#include -#include -#include -#include -#include - -#define KEYBOARD_IRQ 1 -#define DISABLE_KBD_DURING_INTERRUPTS 0 - -extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode); -extern int pckbd_getkeycode(unsigned int scancode); -extern int pckbd_translate(unsigned char scancode, unsigned char *keycode, - char raw_mode); -extern char pckbd_unexpected_up(unsigned char keycode); -extern void pckbd_leds(unsigned char leds); -extern void pckbd_init_hw(void); -extern int pckbd_pm_resume(struct pm_dev *, pm_request_t, void *); -extern pm_callback pm_kbd_request_override; - -#define kbd_setkeycode pckbd_setkeycode -#define kbd_getkeycode pckbd_getkeycode -#define kbd_translate pckbd_translate -#define kbd_unexpected_up pckbd_unexpected_up -#define kbd_leds pckbd_leds -#define kbd_init_hw pckbd_init_hw - -/* resource allocation */ -#define kbd_request_region() -#define kbd_request_irq(handler) request_irq(KEYBOARD_IRQ, handler, 0, \ - "keyboard", NULL) - -/* How to access the keyboard macros on this platform. */ -#define kbd_read_input() inb(KBD_DATA_REG) -#define kbd_read_status() inb(KBD_STATUS_REG) -#define kbd_write_output(val) outb(val, KBD_DATA_REG) -#define kbd_write_command(val) outb(val, KBD_CNTL_REG) - -/* Some stoneage hardware needs delays after some operations. */ -#define kbd_pause() do { } while(0) - -/* - * Machine specific bits for the PS/2 driver - */ - -#define AUX_IRQ 12 - -#define aux_request_irq(hand, dev_id) \ - request_irq(AUX_IRQ, hand, IRQF_SHARED, "PS2 Mouse", dev_id) - -#define aux_free_irq(dev_id) free_irq(AUX_IRQ, dev_id) - -#endif /* __KERNEL__ */ diff --git a/include/asm-sh/mpc1211/m1543c.h b/include/asm-sh/mpc1211/m1543c.h deleted file mode 100644 index c95d13236c3be6833dccfea13a9d6788d56d79aa..0000000000000000000000000000000000000000 --- a/include/asm-sh/mpc1211/m1543c.h +++ /dev/null @@ -1,200 +0,0 @@ -#ifndef __ASM_SH_M1543C_H -#define __ASM_SH_M1543C_H - -/* - * linux/include/asm-sh/m1543c.h - * Copyright (C) 2001 Nobuhiro Sakawa - * M1543C:PCI-ISA Bus Bridge with Super IO Chip support - * - * from - * - * linux/include/asm-sh/smc37c93x.h - * - * Copyright (C) 2000 Kazumoto Kojima - * - * SMSC 37C93x Super IO Chip support - */ - -/* Default base I/O address */ -#define FDC_PRIMARY_BASE 0x3f0 -#define IDE1_PRIMARY_BASE 0x1f0 -#define IDE1_SECONDARY_BASE 0x170 -#define PARPORT_PRIMARY_BASE 0x378 -#define COM1_PRIMARY_BASE 0x2f8 -#define COM2_PRIMARY_BASE 0x3f8 -#define COM3_PRIMARY_BASE 0x3e8 -#define RTC_PRIMARY_BASE 0x070 -#define KBC_PRIMARY_BASE 0x060 -#define AUXIO_PRIMARY_BASE 0x000 /* XXX */ -#define I8259_M_CR 0x20 -#define I8259_M_MR 0x21 -#define I8259_S_CR 0xa0 -#define I8259_S_MR 0xa1 - -/* Logical device number */ -#define LDN_FDC 0 -#define LDN_IDE1 1 -#define LDN_IDE2 2 -#define LDN_PARPORT 3 -#define LDN_COM1 4 -#define LDN_COM2 5 -#define LDN_COM3 11 -#define LDN_RTC 6 -#define LDN_KBC 7 - -/* Configuration port and key */ -#define CONFIG_PORT 0x3f0 -#define INDEX_PORT CONFIG_PORT -#define DATA_PORT 0x3f1 -#define CONFIG_ENTER1 0x51 -#define CONFIG_ENTER2 0x23 -#define CONFIG_EXIT 0xbb - -/* Configuration index */ -#define CURRENT_LDN_INDEX 0x07 -#define POWER_CONTROL_INDEX 0x22 -#define ACTIVATE_INDEX 0x30 -#define IO_BASE_HI_INDEX 0x60 -#define IO_BASE_LO_INDEX 0x61 -#define IRQ_SELECT_INDEX 0x70 -#define PS2_IRQ_INDEX 0x72 -#define DMA_SELECT_INDEX 0x74 - -/* UART stuff. Only for debugging. */ -/* UART Register */ - -#define UART_RBR 0x0 /* Receiver Buffer Register (Read Only) */ -#define UART_THR 0x0 /* Transmitter Holding Register (Write Only) */ -#define UART_IER 0x2 /* Interrupt Enable Register */ -#define UART_IIR 0x4 /* Interrupt Ident Register (Read Only) */ -#define UART_FCR 0x4 /* FIFO Control Register (Write Only) */ -#define UART_LCR 0x6 /* Line Control Register */ -#define UART_MCR 0x8 /* MODEM Control Register */ -#define UART_LSR 0xa /* Line Status Register */ -#define UART_MSR 0xc /* MODEM Status Register */ -#define UART_SCR 0xe /* Scratch Register */ -#define UART_DLL 0x0 /* Divisor Latch (LS) */ -#define UART_DLM 0x2 /* Divisor Latch (MS) */ - -#ifndef __ASSEMBLY__ -typedef struct uart_reg { - volatile __u16 rbr; - volatile __u16 ier; - volatile __u16 iir; - volatile __u16 lcr; - volatile __u16 mcr; - volatile __u16 lsr; - volatile __u16 msr; - volatile __u16 scr; -} uart_reg; -#endif /* ! __ASSEMBLY__ */ - -/* Alias for Write Only Register */ - -#define thr rbr -#define tcr iir - -/* Alias for Divisor Latch Register */ - -#define dll rbr -#define dlm ier -#define fcr iir - -/* Interrupt Enable Register */ - -#define IER_ERDAI 0x0100 /* Enable Received Data Available Interrupt */ -#define IER_ETHREI 0x0200 /* Enable Transmitter Holding Register Empty Interrupt */ -#define IER_ELSI 0x0400 /* Enable Receiver Line Status Interrupt */ -#define IER_EMSI 0x0800 /* Enable MODEM Status Interrupt */ - -/* Interrupt Ident Register */ - -#define IIR_IP 0x0100 /* "0" if Interrupt Pending */ -#define IIR_IIB0 0x0200 /* Interrupt ID Bit 0 */ -#define IIR_IIB1 0x0400 /* Interrupt ID Bit 1 */ -#define IIR_IIB2 0x0800 /* Interrupt ID Bit 2 */ -#define IIR_FIFO 0xc000 /* FIFOs enabled */ - -/* FIFO Control Register */ - -#define FCR_FEN 0x0100 /* FIFO enable */ -#define FCR_RFRES 0x0200 /* Receiver FIFO reset */ -#define FCR_TFRES 0x0400 /* Transmitter FIFO reset */ -#define FCR_DMA 0x0800 /* DMA mode select */ -#define FCR_RTL 0x4000 /* Receiver triger (LSB) */ -#define FCR_RTM 0x8000 /* Receiver triger (MSB) */ - -/* Line Control Register */ - -#define LCR_WLS0 0x0100 /* Word Length Select Bit 0 */ -#define LCR_WLS1 0x0200 /* Word Length Select Bit 1 */ -#define LCR_STB 0x0400 /* Number of Stop Bits */ -#define LCR_PEN 0x0800 /* Parity Enable */ -#define LCR_EPS 0x1000 /* Even Parity Select */ -#define LCR_SP 0x2000 /* Stick Parity */ -#define LCR_SB 0x4000 /* Set Break */ -#define LCR_DLAB 0x8000 /* Divisor Latch Access Bit */ - -/* MODEM Control Register */ - -#define MCR_DTR 0x0100 /* Data Terminal Ready */ -#define MCR_RTS 0x0200 /* Request to Send */ -#define MCR_OUT1 0x0400 /* Out 1 */ -#define MCR_IRQEN 0x0800 /* IRQ Enable */ -#define MCR_LOOP 0x1000 /* Loop */ - -/* Line Status Register */ - -#define LSR_DR 0x0100 /* Data Ready */ -#define LSR_OE 0x0200 /* Overrun Error */ -#define LSR_PE 0x0400 /* Parity Error */ -#define LSR_FE 0x0800 /* Framing Error */ -#define LSR_BI 0x1000 /* Break Interrupt */ -#define LSR_THRE 0x2000 /* Transmitter Holding Register Empty */ -#define LSR_TEMT 0x4000 /* Transmitter Empty */ -#define LSR_FIFOE 0x8000 /* Receiver FIFO error */ - -/* MODEM Status Register */ - -#define MSR_DCTS 0x0100 /* Delta Clear to Send */ -#define MSR_DDSR 0x0200 /* Delta Data Set Ready */ -#define MSR_TERI 0x0400 /* Trailing Edge Ring Indicator */ -#define MSR_DDCD 0x0800 /* Delta Data Carrier Detect */ -#define MSR_CTS 0x1000 /* Clear to Send */ -#define MSR_DSR 0x2000 /* Data Set Ready */ -#define MSR_RI 0x4000 /* Ring Indicator */ -#define MSR_DCD 0x8000 /* Data Carrier Detect */ - -/* Baud Rate Divisor */ - -#define UART_CLK (1843200) /* 1.8432 MHz */ -#define UART_BAUD(x) (UART_CLK / (16 * (x))) - -/* RTC register definition */ -#define RTC_SECONDS 0 -#define RTC_SECONDS_ALARM 1 -#define RTC_MINUTES 2 -#define RTC_MINUTES_ALARM 3 -#define RTC_HOURS 4 -#define RTC_HOURS_ALARM 5 -#define RTC_DAY_OF_WEEK 6 -#define RTC_DAY_OF_MONTH 7 -#define RTC_MONTH 8 -#define RTC_YEAR 9 -#define RTC_FREQ_SELECT 10 -# define RTC_UIP 0x80 -# define RTC_DIV_CTL 0x70 -/* This RTC can work under 32.768KHz clock only. */ -# define RTC_OSC_ENABLE 0x20 -# define RTC_OSC_DISABLE 0x00 -#define RTC_CONTROL 11 -# define RTC_SET 0x80 -# define RTC_PIE 0x40 -# define RTC_AIE 0x20 -# define RTC_UIE 0x10 -# define RTC_SQWE 0x08 -# define RTC_DM_BINARY 0x04 -# define RTC_24H 0x02 -# define RTC_DST_EN 0x01 - -#endif /* __ASM_SH_M1543C_H */ diff --git a/include/asm-sh/mpc1211/mc146818rtc.h b/include/asm-sh/mpc1211/mc146818rtc.h deleted file mode 100644 index e245f2a3cd78ed86c51f9061aa9c881da6049182..0000000000000000000000000000000000000000 --- a/include/asm-sh/mpc1211/mc146818rtc.h +++ /dev/null @@ -1,6 +0,0 @@ -/* - * MPC1211 uses PC/AT style RTC definitions. - */ -#include - - diff --git a/include/asm-sh/mpc1211/mpc1211.h b/include/asm-sh/mpc1211/mpc1211.h deleted file mode 100644 index fa456c3e4e01baae4f97ea35068dc4889b5e65ce..0000000000000000000000000000000000000000 --- a/include/asm-sh/mpc1211/mpc1211.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef __ASM_SH_MPC1211_H -#define __ASM_SH_MPC1211_H - -/* - * linux/include/asm-sh/mpc1211.h - * - * Copyright (C) 2001 Saito.K & Jeanne - * - * Interface MPC-1211 support - */ - -#define PA_PCI_IO (0xa4000000) /* PCI I/O space */ -#define PA_PCI_MEM (0xb0000000) /* PCI MEM space */ - -#define PCIPAR (0xa4000cf8) /* PCI Config address */ -#define PCIPDR (0xa4000cfc) /* PCI Config data */ - -#endif /* __ASM_SH_MPC1211_H */ diff --git a/include/asm-sh/mpc1211/pci.h b/include/asm-sh/mpc1211/pci.h deleted file mode 100644 index d9162c5ed76a417c6158bf3807490c0f2195737a..0000000000000000000000000000000000000000 --- a/include/asm-sh/mpc1211/pci.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Low-Level PCI Support for MPC-1211 - * - * (c) 2002 Saito.K & Jeanne - * - */ - -#ifndef _PCI_MPC1211_H_ -#define _PCI_MPC1211_H_ - -#include - -/* set debug level 4=verbose...1=terse */ -//#define DEBUG_PCI 3 -#undef DEBUG_PCI - -#ifdef DEBUG_PCI -#define PCIDBG(n, x...) { if(DEBUG_PCI>=n) printk(x); } -#else -#define PCIDBG(n, x...) -#endif - -/* startup values */ -#define PCI_PROBE_BIOS 1 -#define PCI_PROBE_CONF1 2 -#define PCI_PROBE_CONF2 4 -#define PCI_NO_CHECKS 0x400 -#define PCI_ASSIGN_ROMS 0x1000 -#define PCI_BIOS_IRQ_SCAN 0x2000 - -/* MPC-1211 Specific Values */ -#define PCIPAR (0xa4000cf8) /* PCI Config address */ -#define PCIPDR (0xa4000cfc) /* PCI Config data */ - -#define PA_PCI_IO (0xa4000000) /* PCI I/O space */ -#define PA_PCI_MEM (0xb0000000) /* PCI MEM space */ - -#endif /* _PCI_MPC1211_H_ */ diff --git a/include/asm-sh/r7780rp.h b/include/asm-sh/r7780rp.h index a33838f23a6d879b1b443554f66c36b1d6e685a8..306f7359f7d4c345a9cb8b19b7556d79720a3969 100644 --- a/include/asm-sh/r7780rp.h +++ b/include/asm-sh/r7780rp.h @@ -193,8 +193,6 @@ #define IRQ_SCIF0 (HL_FPGA_IRQ_BASE + 15) #define IRQ_SCIF1 (HL_FPGA_IRQ_BASE + 16) -unsigned char *highlander_init_irq_r7780mp(void); -unsigned char *highlander_init_irq_r7780rp(void); -unsigned char *highlander_init_irq_r7785rp(void); +unsigned char *highlander_plat_irq_setup(void); #endif /* __ASM_SH_RENESAS_R7780RP */ diff --git a/include/asm-sh/tlb_64.h b/include/asm-sh/tlb_64.h index 0308e05fc57be27a1fd48f3bfeaccee9a7b0a305..0a96f3af69e3122ff6ea8b8646349ed12d4f000d 100644 --- a/include/asm-sh/tlb_64.h +++ b/include/asm-sh/tlb_64.h @@ -56,6 +56,7 @@ static inline void __flush_tlb_slot(unsigned long long slot) __asm__ __volatile__ ("putcfg %0, 0, r63\n" : : "r" (slot)); } +#ifdef CONFIG_MMU /* arch/sh64/mm/tlb.c */ int sh64_tlb_init(void); unsigned long long sh64_next_free_dtlb_entry(void); @@ -64,6 +65,13 @@ int sh64_put_wired_dtlb_entry(unsigned long long entry); void sh64_setup_tlb_slot(unsigned long long config_addr, unsigned long eaddr, unsigned long asid, unsigned long paddr); void sh64_teardown_tlb_slot(unsigned long long config_addr); - +#else +#define sh64_tlb_init() do { } while (0) +#define sh64_next_free_dtlb_entry() (0) +#define sh64_get_wired_dtlb_entry() (0) +#define sh64_put_wired_dtlb_entry(entry) do { } while (0) +#define sh64_setup_tlb_slot(conf, virt, asid, phys) do { } while (0) +#define sh64_teardown_tlb_slot(addr) do { } while (0) +#endif /* CONFIG_MMU */ #endif /* __ASSEMBLY__ */ #endif /* __ASM_SH_TLB_64_H */ diff --git a/include/asm-sh/topology.h b/include/asm-sh/topology.h index 34cdb28e8f4429c2deb7ed7e96ec9e07c50bbd98..95f0085e098a6859d746581b3b4b616439062854 100644 --- a/include/asm-sh/topology.h +++ b/include/asm-sh/topology.h @@ -29,6 +29,17 @@ .nr_balance_failed = 0, \ } +#define cpu_to_node(cpu) ((void)(cpu),0) +#define parent_node(node) ((void)(node),0) + +#define node_to_cpumask(node) ((void)node, cpu_online_map) +#define node_to_first_cpu(node) ((void)(node),0) + +#define pcibus_to_node(bus) ((void)(bus), -1) +#define pcibus_to_cpumask(bus) (pcibus_to_node(bus) == -1 ? \ + CPU_MASK_ALL : \ + node_to_cpumask(pcibus_to_node(bus)) \ + ) #endif #include diff --git a/include/asm-sh/uaccess_64.h b/include/asm-sh/uaccess_64.h index f956b7b316c7a102cd25005fd1f60ebfeabd5fb5..a9b68d094844eb7a93556edf8e7c0016d380f46c 100644 --- a/include/asm-sh/uaccess_64.h +++ b/include/asm-sh/uaccess_64.h @@ -274,7 +274,9 @@ struct exception_table_entry unsigned long insn, fixup; }; +#ifdef CONFIG_MMU #define ARCH_HAS_SEARCH_EXTABLE +#endif /* Returns 0 if exception not found and fixup.unit otherwise. */ extern unsigned long search_exception_table(unsigned long addr); diff --git a/include/asm-sparc/mman.h b/include/asm-sparc/mman.h index e18be984c01d695e06de0db3ed24c088769c5771..3d16b40bb8effebf23c6cc74bd8a8140c2063daa 100644 --- a/include/asm-sparc/mman.h +++ b/include/asm-sparc/mman.h @@ -24,9 +24,8 @@ #ifdef __KERNEL__ #ifndef __ASSEMBLY__ -#define arch_mmap_check sparc_mmap_check -int sparc_mmap_check(unsigned long addr, unsigned long len, - unsigned long flags); +#define arch_mmap_check(addr,len,flags) sparc_mmap_check(addr,len) +int sparc_mmap_check(unsigned long addr, unsigned long len); #endif #endif diff --git a/include/asm-sparc/psr.h b/include/asm-sparc/psr.h index 19c9780511180f2b24378bf26dfdeff9ecb535c8..213970477a2499a25723eaf8513b610db2d453d1 100644 --- a/include/asm-sparc/psr.h +++ b/include/asm-sparc/psr.h @@ -25,6 +25,7 @@ #define PSR_PIL 0x00000f00 /* processor interrupt level */ #define PSR_EF 0x00001000 /* enable floating point */ #define PSR_EC 0x00002000 /* enable co-processor */ +#define PSR_SYSCALL 0x00004000 /* inside of a syscall */ #define PSR_LE 0x00008000 /* SuperSparcII little-endian */ #define PSR_ICC 0x00f00000 /* integer condition codes */ #define PSR_C 0x00100000 /* carry bit */ diff --git a/include/asm-sparc/ptrace.h b/include/asm-sparc/ptrace.h index 8201a7b29d49bdc7052793b4ccac9b75fb5b8b73..0afb867d6c1b242b36a1f446b71553773b0f5289 100644 --- a/include/asm-sparc/ptrace.h +++ b/include/asm-sparc/ptrace.h @@ -10,6 +10,8 @@ #ifndef __ASSEMBLY__ +#include + struct pt_regs { unsigned long psr; unsigned long pc; @@ -39,6 +41,16 @@ struct pt_regs { #define UREG_FP UREG_I6 #define UREG_RETPC UREG_I7 +static inline bool pt_regs_is_syscall(struct pt_regs *regs) +{ + return (regs->psr & PSR_SYSCALL); +} + +static inline bool pt_regs_clear_syscall(struct pt_regs *regs) +{ + return (regs->psr &= ~PSR_SYSCALL); +} + /* A register window */ struct reg_window { unsigned long locals[8]; @@ -149,6 +161,7 @@ extern void show_regs(struct pt_regs *); #define SF_XXARG 0x5c /* Stuff for the ptrace system call */ +#define PTRACE_SPARC_DETACH 11 #define PTRACE_GETREGS 12 #define PTRACE_SETREGS 13 #define PTRACE_GETFPREGS 14 diff --git a/include/asm-sparc/signal.h b/include/asm-sparc/signal.h index d03a21c97abbda83d56ba4264cd9e4921d659158..94071c75701f4b1c8511cdf768c298ce988fa364 100644 --- a/include/asm-sparc/signal.h +++ b/include/asm-sparc/signal.h @@ -199,13 +199,7 @@ typedef struct sigaltstack { size_t ss_size; } stack_t; -struct sparc_deliver_cookie { - int restart_syscall; - unsigned long orig_i0; -}; - -struct pt_regs; -extern void ptrace_signal_deliver(struct pt_regs *regs, void *cookie); +#define ptrace_signal_deliver(regs, cookie) do { } while (0) #endif /* !(__KERNEL__) */ diff --git a/include/asm-sparc64/mman.h b/include/asm-sparc64/mman.h index e584563b56eb26f7bc8187250223e27bc3c421cb..625be4d61baf8d7622e1dd5ce195260fdc6beb1e 100644 --- a/include/asm-sparc64/mman.h +++ b/include/asm-sparc64/mman.h @@ -24,9 +24,8 @@ #ifdef __KERNEL__ #ifndef __ASSEMBLY__ -#define arch_mmap_check sparc64_mmap_check -int sparc64_mmap_check(unsigned long addr, unsigned long len, - unsigned long flags); +#define arch_mmap_check(addr,len,flags) sparc64_mmap_check(addr,len) +int sparc64_mmap_check(unsigned long addr, unsigned long len); #endif #endif diff --git a/include/asm-sparc64/psrcompat.h b/include/asm-sparc64/psrcompat.h index 5590ce6bd0767273e2bc5e296af9fbf1d91e7864..3614ca04753fff3792fbab5e8029296f56aa7840 100644 --- a/include/asm-sparc64/psrcompat.h +++ b/include/asm-sparc64/psrcompat.h @@ -12,6 +12,7 @@ #define PSR_PIL 0x00000f00 /* processor interrupt level */ #define PSR_EF 0x00001000 /* enable floating point */ #define PSR_EC 0x00002000 /* enable co-processor */ +#define PSR_SYSCALL 0x00004000 /* inside of a syscall */ #define PSR_LE 0x00008000 /* SuperSparcII little-endian */ #define PSR_ICC 0x00f00000 /* integer condition codes */ #define PSR_C 0x00100000 /* carry bit */ @@ -30,6 +31,7 @@ static inline unsigned int tstate_to_psr(unsigned long tstate) PSR_S | ((tstate & TSTATE_ICC) >> 12) | ((tstate & TSTATE_XCC) >> 20) | + ((tstate & TSTATE_SYSCALL) ? PSR_SYSCALL : 0) | PSR_V8PLUS); } diff --git a/include/asm-sparc64/pstate.h b/include/asm-sparc64/pstate.h index f3c45484c63635fef86342942d715ce83ea25c16..949aebaf991d601a5d01a6a4f4b4db26f463feb5 100644 --- a/include/asm-sparc64/pstate.h +++ b/include/asm-sparc64/pstate.h @@ -62,6 +62,7 @@ #define TSTATE_PRIV _AC(0x0000000000000400,UL) /* Privilege. */ #define TSTATE_IE _AC(0x0000000000000200,UL) /* Interrupt Enable. */ #define TSTATE_AG _AC(0x0000000000000100,UL) /* Alternate Globals.*/ +#define TSTATE_SYSCALL _AC(0x0000000000000020,UL) /* in syscall trap */ #define TSTATE_CWP _AC(0x000000000000001f,UL) /* Curr Win-Pointer. */ /* Floating-Point Registers State Register. diff --git a/include/asm-sparc64/ptrace.h b/include/asm-sparc64/ptrace.h index 714b81956f32a653a4c9863edbbc2aefb16b89a8..90972a5ada59f8e3b324f430587922c7cbb2a562 100644 --- a/include/asm-sparc64/ptrace.h +++ b/include/asm-sparc64/ptrace.h @@ -42,16 +42,14 @@ static inline int pt_regs_trap_type(struct pt_regs *regs) return regs->magic & 0x1ff; } -static inline int pt_regs_clear_trap_type(struct pt_regs *regs) +static inline bool pt_regs_is_syscall(struct pt_regs *regs) { - return regs->magic &= ~0x1ff; + return (regs->tstate & TSTATE_SYSCALL); } -static inline bool pt_regs_is_syscall(struct pt_regs *regs) +static inline bool pt_regs_clear_syscall(struct pt_regs *regs) { - int tt = pt_regs_trap_type(regs); - - return (tt == 0x110 || tt == 0x111 || tt == 0x16d); + return (regs->tstate &= ~TSTATE_SYSCALL); } struct pt_regs32 { @@ -298,6 +296,7 @@ extern void __show_regs(struct pt_regs *); #define SF_XXARG 0x5c /* Stuff for the ptrace system call */ +#define PTRACE_SPARC_DETACH 11 #define PTRACE_GETREGS 12 #define PTRACE_SETREGS 13 #define PTRACE_GETFPREGS 14 diff --git a/include/asm-sparc64/signal.h b/include/asm-sparc64/signal.h index fa6f467389db2735daf794361b481a08b40ec942..c49f32d387071594d67eef8a3284e80fcb3b9251 100644 --- a/include/asm-sparc64/signal.h +++ b/include/asm-sparc64/signal.h @@ -186,13 +186,7 @@ struct k_sigaction { void __user *ka_restorer; }; -struct signal_deliver_cookie { - int restart_syscall; - unsigned long orig_i0; -}; - -struct pt_regs; -extern void ptrace_signal_deliver(struct pt_regs *regs, void *cookie); +#define ptrace_signal_deliver(regs, cookie) do { } while (0) #endif /* !(__KERNEL__) */ diff --git a/include/asm-sparc64/thread_info.h b/include/asm-sparc64/thread_info.h index 71e42d1a80d9914c2fb0aaca67ca3fa0265b7533..e5873e3853063c836b01e6e715198f1396bd33f0 100644 --- a/include/asm-sparc64/thread_info.h +++ b/include/asm-sparc64/thread_info.h @@ -38,7 +38,7 @@ struct thread_info { struct task_struct *task; unsigned long flags; __u8 fpsaved[7]; - __u8 pad; + __u8 status; unsigned long ksp; /* D$ line 2 */ @@ -217,7 +217,7 @@ register struct thread_info *current_thread_info_reg asm("g6"); * nop */ #define TIF_SYSCALL_TRACE 0 /* syscall trace active */ -#define TIF_RESTORE_SIGMASK 1 /* restore signal mask in do_signal() */ +/* flags bit 1 is available */ #define TIF_SIGPENDING 2 /* signal pending */ #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ #define TIF_PERFCTR 4 /* performance counters active */ @@ -244,14 +244,34 @@ register struct thread_info *current_thread_info_reg asm("g6"); #define _TIF_32BIT (1<status |= TS_RESTORE_SIGMASK; + set_bit(TIF_SIGPENDING, &ti->flags); +} +#endif /* !__ASSEMBLY__ */ + #endif /* __KERNEL__ */ #endif /* _ASM_THREAD_INFO_H */ diff --git a/include/asm-sparc64/ttable.h b/include/asm-sparc64/ttable.h index 1b55538b944fa82ce802dbdd358dde60818f7ae8..52d67d394107f5fe57d3a29f14aada25008aec27 100644 --- a/include/asm-sparc64/ttable.h +++ b/include/asm-sparc64/ttable.h @@ -91,13 +91,14 @@ nop; #define SYSCALL_TRAP(routine, systbl) \ + rdpr %pil, %g2; \ + mov TSTATE_SYSCALL, %g3; \ sethi %hi(109f), %g7; \ - ba,pt %xcc, etrap; \ + ba,pt %xcc, etrap_syscall; \ 109: or %g7, %lo(109b), %g7; \ sethi %hi(systbl), %l7; \ ba,pt %xcc, routine; \ - or %l7, %lo(systbl), %l7; \ - nop; nop; + or %l7, %lo(systbl), %l7; #define TRAP_UTRAP(handler,lvl) \ mov handler, %g3; \ diff --git a/include/asm-um/irq.h b/include/asm-um/irq.h index de389a477cdd648ad8493164228737c03ef1303f..4a2037f8204baff05ed0b86e097fcc07e465f456 100644 --- a/include/asm-um/irq.h +++ b/include/asm-um/irq.h @@ -15,8 +15,9 @@ #define SIGIO_WRITE_IRQ 11 #define TELNETD_IRQ 12 #define XTERM_IRQ 13 +#define RANDOM_IRQ 14 -#define LAST_IRQ XTERM_IRQ +#define LAST_IRQ RANDOM_IRQ #define NR_IRQS (LAST_IRQ + 1) #endif diff --git a/include/asm-um/keyboard.h b/include/asm-um/keyboard.h deleted file mode 100644 index ee2e2303d0e4ae197b8493bcaa7c50343f60f3bd..0000000000000000000000000000000000000000 --- a/include/asm-um/keyboard.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __UM_KEYBOARD_H -#define __UM_KEYBOARD_H - -#include "asm/arch/keyboard.h" - -#endif diff --git a/include/asm-um/page.h b/include/asm-um/page.h index 381f96b1c8259153fca3433c9eca220031fa1e63..916e1a61999f4b414b94e31db9b928c09ef69aff 100644 --- a/include/asm-um/page.h +++ b/include/asm-um/page.h @@ -7,16 +7,20 @@ #ifndef __UM_PAGE_H #define __UM_PAGE_H -struct page; - -#include -#include +#include /* PAGE_SHIFT determines the page size */ #define PAGE_SHIFT 12 -#define PAGE_SIZE (1UL << PAGE_SHIFT) +#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) #define PAGE_MASK (~(PAGE_SIZE-1)) +#ifndef __ASSEMBLY__ + +struct page; + +#include +#include + /* * These are used to make use of C type-checking.. */ @@ -120,4 +124,5 @@ extern struct page *arch_validate(struct page *page, gfp_t mask, int order); #include #include -#endif +#endif /* __ASSEMBLY__ */ +#endif /* __UM_PAGE_H */ diff --git a/include/asm-um/param.h b/include/asm-um/param.h index 4cd4a226f8c125d07668b15fbf239370baa58ebe..e44f4e60d16d387a9c7fb6ac72a1e5231e1205da 100644 --- a/include/asm-um/param.h +++ b/include/asm-um/param.h @@ -13,6 +13,8 @@ #define HZ CONFIG_HZ #define USER_HZ 100 /* .. some user interfaces are in "ticks" */ #define CLOCKS_PER_SEC (USER_HZ) /* frequency at which times() counts */ +#else +#define HZ 100 #endif #endif diff --git a/include/asm-v850/param.h b/include/asm-v850/param.h index 281832690290536007c861a8362634cb673b7f43..4391f5fe0204129be5aa0b96f28514e799e336ca 100644 --- a/include/asm-v850/param.h +++ b/include/asm-v850/param.h @@ -26,6 +26,8 @@ # define HZ CONFIG_HZ # define USER_HZ 100 # define CLOCKS_PER_SEC USER_HZ +#else +# define HZ 100 #endif #endif /* __V850_PARAM_H__ */ diff --git a/include/asm-x86/bitops.h b/include/asm-x86/bitops.h index b81a4d4d333787e4c9e8b69cb74fd190f09c4e69..ee4b3ead6a438d8d68c626803031072f60a19060 100644 --- a/include/asm-x86/bitops.h +++ b/include/asm-x86/bitops.h @@ -23,13 +23,10 @@ #if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 1) /* Technically wrong, but this avoids compilation errors on some gcc versions. */ -#define ADDR "=m" (*(volatile long *)addr) -#define BIT_ADDR "=m" (((volatile int *)addr)[nr >> 5]) +#define ADDR "=m" (*(volatile long *) addr) #else #define ADDR "+m" (*(volatile long *) addr) -#define BIT_ADDR "+m" (((volatile int *)addr)[nr >> 5]) #endif -#define BASE_ADDR "m" (*(volatile int *)addr) /** * set_bit - Atomically set a bit in memory @@ -77,7 +74,7 @@ static inline void __set_bit(int nr, volatile void *addr) */ static inline void clear_bit(int nr, volatile void *addr) { - asm volatile(LOCK_PREFIX "btr %1,%2" : BIT_ADDR : "Ir" (nr), BASE_ADDR); + asm volatile(LOCK_PREFIX "btr %1,%0" : ADDR : "Ir" (nr)); } /* @@ -96,7 +93,7 @@ static inline void clear_bit_unlock(unsigned nr, volatile void *addr) static inline void __clear_bit(int nr, volatile void *addr) { - asm volatile("btr %1,%2" : BIT_ADDR : "Ir" (nr), BASE_ADDR); + asm volatile("btr %1,%0" : ADDR : "Ir" (nr)); } /* @@ -131,7 +128,7 @@ static inline void __clear_bit_unlock(unsigned nr, volatile void *addr) */ static inline void __change_bit(int nr, volatile void *addr) { - asm volatile("btc %1,%2" : BIT_ADDR : "Ir" (nr), BASE_ADDR); + asm volatile("btc %1,%0" : ADDR : "Ir" (nr)); } /** @@ -145,7 +142,7 @@ static inline void __change_bit(int nr, volatile void *addr) */ static inline void change_bit(int nr, volatile void *addr) { - asm volatile(LOCK_PREFIX "btc %1,%2" : BIT_ADDR : "Ir" (nr), BASE_ADDR); + asm volatile(LOCK_PREFIX "btc %1,%0" : ADDR : "Ir" (nr)); } /** @@ -191,9 +188,10 @@ static inline int __test_and_set_bit(int nr, volatile void *addr) { int oldbit; - asm volatile("bts %2,%3\n\t" - "sbb %0,%0" - : "=r" (oldbit), BIT_ADDR : "Ir" (nr), BASE_ADDR); + asm("bts %2,%1\n\t" + "sbb %0,%0" + : "=r" (oldbit), ADDR + : "Ir" (nr)); return oldbit; } @@ -229,9 +227,10 @@ static inline int __test_and_clear_bit(int nr, volatile void *addr) { int oldbit; - asm volatile("btr %2,%3\n\t" + asm volatile("btr %2,%1\n\t" "sbb %0,%0" - : "=r" (oldbit), BIT_ADDR : "Ir" (nr), BASE_ADDR); + : "=r" (oldbit), ADDR + : "Ir" (nr)); return oldbit; } @@ -240,9 +239,10 @@ static inline int __test_and_change_bit(int nr, volatile void *addr) { int oldbit; - asm volatile("btc %2,%3\n\t" + asm volatile("btc %2,%1\n\t" "sbb %0,%0" - : "=r" (oldbit), BIT_ADDR : "Ir" (nr), BASE_ADDR); + : "=r" (oldbit), ADDR + : "Ir" (nr) : "memory"); return oldbit; } @@ -276,11 +276,10 @@ static inline int variable_test_bit(int nr, volatile const void *addr) { int oldbit; - asm volatile("bt %2,%3\n\t" + asm volatile("bt %2,%1\n\t" "sbb %0,%0" : "=r" (oldbit) - : "m" (((volatile const int *)addr)[nr >> 5]), - "Ir" (nr), BASE_ADDR); + : "m" (*(unsigned long *)addr), "Ir" (nr)); return oldbit; } @@ -397,8 +396,6 @@ static inline int fls(int x) } #endif /* __KERNEL__ */ -#undef BASE_ADDR -#undef BIT_ADDR #undef ADDR static inline void set_bit_string(unsigned long *bitmap, diff --git a/include/asm-x86/geode.h b/include/asm-x86/geode.h index 7154dc4de9511692c5417973ac866f4883d2d7c3..6e6458853a36322bc2830628270f8a6656d6c9f3 100644 --- a/include/asm-x86/geode.h +++ b/include/asm-x86/geode.h @@ -185,16 +185,14 @@ static inline int is_geode(void) return (is_geode_gx() || is_geode_lx()); } -/* - * The VSA has virtual registers that we can query for a signature. - */ +#ifdef CONFIG_MGEODE_LX +extern int geode_has_vsa2(void); +#else static inline int geode_has_vsa2(void) { - outw(VSA_VR_UNLOCK, VSA_VRC_INDEX); - outw(VSA_VR_SIGNATURE, VSA_VRC_INDEX); - - return (inw(VSA_VRC_DATA) == VSA_SIG); + return 0; } +#endif /* MFGPTs */ diff --git a/include/asm-x86/i387.h b/include/asm-x86/i387.h index da2adb45f6e3949476ac0a4d2c1aa1cbb2024986..6b722d315936705605850bdd43141064bae9f71f 100644 --- a/include/asm-x86/i387.h +++ b/include/asm-x86/i387.h @@ -175,7 +175,15 @@ static inline int save_i387(struct _fpstate __user *buf) */ static inline int restore_i387(struct _fpstate __user *buf) { - set_used_math(); + struct task_struct *tsk = current; + int err; + + if (!used_math()) { + err = init_fpu(tsk); + if (err) + return err; + } + if (!(task_thread_info(current)->status & TS_USEDFPU)) { clts(); task_thread_info(current)->status |= TS_USEDFPU; diff --git a/include/asm-x86/kvm_x86_emulate.h b/include/asm-x86/kvm_x86_emulate.h index d6337f941c9838c9267cde6b3b842c3b34a4556a..b877bbd2d3a7064aa80fc27dbcfe2a45fc5e5246 100644 --- a/include/asm-x86/kvm_x86_emulate.h +++ b/include/asm-x86/kvm_x86_emulate.h @@ -135,6 +135,7 @@ struct decode_cache { u8 modrm_rm; u8 use_modrm_ea; unsigned long modrm_ea; + void *modrm_ptr; unsigned long modrm_val; struct fetch_cache fetch; }; diff --git a/include/asm-x86/pat.h b/include/asm-x86/pat.h index 8b822b5a17861215eacfa2d7253ea99c84f310b7..88f60cc6a22737f8e45b20e36a67b27410bb5326 100644 --- a/include/asm-x86/pat.h +++ b/include/asm-x86/pat.h @@ -4,7 +4,13 @@ #include +#ifdef CONFIG_X86_PAT extern int pat_wc_enabled; +extern void validate_pat_support(struct cpuinfo_x86 *c); +#else +static const int pat_wc_enabled = 0; +static inline void validate_pat_support(struct cpuinfo_x86 *c) { } +#endif extern void pat_init(void); @@ -12,5 +18,7 @@ extern int reserve_memtype(u64 start, u64 end, unsigned long req_type, unsigned long *ret_type); extern int free_memtype(u64 start, u64 end); +extern void pat_disable(char *reason); + #endif diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h index 801b31f714524052a2e44652bcf8db0746a45a57..55c3a0e3a8ce34e2aed22986dcf780697d6a1168 100644 --- a/include/asm-x86/pgtable.h +++ b/include/asm-x86/pgtable.h @@ -57,7 +57,8 @@ #define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | \ _PAGE_DIRTY) -#define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY) +#define _PAGE_CHG_MASK (PTE_MASK | _PAGE_PCD | _PAGE_PWT | \ + _PAGE_ACCESSED | _PAGE_DIRTY) #define _PAGE_CACHE_MASK (_PAGE_PCD | _PAGE_PWT) #define _PAGE_CACHE_WB (0) @@ -288,12 +289,21 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) * Chop off the NX bit (if present), and add the NX portion of * the newprot (if present): */ - val &= _PAGE_CHG_MASK & ~_PAGE_NX; - val |= pgprot_val(newprot) & __supported_pte_mask; + val &= _PAGE_CHG_MASK; + val |= pgprot_val(newprot) & (~_PAGE_CHG_MASK) & __supported_pte_mask; return __pte(val); } +/* mprotect needs to preserve PAT bits when updating vm_page_prot */ +#define pgprot_modify pgprot_modify +static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot) +{ + pgprotval_t preservebits = pgprot_val(oldprot) & _PAGE_CHG_MASK; + pgprotval_t addbits = pgprot_val(newprot); + return __pgprot(preservebits | addbits); +} + #define pte_pgprot(x) __pgprot(pte_val(x) & (0xfff | _PAGE_NX)) #define canon_pgprot(p) __pgprot(pgprot_val(p) & __supported_pte_mask) diff --git a/include/asm-x86/pgtable_32.h b/include/asm-x86/pgtable_32.h index 577ab79c4c27b8ebaa84542806dfe4d3f217553f..d7f0403bbecb89a31c9097e79392c4c9b0c7eae5 100644 --- a/include/asm-x86/pgtable_32.h +++ b/include/asm-x86/pgtable_32.h @@ -88,14 +88,7 @@ extern unsigned long pg0[]; /* To avoid harmful races, pmd_none(x) should check only the lower when PAE */ #define pmd_none(x) (!(unsigned long)pmd_val((x))) #define pmd_present(x) (pmd_val((x)) & _PAGE_PRESENT) - -extern int pmd_bad(pmd_t pmd); - -#define pmd_bad_v1(x) \ - (_KERNPG_TABLE != (pmd_val((x)) & ~(PAGE_MASK | _PAGE_USER))) -#define pmd_bad_v2(x) \ - (_KERNPG_TABLE != (pmd_val((x)) & ~(PAGE_MASK | _PAGE_USER | \ - _PAGE_PSE | _PAGE_NX))) +#define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE) #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT)) diff --git a/include/asm-x86/pgtable_64.h b/include/asm-x86/pgtable_64.h index a3bbf8766c1d62790d2f999bba1edac5dab7fa64..efe83dcbd41200fc6822a96ebea1a678fe452ef1 100644 --- a/include/asm-x86/pgtable_64.h +++ b/include/asm-x86/pgtable_64.h @@ -158,14 +158,12 @@ static inline unsigned long pgd_bad(pgd_t pgd) static inline unsigned long pud_bad(pud_t pud) { - return pud_val(pud) & - ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER | _PAGE_PSE | _PAGE_NX); + return pud_val(pud) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER); } static inline unsigned long pmd_bad(pmd_t pmd) { - return pmd_val(pmd) & - ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER | _PAGE_PSE | _PAGE_NX); + return pmd_val(pmd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER); } #define pte_none(x) (!pte_val((x))) diff --git a/include/asm-x86/spinlock.h b/include/asm-x86/spinlock.h index bc6376f1bc5a9d8029c8448b49fcba8685c9b7b8..21e89bf92f1c8cd547b697fcc37021388d8115e2 100644 --- a/include/asm-x86/spinlock.h +++ b/include/asm-x86/spinlock.h @@ -20,18 +20,8 @@ */ #ifdef CONFIG_X86_32 -typedef char _slock_t; -# define LOCK_INS_DEC "decb" -# define LOCK_INS_XCH "xchgb" -# define LOCK_INS_MOV "movb" -# define LOCK_INS_CMP "cmpb" # define LOCK_PTR_REG "a" #else -typedef int _slock_t; -# define LOCK_INS_DEC "decl" -# define LOCK_INS_XCH "xchgl" -# define LOCK_INS_MOV "movl" -# define LOCK_INS_CMP "cmpl" # define LOCK_PTR_REG "D" #endif @@ -66,14 +56,14 @@ typedef int _slock_t; #if (NR_CPUS < 256) static inline int __raw_spin_is_locked(raw_spinlock_t *lock) { - int tmp = *(volatile signed int *)(&(lock)->slock); + int tmp = ACCESS_ONCE(lock->slock); return (((tmp >> 8) & 0xff) != (tmp & 0xff)); } static inline int __raw_spin_is_contended(raw_spinlock_t *lock) { - int tmp = *(volatile signed int *)(&(lock)->slock); + int tmp = ACCESS_ONCE(lock->slock); return (((tmp >> 8) & 0xff) - (tmp & 0xff)) > 1; } @@ -130,14 +120,14 @@ static __always_inline void __raw_spin_unlock(raw_spinlock_t *lock) #else static inline int __raw_spin_is_locked(raw_spinlock_t *lock) { - int tmp = *(volatile signed int *)(&(lock)->slock); + int tmp = ACCESS_ONCE(lock->slock); return (((tmp >> 16) & 0xffff) != (tmp & 0xffff)); } static inline int __raw_spin_is_contended(raw_spinlock_t *lock) { - int tmp = *(volatile signed int *)(&(lock)->slock); + int tmp = ACCESS_ONCE(lock->slock); return (((tmp >> 16) & 0xffff) - (tmp & 0xffff)) > 1; } diff --git a/include/asm-x86/topology.h b/include/asm-x86/topology.h index 4f35a0fb4f22ac5ba6d459a45f4eb8971eb50cac..dcf3f8131d6b4b728643b84cd9d395b0ea4dd963 100644 --- a/include/asm-x86/topology.h +++ b/include/asm-x86/topology.h @@ -25,6 +25,16 @@ #ifndef _ASM_X86_TOPOLOGY_H #define _ASM_X86_TOPOLOGY_H +#ifdef CONFIG_X86_32 +# ifdef CONFIG_X86_HT +# define ENABLE_TOPO_DEFINES +# endif +#else +# ifdef CONFIG_SMP +# define ENABLE_TOPO_DEFINES +# endif +#endif + #ifdef CONFIG_NUMA #include #include @@ -130,10 +140,6 @@ extern unsigned long node_end_pfn[]; extern unsigned long node_remap_size[]; #define node_has_online_mem(nid) (node_start_pfn[nid] != node_end_pfn[nid]) -# ifdef CONFIG_X86_HT -# define ENABLE_TOPO_DEFINES -# endif - # define SD_CACHE_NICE_TRIES 1 # define SD_IDLE_IDX 1 # define SD_NEWIDLE_IDX 2 @@ -141,10 +147,6 @@ extern unsigned long node_remap_size[]; #else -# ifdef CONFIG_SMP -# define ENABLE_TOPO_DEFINES -# endif - # define SD_CACHE_NICE_TRIES 2 # define SD_IDLE_IDX 2 # define SD_NEWIDLE_IDX 2 diff --git a/include/asm-xtensa/param.h b/include/asm-xtensa/param.h index 82ad34d92d359746de497c9a680306a7a661f45f..ba03d5aeab6b085d21bd0b14db47163552f04be7 100644 --- a/include/asm-xtensa/param.h +++ b/include/asm-xtensa/param.h @@ -15,6 +15,8 @@ # define HZ CONFIG_HZ /* internal timer frequency */ # define USER_HZ 100 /* for user interfaces in "ticks" */ # define CLOCKS_PER_SEC (USER_HZ) /* frequnzy at which times() counts */ +#else +# define HZ 100 #endif #define EXEC_PAGESIZE 4096 diff --git a/include/linux/Kbuild b/include/linux/Kbuild index b7d81b2a90411bb16b5b4de8a7766c8547e1d01f..5dfa739045c8106578101d7117ce3754993c9ece 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild @@ -105,7 +105,6 @@ header-y += ixjuser.h header-y += jffs2.h header-y += keyctl.h header-y += limits.h -header-y += dlm_plock.h header-y += magic.h header-y += major.h header-y += matroxfb.h @@ -190,6 +189,7 @@ unifdef-y += cyclades.h unifdef-y += dccp.h unifdef-y += dirent.h unifdef-y += dlm.h +unifdef-y += dlm_plock.h unifdef-y += edd.h unifdef-y += elf.h unifdef-y += elfcore.h diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h index b512e48f6d8e9ccbcc811c364cf73a8f85bdd58f..ee0ed48e834809778a946343d6840e446eb9f2b7 100644 --- a/include/linux/binfmts.h +++ b/include/linux/binfmts.h @@ -99,6 +99,7 @@ extern int copy_strings_kernel(int argc,char ** argv,struct linux_binprm *bprm); extern void compute_creds(struct linux_binprm *binprm); extern int do_coredump(long signr, int exit_code, struct pt_regs * regs); extern int set_binfmt(struct linux_binfmt *new); +extern void free_bprm(struct linux_binprm *); #endif /* __KERNEL__ */ #endif /* _LINUX_BINFMTS_H */ diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h index 43b406def35f6bfadcdbf5b621995e7f920bc851..1abfe664c4446a9a64ea182ce680e6c08d1a3086 100644 --- a/include/linux/bitmap.h +++ b/include/linux/bitmap.h @@ -110,7 +110,6 @@ extern int __bitmap_weight(const unsigned long *bitmap, int bits); extern int bitmap_scnprintf(char *buf, unsigned int len, const unsigned long *src, int nbits); -extern int bitmap_scnprintf_len(unsigned int len); extern int __bitmap_parse(const char *buf, unsigned int buflen, int is_user, unsigned long *dst, int nbits); extern int bitmap_parse_user(const char __user *ubuf, unsigned int ulen, diff --git a/include/linux/compiler.h b/include/linux/compiler.h index dcae0c8d97e6e2d04a8db04494e899eb403e1c18..c8bd2daf95ec51e0f42ad05e6b8c13be1300ce16 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -182,4 +182,16 @@ extern void __chk_io_ptr(const volatile void __iomem *); # define __section(S) __attribute__ ((__section__(#S))) #endif +/* + * Prevent the compiler from merging or refetching accesses. The compiler + * is also forbidden from reordering successive instances of ACCESS_ONCE(), + * but only when the compiler is aware of some particular ordering. One way + * to make the compiler aware of ordering is to put the two invocations of + * ACCESS_ONCE() in different C statements. + * + * This macro does absolutely -nothing- to prevent the CPU from reordering, + * merging, or refetching absolutely anything at any time. + */ +#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x)) + #endif /* __LINUX_COMPILER_H */ diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h index 9650806fe2ea266a6c786ec9a95d96adfe8269d3..5df3db58fcc65620fe5daf05752252c59048a21c 100644 --- a/include/linux/cpumask.h +++ b/include/linux/cpumask.h @@ -289,13 +289,6 @@ static inline int __cpumask_scnprintf(char *buf, int len, return bitmap_scnprintf(buf, len, srcp->bits, nbits); } -#define cpumask_scnprintf_len(len) \ - __cpumask_scnprintf_len((len)) -static inline int __cpumask_scnprintf_len(int len) -{ - return bitmap_scnprintf_len(len); -} - #define cpumask_parse_user(ubuf, ulen, dst) \ __cpumask_parse_user((ubuf), (ulen), &(dst), NR_CPUS) static inline int __cpumask_parse_user(const char __user *buf, int len, diff --git a/include/linux/device.h b/include/linux/device.h index 8c23e3dfe3ac215c721c1e54942f8260b25f3d43..15e9fa3ad3af92b8b692ad801bd3aa89fdb9d1b3 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -183,7 +183,6 @@ struct class { struct module *owner; struct kset subsys; - struct list_head children; struct list_head devices; struct list_head interfaces; struct kset class_dirs; diff --git a/include/linux/exportfs.h b/include/linux/exportfs.h index de8387b7ceb6cd85ab872c3fe5e5f62c366af260..f5abd1306638379ecd609512cc742b8af53169e3 100644 --- a/include/linux/exportfs.h +++ b/include/linux/exportfs.h @@ -33,6 +33,19 @@ enum fid_type { * 32 bit parent directory inode number. */ FILEID_INO32_GEN_PARENT = 2, + + /* + * 32 bit block number, 16 bit partition reference, + * 16 bit unused, 32 bit generation number. + */ + FILEID_UDF_WITHOUT_PARENT = 0x51, + + /* + * 32 bit block number, 16 bit partition reference, + * 16 bit unused, 32 bit generation number, + * 32 bit parent block number, 32 bit parent generation number + */ + FILEID_UDF_WITH_PARENT = 0x52, }; struct fid { @@ -43,6 +56,14 @@ struct fid { u32 parent_ino; u32 parent_gen; } i32; + struct { + u32 block; + u16 partref; + u16 parent_partref; + u32 generation; + u32 parent_block; + u32 parent_generation; + } udf; __u32 raw[0]; }; }; diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h index a118f3c0b240feb6b18c93c6c968557bdab117ae..4aab6f12cfab1cb32a13c220916a9710cb42cb7d 100644 --- a/include/linux/fdtable.h +++ b/include/linux/fdtable.h @@ -93,6 +93,7 @@ struct files_struct *get_files_struct(struct task_struct *); void put_files_struct(struct files_struct *fs); void reset_files_struct(struct files_struct *); int unshare_files(struct files_struct **); +struct files_struct *dup_fd(struct files_struct *, int *); extern struct kmem_cache *files_cachep; diff --git a/include/linux/fs.h b/include/linux/fs.h index a1ba005d08e7ef80f441d00a7f5d934582fe13e6..f413085f748e574140ca4216abbb303209cc7fb0 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1289,17 +1289,12 @@ extern ssize_t vfs_readv(struct file *, const struct iovec __user *, extern ssize_t vfs_writev(struct file *, const struct iovec __user *, unsigned long, loff_t *); -/* - * NOTE: write_inode, delete_inode, clear_inode, put_inode can be called - * without the big kernel lock held in all filesystems. - */ struct super_operations { struct inode *(*alloc_inode)(struct super_block *sb); void (*destroy_inode)(struct inode *); void (*dirty_inode) (struct inode *); int (*write_inode) (struct inode *, int); - void (*put_inode) (struct inode *); void (*drop_inode) (struct inode *); void (*delete_inode) (struct inode *); void (*put_super) (struct super_block *); @@ -1821,7 +1816,6 @@ extern void iget_failed(struct inode *); extern void clear_inode(struct inode *); extern void destroy_inode(struct inode *); extern struct inode *new_inode(struct super_block *); -extern int __remove_suid(struct dentry *, int); extern int should_remove_suid(struct dentry *); extern int remove_suid(struct dentry *); diff --git a/include/linux/fuse.h b/include/linux/fuse.h index 5c86f1196c3ad132ed714d2a07eb2bfed832bc47..d48282197696fdf1644820a121ce75cd5571bd67 100644 --- a/include/linux/fuse.h +++ b/include/linux/fuse.h @@ -109,6 +109,7 @@ struct fuse_file_lock { #define FUSE_POSIX_LOCKS (1 << 1) #define FUSE_FILE_OPS (1 << 2) #define FUSE_ATOMIC_O_TRUNC (1 << 3) +#define FUSE_BIG_WRITES (1 << 5) /** * Release flags diff --git a/include/linux/genhd.h b/include/linux/genhd.h index ecd2bf63fc849e201f4825010293ba20a736d09b..ae7aec3cabee67ef4fb9c6440b8ec14dd76c5207 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -178,17 +178,17 @@ static inline struct hd_struct *get_part(struct gendisk *gendiskp, static inline void disk_stat_set_all(struct gendisk *gendiskp, int value) { int i; + for_each_possible_cpu(i) memset(per_cpu_ptr(gendiskp->dkstats, i), value, - sizeof (struct disk_stats)); + sizeof(struct disk_stats)); } #define __part_stat_add(part, field, addnd) \ (per_cpu_ptr(part->dkstats, smp_processor_id())->field += addnd) -#define __all_stat_add(gendiskp, field, addnd, sector) \ +#define __all_stat_add(gendiskp, part, field, addnd, sector) \ ({ \ - struct hd_struct *part = get_part(gendiskp, sector); \ if (part) \ __part_stat_add(part, field, addnd); \ __disk_stat_add(gendiskp, field, addnd); \ @@ -203,11 +203,13 @@ static inline void disk_stat_set_all(struct gendisk *gendiskp, int value) { res; \ }) -static inline void part_stat_set_all(struct hd_struct *part, int value) { +static inline void part_stat_set_all(struct hd_struct *part, int value) +{ int i; + for_each_possible_cpu(i) memset(per_cpu_ptr(part->dkstats, i), value, - sizeof(struct disk_stats)); + sizeof(struct disk_stats)); } #else /* !CONFIG_SMP */ @@ -223,9 +225,8 @@ static inline void disk_stat_set_all(struct gendisk *gendiskp, int value) #define __part_stat_add(part, field, addnd) \ (part->dkstats.field += addnd) -#define __all_stat_add(gendiskp, field, addnd, sector) \ +#define __all_stat_add(gendiskp, part, field, addnd, sector) \ ({ \ - struct hd_struct *part = get_part(gendiskp, sector); \ if (part) \ part->dkstats.field += addnd; \ __disk_stat_add(gendiskp, field, addnd); \ @@ -276,10 +277,10 @@ static inline void part_stat_set_all(struct hd_struct *part, int value) #define part_stat_sub(gendiskp, field, subnd) \ part_stat_add(gendiskp, field, -subnd) -#define all_stat_add(gendiskp, field, addnd, sector) \ +#define all_stat_add(gendiskp, part, field, addnd, sector) \ do { \ preempt_disable(); \ - __all_stat_add(gendiskp, field, addnd, sector); \ + __all_stat_add(gendiskp, part, field, addnd, sector); \ preempt_enable(); \ } while (0) @@ -288,15 +289,15 @@ static inline void part_stat_set_all(struct hd_struct *part, int value) #define all_stat_dec(gendiskp, field, sector) \ all_stat_add(gendiskp, field, -1, sector) -#define __all_stat_inc(gendiskp, field, sector) \ - __all_stat_add(gendiskp, field, 1, sector) -#define all_stat_inc(gendiskp, field, sector) \ - all_stat_add(gendiskp, field, 1, sector) +#define __all_stat_inc(gendiskp, part, field, sector) \ + __all_stat_add(gendiskp, part, field, 1, sector) +#define all_stat_inc(gendiskp, part, field, sector) \ + all_stat_add(gendiskp, part, field, 1, sector) -#define __all_stat_sub(gendiskp, field, subnd, sector) \ - __all_stat_add(gendiskp, field, -subnd, sector) -#define all_stat_sub(gendiskp, field, subnd, sector) \ - all_stat_add(gendiskp, field, -subnd, sector) +#define __all_stat_sub(gendiskp, part, field, subnd, sector) \ + __all_stat_add(gendiskp, part, field, -subnd, sector) +#define all_stat_sub(gendiskp, part, field, subnd, sector) \ + all_stat_add(gendiskp, part, field, -subnd, sector) /* Inlines to alloc and free disk stats in struct gendisk */ #ifdef CONFIG_SMP @@ -524,7 +525,7 @@ struct unixware_disklabel { #define ADDPART_FLAG_RAID 1 #define ADDPART_FLAG_WHOLEDISK 2 -extern dev_t blk_lookup_devt(const char *name); +extern dev_t blk_lookup_devt(const char *name, int part); extern char *disk_name (struct gendisk *hd, int part, char *buf); extern int rescan_partitions(struct gendisk *disk, struct block_device *bdev); @@ -552,7 +553,7 @@ static inline struct block_device *bdget_disk(struct gendisk *disk, int index) static inline void printk_all_partitions(void) { } -static inline dev_t blk_lookup_devt(const char *name) +static inline dev_t blk_lookup_devt(const char *name, int part) { dev_t devt = MKDEV(0, 0); return devt; diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h index 897f723bd222f73a9c9e72519fe4b8cd14e40f14..181006cc94a03ecd29630d80d91762589fc1c316 100644 --- a/include/linux/hardirq.h +++ b/include/linux/hardirq.h @@ -72,6 +72,14 @@ #define in_softirq() (softirq_count()) #define in_interrupt() (irq_count()) +#if defined(CONFIG_PREEMPT) +# define PREEMPT_INATOMIC_BASE kernel_locked() +# define PREEMPT_CHECK_OFFSET 1 +#else +# define PREEMPT_INATOMIC_BASE 0 +# define PREEMPT_CHECK_OFFSET 0 +#endif + /* * Are we running in atomic context? WARNING: this macro cannot * always detect atomic context; in particular, it cannot know about @@ -79,17 +87,11 @@ * used in the general case to determine whether sleeping is possible. * Do not use in_atomic() in driver code. */ -#define in_atomic() ((preempt_count() & ~PREEMPT_ACTIVE) != 0) - -#ifdef CONFIG_PREEMPT -# define PREEMPT_CHECK_OFFSET 1 -#else -# define PREEMPT_CHECK_OFFSET 0 -#endif +#define in_atomic() ((preempt_count() & ~PREEMPT_ACTIVE) != PREEMPT_INATOMIC_BASE) /* * Check whether we were atomic before we did preempt_disable(): - * (used by the scheduler) + * (used by the scheduler, *after* releasing the kernel lock) */ #define in_atomic_preempt_off() \ ((preempt_count() & ~PREEMPT_ACTIVE) != PREEMPT_CHECK_OFFSET) diff --git a/include/linux/i2c.h b/include/linux/i2c.h index cb63da5c2139f04c331f44da7e681c36ec07ece1..fb9af6a0fe9cb0bf275c706129c4589d4ee8fb30 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -155,8 +155,6 @@ struct i2c_driver { * @driver: device's driver, hence pointer to access routines * @dev: Driver model device node for the slave. * @irq: indicates the IRQ generated by this device (if any) - * @driver_name: Identifies new-style driver used with this device; also - * used as the module name for hotplug/coldplug modprobe support. * @list: list of active/busy clients (DEPRECATED) * @released: used to synchronize client releases & detaches and references * @@ -174,7 +172,6 @@ struct i2c_client { struct i2c_driver *driver; /* and our access routines */ struct device dev; /* the device structure */ int irq; /* irq issued by device (or -1) */ - char driver_name[KOBJ_NAME_LEN]; struct list_head list; /* DEPRECATED */ struct completion released; }; @@ -200,8 +197,7 @@ static inline void i2c_set_clientdata (struct i2c_client *dev, void *data) /** * struct i2c_board_info - template for device creation - * @driver_name: identifies the driver to be bound to the device - * @type: optional chip type information, to initialize i2c_client.name + * @type: chip type, to initialize i2c_client.name * @flags: to initialize i2c_client.flags * @addr: stored in i2c_client.addr * @platform_data: stored in i2c_client.dev.platform_data @@ -220,7 +216,6 @@ static inline void i2c_set_clientdata (struct i2c_client *dev, void *data) * with the adapter already known. */ struct i2c_board_info { - char driver_name[KOBJ_NAME_LEN]; char type[I2C_NAME_SIZE]; unsigned short flags; unsigned short addr; @@ -262,7 +257,7 @@ i2c_new_probed_device(struct i2c_adapter *adap, * client handles for the extra addresses. */ extern struct i2c_client * -i2c_new_dummy(struct i2c_adapter *adap, u16 address, const char *type); +i2c_new_dummy(struct i2c_adapter *adap, u16 address); extern void i2c_unregister_device(struct i2c_client *); diff --git a/include/linux/i2c/pcf857x.h b/include/linux/i2c/pcf857x.h index ba8ea6e16476e48231cbbabc884032d9e9e45d94..0767a2a6b2f1256746220a9f772efaec82f5c9f7 100644 --- a/include/linux/i2c/pcf857x.h +++ b/include/linux/i2c/pcf857x.h @@ -12,8 +12,7 @@ * @context: optional parameter passed to setup() and teardown() * * In addition to the I2C_BOARD_INFO() state appropriate to each chip, - * the i2c_board_info used with the pcf875x driver must provide the - * chip "type" ("pcf8574", "pcf8574a", "pcf8575", "pcf8575c") and its + * the i2c_board_info used with the pcf875x driver must provide its * platform_data (pointer to one of these structures) with at least * the gpio_base value initialized. * diff --git a/include/linux/ide.h b/include/linux/ide.h index b0135b0c3a0435777b379d8f47f817d18c73de67..f8f195c20da265cbe8d804f998a946735d8e7978 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -965,7 +965,6 @@ typedef struct ide_task_s { void ide_tf_dump(const char *, struct ide_taskfile *); extern void SELECT_DRIVE(ide_drive_t *); -extern void SELECT_MASK(ide_drive_t *, int); extern int drive_is_ready(ide_drive_t *); @@ -1058,8 +1057,8 @@ enum { IDE_HFLAG_NO_SET_MODE = (1 << 9), /* trust BIOS for programming chipset/device for DMA */ IDE_HFLAG_TRUST_BIOS_FOR_DMA = (1 << 10), - /* host uses VDMA (tied with IDE_HFLAG_CS5520 for now) */ - IDE_HFLAG_VDMA = (1 << 11), + /* host is CS5510/CS5520 */ + IDE_HFLAG_CS5520 = (1 << 11), /* ATAPI DMA is unsupported */ IDE_HFLAG_NO_ATAPI_DMA = (1 << 12), /* set if host is a "non-bootable" controller */ @@ -1070,8 +1069,6 @@ enum { IDE_HFLAG_NO_AUTODMA = (1 << 15), /* host uses MMIO */ IDE_HFLAG_MMIO = (1 << 16), - /* host is CS5510/CS5520 */ - IDE_HFLAG_CS5520 = IDE_HFLAG_VDMA, /* no LBA48 */ IDE_HFLAG_NO_LBA48 = (1 << 17), /* no LBA48 DMA */ @@ -1101,6 +1098,8 @@ enum { IDE_HFLAG_NO_IO_32BIT = (1 << 30), /* never unmask IRQs */ IDE_HFLAG_NO_UNMASK_IRQS = (1 << 31), + /* host uses VDMA (disabled for now) */ + IDE_HFLAG_VDMA = 0, }; #ifdef CONFIG_BLK_DEV_OFFBOARD diff --git a/include/linux/init_task.h b/include/linux/init_task.h index b24c2875aa0570524502e12c97d8e7c3b0d44fa0..9927a88674a3bd3b5c1a5d4fe346f8a9889f6cc9 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h @@ -1,7 +1,6 @@ #ifndef _LINUX__INIT_TASK_H #define _LINUX__INIT_TASK_H -#include #include #include #include @@ -12,27 +11,7 @@ #include #include -#define INIT_FDTABLE \ -{ \ - .max_fds = NR_OPEN_DEFAULT, \ - .fd = &init_files.fd_array[0], \ - .close_on_exec = (fd_set *)&init_files.close_on_exec_init, \ - .open_fds = (fd_set *)&init_files.open_fds_init, \ - .rcu = RCU_HEAD_INIT, \ - .next = NULL, \ -} - -#define INIT_FILES \ -{ \ - .count = ATOMIC_INIT(1), \ - .fdt = &init_files.fdtab, \ - .fdtab = INIT_FDTABLE, \ - .file_lock = __SPIN_LOCK_UNLOCKED(init_task.file_lock), \ - .next_fd = 0, \ - .close_on_exec_init = { { 0, } }, \ - .open_fds_init = { { 0, } }, \ - .fd_array = { NULL, } \ -} +extern struct files_struct init_files; #define INIT_KIOCTX(name, which_mm) \ { \ diff --git a/include/linux/ioprio.h b/include/linux/ioprio.h index 2a3bb1bb74336f27c27f6627153900d46d6c178a..f98a656b17e5b4b732e57e0e70e4eb5ec53bce84 100644 --- a/include/linux/ioprio.h +++ b/include/linux/ioprio.h @@ -67,6 +67,20 @@ static inline int task_nice_ioprio(struct task_struct *task) return (task_nice(task) + 20) / 5; } +/* + * This is for the case where the task hasn't asked for a specific IO class. + * Check for idle and rt task process, and return appropriate IO class. + */ +static inline int task_nice_ioclass(struct task_struct *task) +{ + if (task->policy == SCHED_IDLE) + return IOPRIO_CLASS_IDLE; + else if (task->policy == SCHED_FIFO || task->policy == SCHED_RR) + return IOPRIO_CLASS_RT; + else + return IOPRIO_CLASS_BE; +} + /* * For inheritance, return the highest of the two given priorities */ diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h index 82de2fb62cb71677cfbd876e34189b2b7b002779..00c1801099fa0de4024690c6c415fe0b58724bc5 100644 --- a/include/linux/kallsyms.h +++ b/include/linux/kallsyms.h @@ -83,16 +83,6 @@ __attribute__((format(printf,1,2))); static inline void __check_printsym_format(const char *fmt, ...) { } -/* ia64 and ppc64 use function descriptors, which contain the real address */ -#if defined(CONFIG_IA64) || defined(CONFIG_PPC64) -#define print_fn_descriptor_symbol(fmt, addr) \ -do { \ - unsigned long *__faddr = (unsigned long*) addr; \ - print_symbol(fmt, __faddr[0]); \ -} while (0) -#else -#define print_fn_descriptor_symbol(fmt, addr) print_symbol(fmt, addr) -#endif static inline void print_symbol(const char *fmt, unsigned long addr) { @@ -101,6 +91,20 @@ static inline void print_symbol(const char *fmt, unsigned long addr) __builtin_extract_return_addr((void *)addr)); } +/* + * Pretty-print a function pointer. + * + * ia64 and ppc64 function pointers are really function descriptors, + * which contain a pointer the real address. + */ +static inline void print_fn_descriptor_symbol(const char *fmt, void *addr) +{ +#if defined(CONFIG_IA64) || defined(CONFIG_PPC64) + addr = *(void **)addr; +#endif + print_symbol(fmt, (unsigned long)addr); +} + #ifndef CONFIG_64BIT #define print_ip_sym(ip) \ do { \ diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 4d46e299afb5cb44003e42d894912d23fbe17a13..792bf0aa779b50d3e6aee9edaff9efe69569848f 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -276,7 +276,17 @@ extern void print_hex_dump(const char *level, const char *prefix_str, const void *buf, size_t len, bool ascii); extern void print_hex_dump_bytes(const char *prefix_str, int prefix_type, const void *buf, size_t len); -#define hex_asc(x) "0123456789abcdef"[x] + +extern const char hex_asc[]; +#define hex_asc_lo(x) hex_asc[((x) & 0x0f)] +#define hex_asc_hi(x) hex_asc[((x) & 0xf0) >> 4] + +static inline char *pack_hex_byte(char *buf, u8 byte) +{ + *buf++ = hex_asc_hi(byte); + *buf++ = hex_asc_lo(byte); + return buf; +} #define pr_emerg(fmt, arg...) \ printk(KERN_EMERG fmt, ##arg) diff --git a/include/linux/libata.h b/include/linux/libata.h index d1dfe872ee308f854a4b7dd2113e124c4813d1ab..4a92fbafce9d40ba1476b559539467ae55931022 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -341,7 +341,7 @@ enum { ATA_EH_PMP_TRIES = 5, ATA_EH_PMP_LINK_TRIES = 3, - SATA_PMP_SCR_TIMEOUT = 250, + SATA_PMP_RW_TIMEOUT = 3000, /* PMP read/write timeout */ /* Horkage types. May be set by libata or controller on drives (some horkage may be drive/controller pair dependant */ @@ -351,7 +351,7 @@ enum { ATA_HORKAGE_NONCQ = (1 << 2), /* Don't use NCQ */ ATA_HORKAGE_MAX_SEC_128 = (1 << 3), /* Limit max sects to 128 */ ATA_HORKAGE_BROKEN_HPA = (1 << 4), /* Broken HPA */ - ATA_HORKAGE_SKIP_PM = (1 << 5), /* Skip PM operations */ + ATA_HORKAGE_DISABLE = (1 << 5), /* Disable it */ ATA_HORKAGE_HPA_SIZE = (1 << 6), /* native size off by one */ ATA_HORKAGE_IPM = (1 << 7), /* Link PM problems */ ATA_HORKAGE_IVB = (1 << 8), /* cbl det validity bit bugs */ @@ -821,8 +821,6 @@ struct ata_timing { unsigned short udma; /* t2CYCTYP/2 */ }; -#define FIT(v, vmin, vmax) max_t(short, min_t(short, v, vmax), vmin) - /* * Core layer - drivers/ata/libata-core.c */ @@ -1039,6 +1037,7 @@ extern void ata_eh_thaw_port(struct ata_port *ap); extern void ata_eh_qc_complete(struct ata_queued_cmd *qc); extern void ata_eh_qc_retry(struct ata_queued_cmd *qc); +extern void ata_eh_analyze_ncq_error(struct ata_link *link); extern void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset, ata_reset_fn_t softreset, ata_reset_fn_t hardreset, @@ -1381,6 +1380,18 @@ static inline struct ata_port *ata_shost_to_port(struct Scsi_Host *host) return *(struct ata_port **)&host->hostdata[0]; } +static inline int ata_check_ready(u8 status) +{ + if (!(status & ATA_BUSY)) + return 1; + + /* 0xff indicates either no device or device not ready */ + if (status == 0xff) + return -ENODEV; + + return 0; +} + /************************************************************************** * PMP - drivers/ata/libata-pmp.c diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index eb7c16cc95596fae106848e0a66b3b04f6f6b68a..02a27ae78539cfe536106f46a8f89b50ea63985e 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -226,8 +226,17 @@ struct mm_struct { rwlock_t ioctx_list_lock; /* aio lock */ struct kioctx *ioctx_list; #ifdef CONFIG_MM_OWNER - struct task_struct *owner; /* The thread group leader that */ - /* owns the mm_struct. */ + /* + * "owner" points to a task that is regarded as the canonical + * user/owner of this mm. All of the following must be true in + * order for it to be changed: + * + * current == mm->owner + * current->mm != mm + * new_owner->mm == mm + * new_owner->alloc_lock is held + */ + struct task_struct *owner; #endif #ifdef CONFIG_PROC_FS diff --git a/include/linux/mv643xx_eth.h b/include/linux/mv643xx_eth.h index 30e11aa3c1c94cb9d2b1419326896b6462edaaea..a15cdd4a8e584ba94c7704cf185a30224d99d4e3 100644 --- a/include/linux/mv643xx_eth.h +++ b/include/linux/mv643xx_eth.h @@ -1,19 +1,31 @@ /* * MV-643XX ethernet platform device data definition file. */ + #ifndef __LINUX_MV643XX_ETH_H #define __LINUX_MV643XX_ETH_H -#define MV643XX_ETH_SHARED_NAME "mv643xx_eth_shared" -#define MV643XX_ETH_NAME "mv643xx_eth" +#include + +#define MV643XX_ETH_SHARED_NAME "mv643xx_eth" +#define MV643XX_ETH_NAME "mv643xx_eth_port" #define MV643XX_ETH_SHARED_REGS 0x2000 #define MV643XX_ETH_SHARED_REGS_SIZE 0x2000 #define MV643XX_ETH_BAR_4 0x2220 #define MV643XX_ETH_SIZE_REG_4 0x2224 #define MV643XX_ETH_BASE_ADDR_ENABLE_REG 0x2290 +struct mv643xx_eth_shared_platform_data { + struct mbus_dram_target_info *dram; + unsigned int t_clk; +}; + struct mv643xx_eth_platform_data { + struct platform_device *shared; int port_number; + + struct platform_device *shared_smi; + u16 force_phy_addr; /* force override if phy_addr == 0 */ u16 phy_addr; diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 7c1d4466583b74e05ea09a16f86ea96a98651e8f..b11e6e19e96c4c0ec628d4bfd430853d0abec424 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -93,14 +93,16 @@ struct wireless_dev; * used. */ -#if !defined(CONFIG_AX25) && !defined(CONFIG_AX25_MODULE) && !defined(CONFIG_TR) -#define LL_MAX_HEADER 32 +#if defined(CONFIG_WLAN_80211) || defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) +# if defined(CONFIG_MAC80211_MESH) +# define LL_MAX_HEADER 128 +# else +# define LL_MAX_HEADER 96 +# endif +#elif defined(CONFIG_TR) +# define LL_MAX_HEADER 48 #else -#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) -#define LL_MAX_HEADER 96 -#else -#define LL_MAX_HEADER 48 -#endif +# define LL_MAX_HEADER 32 #endif #if !defined(CONFIG_NET_IPIP) && !defined(CONFIG_NET_IPIP_MODULE) && \ @@ -244,11 +246,16 @@ struct hh_cache * * We could use other alignment values, but we must maintain the * relationship HH alignment <= LL alignment. + * + * LL_ALLOCATED_SPACE also takes into account the tailroom the device + * may need. */ #define LL_RESERVED_SPACE(dev) \ - (((dev)->hard_header_len&~(HH_DATA_MOD - 1)) + HH_DATA_MOD) + ((((dev)->hard_header_len+(dev)->needed_headroom)&~(HH_DATA_MOD - 1)) + HH_DATA_MOD) #define LL_RESERVED_SPACE_EXTRA(dev,extra) \ - ((((dev)->hard_header_len+extra)&~(HH_DATA_MOD - 1)) + HH_DATA_MOD) + ((((dev)->hard_header_len+(dev)->needed_headroom+(extra))&~(HH_DATA_MOD - 1)) + HH_DATA_MOD) +#define LL_ALLOCATED_SPACE(dev) \ + ((((dev)->hard_header_len+(dev)->needed_headroom+(dev)->needed_tailroom)&~(HH_DATA_MOD - 1)) + HH_DATA_MOD) struct header_ops { int (*create) (struct sk_buff *skb, struct net_device *dev, @@ -567,6 +574,13 @@ struct net_device unsigned short type; /* interface hardware type */ unsigned short hard_header_len; /* hardware hdr length */ + /* extra head- and tailroom the hardware may need, but not in all cases + * can this be guaranteed, especially tailroom. Some cases also use + * LL_MAX_HEADER instead to allocate the skb. + */ + unsigned short needed_headroom; + unsigned short needed_tailroom; + struct net_device *master; /* Pointer to master device of a group, * which this device is member of. */ @@ -715,6 +729,9 @@ struct net_device struct net *nd_net; #endif + /* mid-layer private */ + void *ml_priv; + /* bridge stuff */ struct net_bridge_port *br_port; /* macvlan */ diff --git a/include/linux/netfilter/nf_conntrack_sip.h b/include/linux/netfilter/nf_conntrack_sip.h index 5da04e586a3fb399fcda285cb23f6046bc8e447b..23aa2ec6b7b7e9fc25f58bb6d83d7ed38a88ebf0 100644 --- a/include/linux/netfilter/nf_conntrack_sip.h +++ b/include/linux/netfilter/nf_conntrack_sip.h @@ -7,6 +7,7 @@ struct nf_ct_sip_master { unsigned int register_cseq; + unsigned int invite_cseq; }; enum sip_expectation_classes { diff --git a/include/linux/of_i2c.h b/include/linux/of_i2c.h index 2e5a9673204223451e56362bd0a59fdb4f25473e..bd2a870ec29621f54b4b53aea5dd15f8bb8c346f 100644 --- a/include/linux/of_i2c.h +++ b/include/linux/of_i2c.h @@ -14,11 +14,7 @@ #include -#ifdef CONFIG_OF_I2C - void of_register_i2c_devices(struct i2c_adapter *adap, struct device_node *adap_node); -#endif /* CONFIG_OF_I2C */ - #endif /* __LINUX_OF_I2C_H */ diff --git a/include/linux/parser.h b/include/linux/parser.h index 26b2bdfcaf06023848f68d8b00ed19277b5647da..7dcd050757567eb94265fb12b29d6f79e5cbcb3f 100644 --- a/include/linux/parser.h +++ b/include/linux/parser.h @@ -29,5 +29,5 @@ int match_token(char *, match_table_t table, substring_t args[]); int match_int(substring_t *, int *result); int match_octal(substring_t *, int *result); int match_hex(substring_t *, int *result); -void match_strcpy(char *, const substring_t *); +size_t match_strlcpy(char *, const substring_t *, size_t); char *match_strdup(const substring_t *); diff --git a/include/linux/percpu.h b/include/linux/percpu.h index d746a2abb322590a7e891762638e774ec0efe2b5..4cdd393e71e1bb70ee0286c16f2aeb08d1458d98 100644 --- a/include/linux/percpu.h +++ b/include/linux/percpu.h @@ -13,8 +13,14 @@ __attribute__((__section__(".data.percpu"))) \ PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name +#ifdef MODULE +#define SHARED_ALIGNED_SECTION ".data.percpu" +#else +#define SHARED_ALIGNED_SECTION ".data.percpu.shared_aligned" +#endif + #define DEFINE_PER_CPU_SHARED_ALIGNED(type, name) \ - __attribute__((__section__(".data.percpu.shared_aligned"))) \ + __attribute__((__section__(SHARED_ALIGNED_SECTION))) \ PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name \ ____cacheline_aligned_in_smp #else diff --git a/include/linux/phy.h b/include/linux/phy.h index 02df20f085fe9e89637affb8cb880d2a1f153628..7224c4099a2820cd8e03b5589fa20e1eeb83b0a6 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -412,6 +412,8 @@ int mdiobus_register(struct mii_bus *bus); void mdiobus_unregister(struct mii_bus *bus); void phy_sanitize_settings(struct phy_device *phydev); int phy_stop_interrupts(struct phy_device *phydev); +int phy_enable_interrupts(struct phy_device *phydev); +int phy_disable_interrupts(struct phy_device *phydev); static inline int phy_read_status(struct phy_device *phydev) { return phydev->drv->read_status(phydev); @@ -447,5 +449,8 @@ int phy_register_fixup_for_uid(u32 phy_uid, u32 phy_uid_mask, int (*run)(struct phy_device *)); int phy_scan_fixups(struct phy_device *phydev); +int __init mdio_bus_init(void); +void mdio_bus_exit(void); + extern struct bus_type mdio_bus_type; #endif /* __PHY_H */ diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 8082d6587a0f6544a1ec6c28af922dc01a4b90ea..d42dbec0608343c9471c3fd3a8c8ae734e27e55f 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -131,18 +131,6 @@ struct rcu_head { */ #define rcu_read_unlock_bh() __rcu_read_unlock_bh() -/* - * Prevent the compiler from merging or refetching accesses. The compiler - * is also forbidden from reordering successive instances of ACCESS_ONCE(), - * but only when the compiler is aware of some particular ordering. One way - * to make the compiler aware of ordering is to put the two invocations of - * ACCESS_ONCE() in different C statements. - * - * This macro does absolutely -nothing- to prevent the CPU from reordering, - * merging, or refetching absolutely anything at any time. - */ -#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x)) - /** * rcu_dereference - fetch an RCU-protected pointer in an * RCU read-side critical section. This pointer may later diff --git a/include/linux/sched.h b/include/linux/sched.h index 0c35b0343a76bf20327af6a84b1be976493735e3..5395a6176f4be13911a57d7174de0274947edb94 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -2027,7 +2027,7 @@ static inline int fatal_signal_pending(struct task_struct *p) static inline int need_resched(void) { - return unlikely(test_tsk_need_resched(current)); + return unlikely(test_thread_flag(TIF_NEED_RESCHED)); } /* @@ -2037,13 +2037,13 @@ static inline int need_resched(void) * cond_resched_lock() will drop the spinlock before scheduling, * cond_resched_softirq() will enable bhs before scheduling. */ -#ifdef CONFIG_PREEMPT +extern int _cond_resched(void); +#ifdef CONFIG_PREEMPT_BKL static inline int cond_resched(void) { return 0; } #else -extern int _cond_resched(void); static inline int cond_resched(void) { return _cond_resched(); @@ -2051,6 +2051,10 @@ static inline int cond_resched(void) #endif extern int cond_resched_lock(spinlock_t * lock); extern int cond_resched_softirq(void); +static inline int cond_resched_bkl(void) +{ + return _cond_resched(); +} /* * Does a critical section need to be broken due to another diff --git a/include/linux/usb/association.h b/include/linux/usb/association.h new file mode 100644 index 0000000000000000000000000000000000000000..07c5e3cf5898ad4bfc43605970d18c6b4b219ddd --- /dev/null +++ b/include/linux/usb/association.h @@ -0,0 +1,150 @@ +/* + * Wireless USB - Cable Based Association + * + * Copyright (C) 2006 Intel Corporation + * Inaky Perez-Gonzalez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 as published by the Free Software Foundation. + * + */ +#ifndef __LINUX_USB_ASSOCIATION_H +#define __LINUX_USB_ASSOCIATION_H + + +/* + * Association attributes + * + * Association Models Supplement to WUSB 1.0 T[3-1] + * + * Each field in the structures has it's ID, it's length and then the + * value. This is the actual definition of the field's ID and its + * length. + */ +struct wusb_am_attr { + __u8 id; + __u8 len; +}; + +/* Different fields defined by the spec */ +#define WUSB_AR_AssociationTypeId { .id = 0x0000, .len = 2 } +#define WUSB_AR_AssociationSubTypeId { .id = 0x0001, .len = 2 } +#define WUSB_AR_Length { .id = 0x0002, .len = 4 } +#define WUSB_AR_AssociationStatus { .id = 0x0004, .len = 4 } +#define WUSB_AR_LangID { .id = 0x0008, .len = 2 } +#define WUSB_AR_DeviceFriendlyName { .id = 0x000b, .len = 64 } /* max */ +#define WUSB_AR_HostFriendlyName { .id = 0x000c, .len = 64 } /* max */ +#define WUSB_AR_CHID { .id = 0x1000, .len = 16 } +#define WUSB_AR_CDID { .id = 0x1001, .len = 16 } +#define WUSB_AR_ConnectionContext { .id = 0x1002, .len = 48 } +#define WUSB_AR_BandGroups { .id = 0x1004, .len = 2 } + +/* CBAF Control Requests (AMS1.0[T4-1] */ +enum { + CBAF_REQ_GET_ASSOCIATION_INFORMATION = 0x01, + CBAF_REQ_GET_ASSOCIATION_REQUEST, + CBAF_REQ_SET_ASSOCIATION_RESPONSE +}; + +/* + * CBAF USB-interface defitions + * + * No altsettings, one optional interrupt endpoint. + */ +enum { + CBAF_IFACECLASS = 0xef, + CBAF_IFACESUBCLASS = 0x03, + CBAF_IFACEPROTOCOL = 0x01, +}; + +/* Association Information (AMS1.0[T4-3]) */ +struct wusb_cbaf_assoc_info { + __le16 Length; + __u8 NumAssociationRequests; + __le16 Flags; + __u8 AssociationRequestsArray[]; +} __attribute__((packed)); + +/* Association Request (AMS1.0[T4-4]) */ +struct wusb_cbaf_assoc_request { + __u8 AssociationDataIndex; + __u8 Reserved; + __le16 AssociationTypeId; + __le16 AssociationSubTypeId; + __le32 AssociationTypeInfoSize; +} __attribute__((packed)); + +enum { + AR_TYPE_WUSB = 0x0001, + AR_TYPE_WUSB_RETRIEVE_HOST_INFO = 0x0000, + AR_TYPE_WUSB_ASSOCIATE = 0x0001, +}; + +/* Association Attribute header (AMS1.0[3.8]) */ +struct wusb_cbaf_attr_hdr { + __le16 id; + __le16 len; +} __attribute__((packed)); + +/* Host Info (AMS1.0[T4-7]) (yeah, more headers and fields...) */ +struct wusb_cbaf_host_info { + struct wusb_cbaf_attr_hdr AssociationTypeId_hdr; + __le16 AssociationTypeId; + struct wusb_cbaf_attr_hdr AssociationSubTypeId_hdr; + __le16 AssociationSubTypeId; + struct wusb_cbaf_attr_hdr CHID_hdr; + struct wusb_ckhdid CHID; + struct wusb_cbaf_attr_hdr LangID_hdr; + __le16 LangID; + struct wusb_cbaf_attr_hdr HostFriendlyName_hdr; + __u8 HostFriendlyName[]; +} __attribute__((packed)); + +/* Device Info (AMS1.0[T4-8]) + * + * I still don't get this tag'n'header stuff for each goddamn + * field... + */ +struct wusb_cbaf_device_info { + struct wusb_cbaf_attr_hdr Length_hdr; + __le32 Length; + struct wusb_cbaf_attr_hdr CDID_hdr; + struct wusb_ckhdid CDID; + struct wusb_cbaf_attr_hdr BandGroups_hdr; + __le16 BandGroups; + struct wusb_cbaf_attr_hdr LangID_hdr; + __le16 LangID; + struct wusb_cbaf_attr_hdr DeviceFriendlyName_hdr; + __u8 DeviceFriendlyName[]; +} __attribute__((packed)); + +/* Connection Context; CC_DATA - Success case (AMS1.0[T4-9]) */ +struct wusb_cbaf_cc_data { + struct wusb_cbaf_attr_hdr AssociationTypeId_hdr; + __le16 AssociationTypeId; + struct wusb_cbaf_attr_hdr AssociationSubTypeId_hdr; + __le16 AssociationSubTypeId; + struct wusb_cbaf_attr_hdr Length_hdr; + __le32 Length; + struct wusb_cbaf_attr_hdr ConnectionContext_hdr; + struct wusb_ckhdid CHID; + struct wusb_ckhdid CDID; + struct wusb_ckhdid CK; + struct wusb_cbaf_attr_hdr BandGroups_hdr; + __le16 BandGroups; +} __attribute__((packed)); + +/* CC_DATA - Failure case (AMS1.0[T4-10]) */ +struct wusb_cbaf_cc_data_fail { + struct wusb_cbaf_attr_hdr AssociationTypeId_hdr; + __le16 AssociationTypeId; + struct wusb_cbaf_attr_hdr AssociationSubTypeId_hdr; + __le16 AssociationSubTypeId; + struct wusb_cbaf_attr_hdr Length_hdr; + __le16 Length; + struct wusb_cbaf_attr_hdr AssociationStatus_hdr; + __u32 AssociationStatus; +} __attribute__((packed)); + +#endif /* __LINUX_USB_ASSOCIATION_H */ diff --git a/include/linux/vermagic.h b/include/linux/vermagic.h index 4d0909e53595dcd9423c9e845bd13d0da36bfcaa..79b9837d9ca079b809405ae7d0a6ed93d5cf273c 100644 --- a/include/linux/vermagic.h +++ b/include/linux/vermagic.h @@ -17,6 +17,11 @@ #else #define MODULE_VERMAGIC_MODULE_UNLOAD "" #endif +#ifdef CONFIG_MODVERSIONS +#define MODULE_VERMAGIC_MODVERSIONS "modversions " +#else +#define MODULE_VERMAGIC_MODVERSIONS "" +#endif #ifndef MODULE_ARCH_VERMAGIC #define MODULE_ARCH_VERMAGIC "" #endif @@ -24,5 +29,6 @@ #define VERMAGIC_STRING \ UTS_RELEASE " " \ MODULE_VERMAGIC_SMP MODULE_VERMAGIC_PREEMPT \ - MODULE_VERMAGIC_MODULE_UNLOAD MODULE_ARCH_VERMAGIC + MODULE_VERMAGIC_MODULE_UNLOAD MODULE_VERMAGIC_MODVERSIONS \ + MODULE_ARCH_VERMAGIC diff --git a/include/media/v4l2-i2c-drv-legacy.h b/include/media/v4l2-i2c-drv-legacy.h index 347b6f8beb23761fa4a7c77fa65ad1dc6a81274b..878562278b674588577c88bfeb22cb7858bbd29c 100644 --- a/include/media/v4l2-i2c-drv-legacy.h +++ b/include/media/v4l2-i2c-drv-legacy.h @@ -31,6 +31,7 @@ struct v4l2_i2c_driver_data { int (*resume)(struct i2c_client *client); int (*legacy_probe)(struct i2c_adapter *adapter); int legacy_class; + const struct i2c_device_id *id_table; }; static struct v4l2_i2c_driver_data v4l2_i2c_data; @@ -124,6 +125,7 @@ static int __init v4l2_i2c_drv_init(void) v4l2_i2c_driver.command = v4l2_i2c_data.command; v4l2_i2c_driver.probe = v4l2_i2c_data.probe; v4l2_i2c_driver.remove = v4l2_i2c_data.remove; + v4l2_i2c_driver.id_table = v4l2_i2c_data.id_table; err = i2c_add_driver(&v4l2_i2c_driver); if (err) i2c_del_driver(&v4l2_i2c_driver_legacy); diff --git a/include/media/v4l2-i2c-drv.h b/include/media/v4l2-i2c-drv.h index 7b6f06be795034d7ae64b385bfa9ef0eac4078c9..40ecef29801d3be1e5902cea4aee4a823e87f158 100644 --- a/include/media/v4l2-i2c-drv.h +++ b/include/media/v4l2-i2c-drv.h @@ -36,6 +36,7 @@ struct v4l2_i2c_driver_data { int (*resume)(struct i2c_client *client); int (*legacy_probe)(struct i2c_adapter *adapter); int legacy_class; + const struct i2c_device_id *id_table; }; static struct v4l2_i2c_driver_data v4l2_i2c_data; @@ -53,6 +54,7 @@ static int __init v4l2_i2c_drv_init(void) v4l2_i2c_driver.remove = v4l2_i2c_data.remove; v4l2_i2c_driver.suspend = v4l2_i2c_data.suspend; v4l2_i2c_driver.resume = v4l2_i2c_data.resume; + v4l2_i2c_driver.id_table = v4l2_i2c_data.id_table; return i2c_add_driver(&v4l2_i2c_driver); } diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h index 585eb4496990d7a6c32951e301aaf192b09ca244..b3d3e27c62999d08360dcb51c15430d2d93c953d 100644 --- a/include/net/9p/9p.h +++ b/include/net/9p/9p.h @@ -29,14 +29,31 @@ #ifdef CONFIG_NET_9P_DEBUG -#define P9_DEBUG_ERROR (1<<0) -#define P9_DEBUG_9P (1<<2) -#define P9_DEBUG_VFS (1<<3) -#define P9_DEBUG_CONV (1<<4) -#define P9_DEBUG_MUX (1<<5) -#define P9_DEBUG_TRANS (1<<6) -#define P9_DEBUG_SLABS (1<<7) -#define P9_DEBUG_FCALL (1<<8) +/** + * enum p9_debug_flags - bits for mount time debug parameter + * @P9_DEBUG_ERROR: more verbose error messages including original error string + * @P9_DEBUG_9P: 9P protocol tracing + * @P9_DEBUG_VFS: VFS API tracing + * @P9_DEBUG_CONV: protocol conversion tracing + * @P9_DEBUG_MUX: trace management of concurrent transactions + * @P9_DEBUG_TRANS: transport tracing + * @P9_DEBUG_SLABS: memory management tracing + * @P9_DEBUG_FCALL: verbose dump of protocol messages + * + * These flags are passed at mount time to turn on various levels of + * verbosity and tracing which will be output to the system logs. + */ + +enum p9_debug_flags { + P9_DEBUG_ERROR = (1<<0), + P9_DEBUG_9P = (1<<2), + P9_DEBUG_VFS = (1<<3), + P9_DEBUG_CONV = (1<<4), + P9_DEBUG_MUX = (1<<5), + P9_DEBUG_TRANS = (1<<6), + P9_DEBUG_SLABS = (1<<7), + P9_DEBUG_FCALL = (1<<8), +}; extern unsigned int p9_debug_level; @@ -62,9 +79,47 @@ do { \ format , __FUNCTION__, task_pid_nr(current), ## arg); \ } while (0) +/** + * enum p9_msg_t - 9P message types + * @P9_TVERSION: version handshake request + * @P9_RVERSION: version handshake response + * @P9_TAUTH: request to establish authentication channel + * @P9_RAUTH: response with authentication information + * @P9_TATTACH: establish user access to file service + * @P9_RATTACH: response with top level handle to file hierarchy + * @P9_TERROR: not used + * @P9_RERROR: response for any failed request + * @P9_TFLUSH: request to abort a previous request + * @P9_RFLUSH: response when previous request has been cancelled + * @P9_TWALK: descend a directory hierarchy + * @P9_RWALK: response with new handle for position within hierarchy + * @P9_TOPEN: prepare a handle for I/O on an existing file + * @P9_ROPEN: response with file access information + * @P9_TCREATE: prepare a handle for I/O on a new file + * @P9_RCREATE: response with file access information + * @P9_TREAD: request to transfer data from a file or directory + * @P9_RREAD: response with data requested + * @P9_TWRITE: reuqest to transfer data to a file + * @P9_RWRITE: response with out much data was transfered to file + * @P9_TCLUNK: forget about a handle to an entity within the file system + * @P9_RCLUNK: response when server has forgotten about the handle + * @P9_TREMOVE: request to remove an entity from the hierarchy + * @P9_RREMOVE: response when server has removed the entity + * @P9_TSTAT: request file entity attributes + * @P9_RSTAT: response with file entity attributes + * @P9_TWSTAT: request to update file entity attributes + * @P9_RWSTAT: response when file entity attributes are updated + * + * There are 14 basic operations in 9P2000, paired as + * requests and responses. The one special case is ERROR + * as there is no @P9_TERROR request for clients to transmit to + * the server, but the server may respond to any other request + * with an @P9_RERROR. + * + * See Also: http://plan9.bell-labs.com/sys/man/5/INDEX.html + */ -/* Message Types */ -enum { +enum p9_msg_t { P9_TVERSION = 100, P9_RVERSION, P9_TAUTH = 102, @@ -95,30 +150,71 @@ enum { P9_RWSTAT, }; -/* open modes */ -enum { +/** + * enum p9_open_mode_t - 9P open modes + * @P9_OREAD: open file for reading only + * @P9_OWRITE: open file for writing only + * @P9_ORDWR: open file for reading or writing + * @P9_OEXEC: open file for execution + * @P9_OTRUNC: truncate file to zero-length before opening it + * @P9_OREXEC: close the file when an exec(2) system call is made + * @P9_ORCLOSE: remove the file when the file is closed + * @P9_OAPPEND: open the file and seek to the end + * @P9_OEXCL: only create a file, do not open it + * + * 9P open modes differ slightly from Posix standard modes. + * In particular, there are extra modes which specify different + * semantic behaviors than may be available on standard Posix + * systems. For example, @P9_OREXEC and @P9_ORCLOSE are modes that + * most likely will not be issued from the Linux VFS client, but may + * be supported by servers. + * + * See Also: http://plan9.bell-labs.com/magic/man2html/2/open + */ + +enum p9_open_mode_t { P9_OREAD = 0x00, P9_OWRITE = 0x01, P9_ORDWR = 0x02, P9_OEXEC = 0x03, - P9_OEXCL = 0x04, P9_OTRUNC = 0x10, P9_OREXEC = 0x20, P9_ORCLOSE = 0x40, P9_OAPPEND = 0x80, -}; - -/* permissions */ -enum { + P9_OEXCL = 0x1000, +}; + +/** + * enum p9_perm_t - 9P permissions + * @P9_DMDIR: mode bite for directories + * @P9_DMAPPEND: mode bit for is append-only + * @P9_DMEXCL: mode bit for excluse use (only one open handle allowed) + * @P9_DMMOUNT: mode bite for mount points + * @P9_DMAUTH: mode bit for authentication file + * @P9_DMTMP: mode bit for non-backed-up files + * @P9_DMSYMLINK: mode bit for symbolic links (9P2000.u) + * @P9_DMLINK: mode bit for hard-link (9P2000.u) + * @P9_DMDEVICE: mode bit for device files (9P2000.u) + * @P9_DMNAMEDPIPE: mode bit for named pipe (9P2000.u) + * @P9_DMSOCKET: mode bit for socket (9P2000.u) + * @P9_DMSETUID: mode bit for setuid (9P2000.u) + * @P9_DMSETGID: mode bit for setgid (9P2000.u) + * @P9_DMSETVTX: mode bit for sticky bit (9P2000.u) + * + * 9P permissions differ slightly from Posix standard modes. + * + * See Also: http://plan9.bell-labs.com/magic/man2html/2/stat + */ +enum p9_perm_t { P9_DMDIR = 0x80000000, P9_DMAPPEND = 0x40000000, P9_DMEXCL = 0x20000000, P9_DMMOUNT = 0x10000000, P9_DMAUTH = 0x08000000, P9_DMTMP = 0x04000000, +/* 9P2000.u extensions */ P9_DMSYMLINK = 0x02000000, P9_DMLINK = 0x01000000, - /* 9P2000.u extensions */ P9_DMDEVICE = 0x00800000, P9_DMNAMEDPIPE = 0x00200000, P9_DMSOCKET = 0x00100000, @@ -127,8 +223,26 @@ enum { P9_DMSETVTX = 0x00010000, }; -/* qid.types */ -enum { +/** + * enum p9_qid_t - QID types + * @P9_QTDIR: directory + * @P9_QTAPPEND: append-only + * @P9_QTEXCL: excluse use (only one open handle allowed) + * @P9_QTMOUNT: mount points + * @P9_QTAUTH: authentication file + * @P9_QTTMP: non-backed-up files + * @P9_QTSYMLINK: symbolic links (9P2000.u) + * @P9_QTLINK: hard-link (9P2000.u) + * @P9_QTFILE: normal files + * + * QID types are a subset of permissions - they are primarily + * used to differentiate semantics for a file system entity via + * a jump-table. Their value is also the most signifigant 16 bits + * of the permission_t + * + * See Also: http://plan9.bell-labs.com/magic/man2html/2/stat + */ +enum p9_qid_t { P9_QTDIR = 0x80, P9_QTAPPEND = 0x40, P9_QTEXCL = 0x20, @@ -140,6 +254,7 @@ enum { P9_QTFILE = 0x00, }; +/* 9P Magic Numbers */ #define P9_NOTAG (u16)(~0) #define P9_NOFID (u32)(~0) #define P9_MAXWELEM 16 @@ -147,19 +262,69 @@ enum { /* ample room for Twrite/Rread header */ #define P9_IOHDRSZ 24 +/** + * struct p9_str - length prefixed string type + * @len: length of the string + * @str: the string + * + * The protocol uses length prefixed strings for all + * string data, so we replicate that for our internal + * string members. + */ + struct p9_str { u16 len; char *str; }; -/* qids are the unique ID for a file (like an inode */ +/** + * struct p9_qid - file system entity information + * @type: 8-bit type &p9_qid_t + * @version: 16-bit monotonically incrementing version number + * @path: 64-bit per-server-unique ID for a file system element + * + * qids are identifiers used by 9P servers to track file system + * entities. The type is used to differentiate semantics for operations + * on the entity (ie. read means something different on a directory than + * on a file). The path provides a server unique index for an entity + * (roughly analogous to an inode number), while the version is updated + * every time a file is modified and can be used to maintain cache + * coherency between clients and serves. + * Servers will often differentiate purely synthetic entities by setting + * their version to 0, signaling that they should never be cached and + * should be accessed synchronously. + * + * See Also://plan9.bell-labs.com/magic/man2html/2/stat + */ + struct p9_qid { u8 type; u32 version; u64 path; }; -/* Plan 9 file metadata (stat) structure */ +/** + * struct p9_stat - file system metadata information + * @size: length prefix for this stat structure instance + * @type: the type of the server (equivilent to a major number) + * @dev: the sub-type of the server (equivilent to a minor number) + * @qid: unique id from the server of type &p9_qid + * @mode: Plan 9 format permissions of type &p9_perm_t + * @atime: Last access/read time + * @mtime: Last modify/write time + * @length: file length + * @name: last element of path (aka filename) in type &p9_str + * @uid: owner name in type &p9_str + * @gid: group owner in type &p9_str + * @muid: last modifier in type &p9_str + * @extension: area used to encode extended UNIX support in type &p9_str + * @n_uid: numeric user id of owner (part of 9p2000.u extension) + * @n_gid: numeric group id (part of 9p2000.u extension) + * @n_muid: numeric user id of laster modifier (part of 9p2000.u extension) + * + * See Also: http://plan9.bell-labs.com/magic/man2html/2/stat + */ + struct p9_stat { u16 size; u16 type; @@ -179,10 +344,14 @@ struct p9_stat { u32 n_muid; /* 9p2000.u extensions */ }; -/* file metadata (stat) structure used to create Twstat message - The is similar to p9_stat, but the strings don't point to - the same memory block and should be freed separately -*/ +/* + * file metadata (stat) structure used to create Twstat message + * The is identical to &p9_stat, but the strings don't point to + * the same memory block and should be freed separately + * + * See Also: http://plan9.bell-labs.com/magic/man2html/2/stat + */ + struct p9_wstat { u16 size; u16 type; @@ -335,10 +504,20 @@ struct p9_twstat { struct p9_rwstat { }; -/* - * fcall is the primary packet structure - * - */ +/** + * struct p9_fcall - primary packet structure + * @size: prefixed length of the structure + * @id: protocol operating identifier of type &p9_msg_t + * @tag: transaction id of the request + * @sdata: payload + * @params: per-operation parameters + * + * &p9_fcall represents the structure for all 9P RPC + * transactions. Requests are packaged into fcalls, and reponses + * must be extracted from them. + * + * See Also: http://plan9.bell-labs.com/magic/man2html/2/fcall + */ struct p9_fcall { u32 size; @@ -416,4 +595,5 @@ int p9_idpool_check(int id, struct p9_idpool *p); int p9_error_init(void); int p9_errstr2errno(char *, int); +int p9_trans_fd_init(void); #endif /* NET_9P_H */ diff --git a/include/net/9p/client.h b/include/net/9p/client.h index e52f93d9ac5fca1dccdbe66a256b2d1b241f1e75..c936dd14de41be35466b8bd55a9e42cd36f91a91 100644 --- a/include/net/9p/client.h +++ b/include/net/9p/client.h @@ -26,6 +26,23 @@ #ifndef NET_9P_CLIENT_H #define NET_9P_CLIENT_H +/** + * struct p9_client - per client instance state + * @lock: protect @fidlist + * @msize: maximum data size negotiated by protocol + * @dotu: extension flags negotiated by protocol + * @trans_mod: module API instantiated with this client + * @trans: tranport instance state and API + * @conn: connection state information used by trans_fd + * @fidpool: fid handle accounting for session + * @fidlist: List of active fid handles + * + * The client structure is used to keep track of various per-client + * state that has been instantiated. + * + * Bugs: duplicated data and potentially unnecessary elements. + */ + struct p9_client { spinlock_t lock; /* protect client structure */ int msize; @@ -38,6 +55,24 @@ struct p9_client { struct list_head fidlist; }; +/** + * struct p9_fid - file system entity handle + * @clnt: back pointer to instantiating &p9_client + * @fid: numeric identifier for this handle + * @mode: current mode of this fid (enum?) + * @qid: the &p9_qid server identifier this handle points to + * @iounit: the server reported maximum transaction size for this file + * @uid: the numeric uid of the local user who owns this handle + * @aux: transport specific information (unused?) + * @rdir_fpos: tracks offset of file position when reading directory contents + * @rdir_pos: (unused?) + * @rdir_fcall: holds response of last directory read request + * @flist: per-client-instance fid tracking + * @dlist: per-dentry fid tracking + * + * TODO: This needs lots of explanation. + */ + struct p9_fid { struct p9_client *clnt; u32 fid; diff --git a/include/net/9p/transport.h b/include/net/9p/transport.h index d2209ae9d18b1a94a61e14ff00c4d6e0d2f1c638..0db3a4038dc0d1e8feb9f89f763203169b335b36 100644 --- a/include/net/9p/transport.h +++ b/include/net/9p/transport.h @@ -26,12 +26,40 @@ #ifndef NET_9P_TRANSPORT_H #define NET_9P_TRANSPORT_H +/** + * enum p9_trans_status - different states of underlying transports + * @Connected: transport is connected and healthy + * @Disconnected: transport has been disconnected + * @Hung: transport is connected by wedged + * + * This enumeration details the various states a transport + * instatiation can be in. + */ + enum p9_trans_status { Connected, Disconnected, Hung, }; +/** + * struct p9_trans - per-transport state and API + * @status: transport &p9_trans_status + * @msize: negotiated maximum packet size (duplicate from client) + * @extended: negotiated protocol extensions (duplicate from client) + * @priv: transport private data + * @close: member function to disconnect and close the transport + * @rpc: member function to issue a request to the transport + * + * This is the basic API for a transport instance. It is used as + * a handle by the client to issue requests. This interface is currently + * in flux during reorganization. + * + * Bugs: there is lots of duplicated data here and its not clear that + * the member functions need to be per-instance versus per transport + * module. + */ + struct p9_trans { enum p9_trans_status status; int msize; @@ -42,6 +70,21 @@ struct p9_trans { struct p9_fcall **rc); }; +/** + * struct p9_trans_module - transport module interface + * @list: used to maintain a list of currently available transports + * @name: the human-readable name of the transport + * @maxsize: transport provided maximum packet size + * @def: set if this transport should be considered the default + * @create: member function to create a new connection on this transport + * + * This is the basic API for a transport module which is registered by the + * transport module with the 9P core network module and used by the client + * to instantiate a new connection on a transport. + * + * Bugs: the transport module list isn't protected. + */ + struct p9_trans_module { struct list_head list; char *name; /* name of transport */ @@ -53,5 +96,4 @@ struct p9_trans_module { void v9fs_register_trans(struct p9_trans_module *m); struct p9_trans_module *v9fs_match_trans(const substring_t *name); struct p9_trans_module *v9fs_default_trans(void); - #endif /* NET_9P_TRANSPORT_H */ diff --git a/include/net/ip.h b/include/net/ip.h index 6d7bcd5e62d48ce689b1700afa9e34a82401e86e..3b40bc2234becd9099dc2e5bb70d352474a04210 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -210,7 +210,7 @@ int ip_dont_fragment(struct sock *sk, struct dst_entry *dst) { return (inet_sk(sk)->pmtudisc == IP_PMTUDISC_DO || (inet_sk(sk)->pmtudisc == IP_PMTUDISC_WANT && - !(dst_metric(dst, RTAX_LOCK)&(1<priv; + struct ppp_device **ppp = dev->ml_priv; BUG_ON((*ppp)->dev != dev); return &(*ppp)->sppp; } diff --git a/include/net/xfrm.h b/include/net/xfrm.h index d1350bcccb03c68efb07bac000b16c0f9cb49ca1..2933d7474a79541a8de4c38e53e3b2b2f6f9ca77 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -648,14 +648,46 @@ extern void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family, extern void xfrm_audit_state_icvfail(struct xfrm_state *x, struct sk_buff *skb, u8 proto); #else -#define xfrm_audit_policy_add(x, r, a, se, s) do { ; } while (0) -#define xfrm_audit_policy_delete(x, r, a, se, s) do { ; } while (0) -#define xfrm_audit_state_add(x, r, a, se, s) do { ; } while (0) -#define xfrm_audit_state_delete(x, r, a, se, s) do { ; } while (0) -#define xfrm_audit_state_replay_overflow(x, s) do { ; } while (0) -#define xfrm_audit_state_notfound_simple(s, f) do { ; } while (0) -#define xfrm_audit_state_notfound(s, f, sp, sq) do { ; } while (0) -#define xfrm_audit_state_icvfail(x, s, p) do { ; } while (0) + +static inline void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, + u32 auid, u32 ses, u32 secid) +{ +} + +static inline void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, + u32 auid, u32 ses, u32 secid) +{ +} + +static inline void xfrm_audit_state_add(struct xfrm_state *x, int result, + u32 auid, u32 ses, u32 secid) +{ +} + +static inline void xfrm_audit_state_delete(struct xfrm_state *x, int result, + u32 auid, u32 ses, u32 secid) +{ +} + +static inline void xfrm_audit_state_replay_overflow(struct xfrm_state *x, + struct sk_buff *skb) +{ +} + +static inline void xfrm_audit_state_notfound_simple(struct sk_buff *skb, + u16 family) +{ +} + +static inline void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family, + __be32 net_spi, __be32 net_seq) +{ +} + +static inline void xfrm_audit_state_icvfail(struct xfrm_state *x, + struct sk_buff *skb, u8 proto) +{ +} #endif /* CONFIG_AUDITSYSCALL */ static inline void xfrm_pol_hold(struct xfrm_policy *policy) diff --git a/include/sound/soc.h b/include/sound/soc.h index e6ea6f7509414566c2327a841e206b7249cbaa2c..d3c8c033dff83b06d772e4dab9178f35413e17ff 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -238,7 +238,7 @@ int snd_soc_info_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo); int snd_soc_info_volsw_ext(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo); -#define snd_soc_info_bool_ext snd_ctl_boolean_mono +#define snd_soc_info_bool_ext snd_ctl_boolean_mono_info int snd_soc_get_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); int snd_soc_put_volsw(struct snd_kcontrol *kcontrol, diff --git a/init/Kconfig b/init/Kconfig index 4c33316743f51528bc9f583f6c18ee1cadd96a08..6135d07f31ece506c597e06c04d220d53308fbfe 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -634,6 +634,14 @@ config ELF_CORE help Enable support for generating core dumps. Disabling saves about 4k. +config PCSPKR_PLATFORM + bool "Enable PC-Speaker support" if EMBEDDED + depends on ALPHA || X86 || MIPS || PPC_PREP || PPC_CHRP || PPC_PSERIES + default y + help + This option allows to disable the internal PC-Speaker + support, saving some memory. + config COMPAT_BRK bool "Disable heap randomization" default y @@ -837,9 +845,9 @@ config MODULE_FORCE_LOAD depends on MODULES default n help - This option allows loading of modules even if that would set the - 'F' (forced) taint, due to lack of version info. Which is - usually a really bad idea. + Allow loading of modules without version information (ie. modprobe + --force). Forced module loading sets the 'F' (forced) taint flag and + is usually a really bad idea. config MODULE_UNLOAD bool "Module unloading" diff --git a/init/do_mounts.c b/init/do_mounts.c index 3885e70e7759d236c8677959174fb0063997f649..660c1e50c91b7a622b2e65bf1095cd4e982b58af 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -76,6 +76,7 @@ dev_t name_to_dev_t(char *name) char s[32]; char *p; dev_t res = 0; + int part; if (strncmp(name, "/dev/", 5) != 0) { unsigned maj, min; @@ -106,7 +107,31 @@ dev_t name_to_dev_t(char *name) for (p = s; *p; p++) if (*p == '/') *p = '!'; - res = blk_lookup_devt(s); + res = blk_lookup_devt(s, 0); + if (res) + goto done; + + /* + * try non-existant, but valid partition, which may only exist + * after revalidating the disk, like partitioned md devices + */ + while (p > s && isdigit(p[-1])) + p--; + if (p == s || !*p || *p == '0') + goto fail; + + /* try disk name without */ + part = simple_strtoul(p, NULL, 10); + *p = '\0'; + res = blk_lookup_devt(s, part); + if (res) + goto done; + + /* try disk name without p */ + if (p < s + 2 || !isdigit(p[-2]) || p[-1] != 'p') + goto fail; + p[-1] = '\0'; + res = blk_lookup_devt(s, part); if (res) goto done; diff --git a/init/main.c b/init/main.c index ddada7acf363c9b4dda58913a3080da6462e4b09..f7fb20021d48d5a4a175cc79d84f6b3cfb9eab53 100644 --- a/init/main.c +++ b/init/main.c @@ -693,55 +693,57 @@ static int __init initcall_debug_setup(char *str) } __setup("initcall_debug", initcall_debug_setup); -extern initcall_t __initcall_start[], __initcall_end[]; - -static void __init do_initcalls(void) +static void __init do_one_initcall(initcall_t fn) { - initcall_t *call; int count = preempt_count(); + ktime_t t0, t1, delta; + char msgbuf[64]; + int result; - for (call = __initcall_start; call < __initcall_end; call++) { - ktime_t t0, t1, delta; - char *msg = NULL; - char msgbuf[40]; - int result; + if (initcall_debug) { + print_fn_descriptor_symbol("calling %s\n", fn); + t0 = ktime_get(); + } - if (initcall_debug) { - print_fn_descriptor_symbol("calling %s()\n", - (unsigned long) *call); - t0 = ktime_get(); - } + result = fn(); - result = (*call)(); + if (initcall_debug) { + t1 = ktime_get(); + delta = ktime_sub(t1, t0); - if (initcall_debug) { - t1 = ktime_get(); - delta = ktime_sub(t1, t0); + print_fn_descriptor_symbol("initcall %s", fn); + printk(" returned %d after %Ld msecs\n", result, + (unsigned long long) delta.tv64 >> 20); + } - print_fn_descriptor_symbol("initcall %s()", - (unsigned long) *call); - printk(" returned %d after %Ld msecs\n", result, - (unsigned long long) delta.tv64 >> 20); - } + msgbuf[0] = 0; - if (result && result != -ENODEV && initcall_debug) { - sprintf(msgbuf, "error code %d", result); - msg = msgbuf; - } - if (preempt_count() != count) { - msg = "preemption imbalance"; - preempt_count() = count; - } - if (irqs_disabled()) { - msg = "disabled interrupts"; - local_irq_enable(); - } - if (msg) { - print_fn_descriptor_symbol(KERN_WARNING "initcall %s()", - (unsigned long) *call); - printk(" returned with %s\n", msg); - } + if (result && result != -ENODEV && initcall_debug) + sprintf(msgbuf, "error code %d ", result); + + if (preempt_count() != count) { + strlcat(msgbuf, "preemption imbalance ", sizeof(msgbuf)); + preempt_count() = count; + } + if (irqs_disabled()) { + strlcat(msgbuf, "disabled interrupts ", sizeof(msgbuf)); + local_irq_enable(); + } + if (msgbuf[0]) { + print_fn_descriptor_symbol(KERN_WARNING "initcall %s", fn); + printk(" returned with %s\n", msgbuf); } +} + + +extern initcall_t __initcall_start[], __initcall_end[]; + +static void __init do_initcalls(void) +{ + initcall_t *call; + + for (call = __initcall_start; call < __initcall_end; call++) + do_one_initcall(*call); /* Make sure there is no pending stuff from the initcall sequence */ flush_scheduled_work(); diff --git a/kernel/audit.c b/kernel/audit.c index b7d3709cc452afdba06492ecf2c977bab04dd530..e8692a5748c24d2bd841ea7a81eaa09ae992bb04 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -572,16 +572,17 @@ void audit_send_reply(int pid, int seq, int type, int done, int multi, skb = audit_make_reply(pid, seq, type, done, multi, payload, size); if (!skb) - return; + goto out; reply->pid = pid; reply->skb = skb; tsk = kthread_run(audit_send_reply_thread, reply, "audit_send_reply"); - if (IS_ERR(tsk)) { - kfree(reply); - kfree_skb(skb); - } + if (!IS_ERR(tsk)) + return; + kfree_skb(skb); +out: + kfree(reply); } /* diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c index 9ef5e0aacc3cd5461d203b2a998f40186f02dd8a..f7921a2ecf16c07537971fd62624ef1a40046812 100644 --- a/kernel/audit_tree.c +++ b/kernel/audit_tree.c @@ -172,10 +172,9 @@ static void insert_hash(struct audit_chunk *chunk) struct audit_chunk *audit_tree_lookup(const struct inode *inode) { struct list_head *list = chunk_hash(inode); - struct list_head *pos; + struct audit_chunk *p; - list_for_each_rcu(pos, list) { - struct audit_chunk *p = container_of(pos, struct audit_chunk, hash); + list_for_each_entry_rcu(p, list, hash) { if (p->watch.inode == inode) { get_inotify_watch(&p->watch); return p; diff --git a/kernel/cpuset.c b/kernel/cpuset.c index 8da627d33804db7c9e30936fead573cedd4407e3..86ea9e34e3260138401663be21dd22d1892c4ce3 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c @@ -1031,11 +1031,9 @@ int current_cpuset_is_being_rebound(void) return task_cs(current) == cpuset_being_rebound; } -static int update_relax_domain_level(struct cpuset *cs, char *buf) +static int update_relax_domain_level(struct cpuset *cs, s64 val) { - int val = simple_strtol(buf, NULL, 10); - - if (val < 0) + if ((int)val < 0) val = -1; if (val != cs->relax_domain_level) { @@ -1280,9 +1278,6 @@ static ssize_t cpuset_common_file_write(struct cgroup *cont, case FILE_MEMLIST: retval = update_nodemask(cs, buffer); break; - case FILE_SCHED_RELAX_DOMAIN_LEVEL: - retval = update_relax_domain_level(cs, buffer); - break; default: retval = -EINVAL; goto out2; @@ -1348,6 +1343,30 @@ static int cpuset_write_u64(struct cgroup *cgrp, struct cftype *cft, u64 val) return retval; } +static int cpuset_write_s64(struct cgroup *cgrp, struct cftype *cft, s64 val) +{ + int retval = 0; + struct cpuset *cs = cgroup_cs(cgrp); + cpuset_filetype_t type = cft->private; + + cgroup_lock(); + + if (cgroup_is_removed(cgrp)) { + cgroup_unlock(); + return -ENODEV; + } + switch (type) { + case FILE_SCHED_RELAX_DOMAIN_LEVEL: + retval = update_relax_domain_level(cs, val); + break; + default: + retval = -EINVAL; + break; + } + cgroup_unlock(); + return retval; +} + /* * These ascii lists should be read in a single call, by using a user * buffer large enough to hold the entire map. If read in smaller @@ -1406,9 +1425,6 @@ static ssize_t cpuset_common_file_read(struct cgroup *cont, case FILE_MEMLIST: s += cpuset_sprintf_memlist(s, cs); break; - case FILE_SCHED_RELAX_DOMAIN_LEVEL: - s += sprintf(s, "%d", cs->relax_domain_level); - break; default: retval = -EINVAL; goto out; @@ -1449,6 +1465,18 @@ static u64 cpuset_read_u64(struct cgroup *cont, struct cftype *cft) } } +static s64 cpuset_read_s64(struct cgroup *cont, struct cftype *cft) +{ + struct cpuset *cs = cgroup_cs(cont); + cpuset_filetype_t type = cft->private; + switch (type) { + case FILE_SCHED_RELAX_DOMAIN_LEVEL: + return cs->relax_domain_level; + default: + BUG(); + } +} + /* * for the common functions, 'private' gives the type of file @@ -1499,8 +1527,8 @@ static struct cftype files[] = { { .name = "sched_relax_domain_level", - .read_u64 = cpuset_read_u64, - .write_u64 = cpuset_write_u64, + .read_s64 = cpuset_read_s64, + .write_s64 = cpuset_write_s64, .private = FILE_SCHED_RELAX_DOMAIN_LEVEL, }, diff --git a/kernel/fork.c b/kernel/fork.c index 933e60ebccae9f35001753a4426993c6aaf54fb6..19908b26cf80494a0db8f3410384521081293a32 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -660,136 +660,6 @@ static int copy_fs(unsigned long clone_flags, struct task_struct *tsk) return 0; } -static int count_open_files(struct fdtable *fdt) -{ - int size = fdt->max_fds; - int i; - - /* Find the last open fd */ - for (i = size/(8*sizeof(long)); i > 0; ) { - if (fdt->open_fds->fds_bits[--i]) - break; - } - i = (i+1) * 8 * sizeof(long); - return i; -} - -static struct files_struct *alloc_files(void) -{ - struct files_struct *newf; - struct fdtable *fdt; - - newf = kmem_cache_alloc(files_cachep, GFP_KERNEL); - if (!newf) - goto out; - - atomic_set(&newf->count, 1); - - spin_lock_init(&newf->file_lock); - newf->next_fd = 0; - fdt = &newf->fdtab; - fdt->max_fds = NR_OPEN_DEFAULT; - fdt->close_on_exec = (fd_set *)&newf->close_on_exec_init; - fdt->open_fds = (fd_set *)&newf->open_fds_init; - fdt->fd = &newf->fd_array[0]; - INIT_RCU_HEAD(&fdt->rcu); - fdt->next = NULL; - rcu_assign_pointer(newf->fdt, fdt); -out: - return newf; -} - -/* - * Allocate a new files structure and copy contents from the - * passed in files structure. - * errorp will be valid only when the returned files_struct is NULL. - */ -static struct files_struct *dup_fd(struct files_struct *oldf, int *errorp) -{ - struct files_struct *newf; - struct file **old_fds, **new_fds; - int open_files, size, i; - struct fdtable *old_fdt, *new_fdt; - - *errorp = -ENOMEM; - newf = alloc_files(); - if (!newf) - goto out; - - spin_lock(&oldf->file_lock); - old_fdt = files_fdtable(oldf); - new_fdt = files_fdtable(newf); - open_files = count_open_files(old_fdt); - - /* - * Check whether we need to allocate a larger fd array and fd set. - * Note: we're not a clone task, so the open count won't change. - */ - if (open_files > new_fdt->max_fds) { - new_fdt->max_fds = 0; - spin_unlock(&oldf->file_lock); - spin_lock(&newf->file_lock); - *errorp = expand_files(newf, open_files-1); - spin_unlock(&newf->file_lock); - if (*errorp < 0) - goto out_release; - new_fdt = files_fdtable(newf); - /* - * Reacquire the oldf lock and a pointer to its fd table - * who knows it may have a new bigger fd table. We need - * the latest pointer. - */ - spin_lock(&oldf->file_lock); - old_fdt = files_fdtable(oldf); - } - - old_fds = old_fdt->fd; - new_fds = new_fdt->fd; - - memcpy(new_fdt->open_fds->fds_bits, - old_fdt->open_fds->fds_bits, open_files/8); - memcpy(new_fdt->close_on_exec->fds_bits, - old_fdt->close_on_exec->fds_bits, open_files/8); - - for (i = open_files; i != 0; i--) { - struct file *f = *old_fds++; - if (f) { - get_file(f); - } else { - /* - * The fd may be claimed in the fd bitmap but not yet - * instantiated in the files array if a sibling thread - * is partway through open(). So make sure that this - * fd is available to the new process. - */ - FD_CLR(open_files - i, new_fdt->open_fds); - } - rcu_assign_pointer(*new_fds++, f); - } - spin_unlock(&oldf->file_lock); - - /* compute the remainder to be cleared */ - size = (new_fdt->max_fds - open_files) * sizeof(struct file *); - - /* This is long word aligned thus could use a optimized version */ - memset(new_fds, 0, size); - - if (new_fdt->max_fds > open_files) { - int left = (new_fdt->max_fds-open_files)/8; - int start = open_files / (8 * sizeof(unsigned long)); - - memset(&new_fdt->open_fds->fds_bits[start], 0, left); - memset(&new_fdt->close_on_exec->fds_bits[start], 0, left); - } - - return newf; - -out_release: - kmem_cache_free(files_cachep, newf); -out: - return NULL; -} - static int copy_files(unsigned long clone_flags, struct task_struct * tsk) { struct files_struct *oldf, *newf; diff --git a/kernel/kgdb.c b/kernel/kgdb.c index 39e31a036f5b0e31bf6187df2751a589d409b328..14787de568b3c916320d06e5f73184e65966dfcc 100644 --- a/kernel/kgdb.c +++ b/kernel/kgdb.c @@ -346,14 +346,6 @@ static void put_packet(char *buffer) } } -static char *pack_hex_byte(char *pkt, u8 byte) -{ - *pkt++ = hexchars[byte >> 4]; - *pkt++ = hexchars[byte & 0xf]; - - return pkt; -} - /* * Convert the memory pointed to by mem into hex, placing result in buf. * Return a pointer to the last char put in buf (null). May return an error. diff --git a/kernel/module.c b/kernel/module.c index 8e4528c9909feab87fe000ea56beb3d69fc26819..f5e9491ef7ac2ed9d9473ded84c37f5018ed722c 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -917,6 +917,10 @@ static int check_version(Elf_Shdr *sechdrs, if (!crc) return 1; + /* No versions at all? modprobe --force does this. */ + if (versindex == 0) + return try_to_force_load(mod, symname) == 0; + versions = (void *) sechdrs[versindex].sh_addr; num_versions = sechdrs[versindex].sh_size / sizeof(struct modversion_info); @@ -932,8 +936,9 @@ static int check_version(Elf_Shdr *sechdrs, goto bad_version; } - if (!try_to_force_load(mod, symname)) - return 1; + printk(KERN_WARNING "%s: no symbol version for %s\n", + mod->name, symname); + return 0; bad_version: printk("%s: disagrees about version of symbol %s\n", @@ -952,11 +957,14 @@ static inline int check_modstruct_version(Elf_Shdr *sechdrs, return check_version(sechdrs, versindex, "struct_module", mod, crc); } -/* First part is kernel version, which we ignore. */ -static inline int same_magic(const char *amagic, const char *bmagic) +/* First part is kernel version, which we ignore if module has crcs. */ +static inline int same_magic(const char *amagic, const char *bmagic, + bool has_crcs) { - amagic += strcspn(amagic, " "); - bmagic += strcspn(bmagic, " "); + if (has_crcs) { + amagic += strcspn(amagic, " "); + bmagic += strcspn(bmagic, " "); + } return strcmp(amagic, bmagic) == 0; } #else @@ -976,7 +984,8 @@ static inline int check_modstruct_version(Elf_Shdr *sechdrs, return 1; } -static inline int same_magic(const char *amagic, const char *bmagic) +static inline int same_magic(const char *amagic, const char *bmagic, + bool has_crcs) { return strcmp(amagic, bmagic) == 0; } @@ -1869,7 +1878,7 @@ static struct module *load_module(void __user *umod, err = try_to_force_load(mod, "magic"); if (err) goto free_hdr; - } else if (!same_magic(modmagic, vermagic)) { + } else if (!same_magic(modmagic, vermagic, versindex)) { printk(KERN_ERR "%s: version magic '%s' should be '%s'\n", mod->name, modmagic, vermagic); err = -ENOEXEC; diff --git a/kernel/relay.c b/kernel/relay.c index 7de644cdec43590be390d3037206e5722aa46856..bc24dcdc570f5dfa222edbff1c1a2d80e23cb7e1 100644 --- a/kernel/relay.c +++ b/kernel/relay.c @@ -1191,7 +1191,7 @@ static ssize_t relay_file_splice_read(struct file *in, ret = 0; spliced = 0; - while (len && !spliced) { + while (len) { ret = subbuf_splice_actor(in, ppos, pipe, len, flags, &nonpad_ret); if (ret < 0) break; diff --git a/kernel/sched.c b/kernel/sched.c index 58fb8af157762ace482952419c724f5dc23063a1..cfa222a91539e193a54d20d422fa92b43a19334b 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -4567,8 +4567,6 @@ EXPORT_SYMBOL(schedule); asmlinkage void __sched preempt_schedule(void) { struct thread_info *ti = current_thread_info(); - struct task_struct *task = current; - int saved_lock_depth; /* * If there is a non-zero preempt_count or interrupts are disabled, @@ -4579,16 +4577,7 @@ asmlinkage void __sched preempt_schedule(void) do { add_preempt_count(PREEMPT_ACTIVE); - - /* - * We keep the big kernel semaphore locked, but we - * clear ->lock_depth so that schedule() doesnt - * auto-release the semaphore: - */ - saved_lock_depth = task->lock_depth; - task->lock_depth = -1; schedule(); - task->lock_depth = saved_lock_depth; sub_preempt_count(PREEMPT_ACTIVE); /* @@ -4609,26 +4598,15 @@ EXPORT_SYMBOL(preempt_schedule); asmlinkage void __sched preempt_schedule_irq(void) { struct thread_info *ti = current_thread_info(); - struct task_struct *task = current; - int saved_lock_depth; /* Catch callers which need to be fixed */ BUG_ON(ti->preempt_count || !irqs_disabled()); do { add_preempt_count(PREEMPT_ACTIVE); - - /* - * We keep the big kernel semaphore locked, but we - * clear ->lock_depth so that schedule() doesnt - * auto-release the semaphore: - */ - saved_lock_depth = task->lock_depth; - task->lock_depth = -1; local_irq_enable(); schedule(); local_irq_disable(); - task->lock_depth = saved_lock_depth; sub_preempt_count(PREEMPT_ACTIVE); /* @@ -5547,7 +5525,6 @@ static void __cond_resched(void) } while (need_resched()); } -#if !defined(CONFIG_PREEMPT) || defined(CONFIG_PREEMPT_VOLUNTARY) int __sched _cond_resched(void) { if (need_resched() && !(preempt_count() & PREEMPT_ACTIVE) && @@ -5558,7 +5535,6 @@ int __sched _cond_resched(void) return 0; } EXPORT_SYMBOL(_cond_resched); -#endif /* * cond_resched_lock() - if a reschedule is pending, drop the given lock, @@ -5853,8 +5829,11 @@ void __cpuinit init_idle(struct task_struct *idle, int cpu) spin_unlock_irqrestore(&rq->lock, flags); /* Set the preempt count _outside_ the spinlocks! */ +#if defined(CONFIG_PREEMPT) + task_thread_info(idle)->preempt_count = (idle->lock_depth >= 0); +#else task_thread_info(idle)->preempt_count = 0; - +#endif /* * The idle tasks have their own, simple scheduling class: */ @@ -9007,7 +8986,7 @@ static u64 cpu_shares_read_u64(struct cgroup *cgrp, struct cftype *cft) #endif #ifdef CONFIG_RT_GROUP_SCHED -static ssize_t cpu_rt_runtime_write(struct cgroup *cgrp, struct cftype *cft, +static int cpu_rt_runtime_write(struct cgroup *cgrp, struct cftype *cft, s64 val) { return sched_group_set_rt_runtime(cgroup_tg(cgrp), val); diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index c863663d204d9db21838e427950ac13e6d731ebc..e24ecd39c4b8aec9786d0ab3df0a01ad6dcba08d 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c @@ -662,10 +662,15 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial) if (!initial) { /* sleeps upto a single latency don't count. */ if (sched_feat(NEW_FAIR_SLEEPERS)) { + unsigned long thresh = sysctl_sched_latency; + + /* + * convert the sleeper threshold into virtual time + */ if (sched_feat(NORMALIZED_SLEEPER)) - vruntime -= calc_delta_weight(sysctl_sched_latency, se); - else - vruntime -= sysctl_sched_latency; + thresh = calc_delta_fair(thresh, se); + + vruntime -= thresh; } /* ensure we never gain time by being placed backwards. */ diff --git a/kernel/sysctl.c b/kernel/sysctl.c index d7ffdc59816ad3f822389d508f3c5ff1b030578d..29116652dca825943ed7cb8e70350108542ce641 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -81,6 +81,7 @@ extern int compat_log; extern int maps_protect; extern int sysctl_stat_interval; extern int latencytop_enabled; +extern int sysctl_nr_open_min, sysctl_nr_open_max; /* Constants used for minimum and maximum */ #if defined(CONFIG_DETECT_SOFTLOCKUP) || defined(CONFIG_HIGHMEM) @@ -1190,7 +1191,9 @@ static struct ctl_table fs_table[] = { .data = &sysctl_nr_open, .maxlen = sizeof(int), .mode = 0644, - .proc_handler = &proc_dointvec, + .proc_handler = &proc_dointvec_minmax, + .extra1 = &sysctl_nr_open_min, + .extra2 = &sysctl_nr_open_max, }, { .ctl_name = FS_DENTRY, diff --git a/lib/bitmap.c b/lib/bitmap.c index c4cb48f77f0c6ab157ba41ec0411644a44a39ca9..482df94ea21eb3e9ab7b2ef4efe88643147c3d80 100644 --- a/lib/bitmap.c +++ b/lib/bitmap.c @@ -315,22 +315,6 @@ int bitmap_scnprintf(char *buf, unsigned int buflen, } EXPORT_SYMBOL(bitmap_scnprintf); -/** - * bitmap_scnprintf_len - return buffer length needed to convert - * bitmap to an ASCII hex string. - * @len: number of bits to be converted - */ -int bitmap_scnprintf_len(unsigned int len) -{ - /* we need 9 chars per word for 32 bit words (8 hexdigits + sep/null) */ - int bitslen = ALIGN(len, CHUNKSZ); - int wordlen = CHUNKSZ / 4; - int buflen = (bitslen / wordlen) * (wordlen + 1) * sizeof(char); - - return buflen; -} -EXPORT_SYMBOL(bitmap_scnprintf_len); - /** * __bitmap_parse - convert an ASCII hex string into a bitmap. * @buf: pointer to buffer containing string. diff --git a/lib/hexdump.c b/lib/hexdump.c index 343546550dc906b92b44605bfb613f7d740c1467..f07c0db81d262eb8ff185391bf6577adae064e1f 100644 --- a/lib/hexdump.c +++ b/lib/hexdump.c @@ -12,6 +12,9 @@ #include #include +const char hex_asc[] = "0123456789abcdef"; +EXPORT_SYMBOL(hex_asc); + /** * hex_dump_to_buffer - convert a blob of data to "hex ASCII" in memory * @buf: data blob to dump @@ -93,8 +96,8 @@ void hex_dump_to_buffer(const void *buf, size_t len, int rowsize, for (j = 0; (j < rowsize) && (j < len) && (lx + 4) < linebuflen; j++) { ch = ptr[j]; - linebuf[lx++] = hex_asc(ch >> 4); - linebuf[lx++] = hex_asc(ch & 0x0f); + linebuf[lx++] = hex_asc_hi(ch); + linebuf[lx++] = hex_asc_lo(ch); linebuf[lx++] = ' '; } ascii_column = 3 * rowsize + 2; diff --git a/lib/kernel_lock.c b/lib/kernel_lock.c index cd3e82530b03b7099d9ee6f777623a0140a43a0c..01a3c22c1b5a9c951dc33a0c37179306f36e18e4 100644 --- a/lib/kernel_lock.c +++ b/lib/kernel_lock.c @@ -11,79 +11,121 @@ #include /* - * The 'big kernel semaphore' + * The 'big kernel lock' * - * This mutex is taken and released recursively by lock_kernel() + * This spinlock is taken and released recursively by lock_kernel() * and unlock_kernel(). It is transparently dropped and reacquired * over schedule(). It is used to protect legacy code that hasn't * been migrated to a proper locking design yet. * - * Note: code locked by this semaphore will only be serialized against - * other code using the same locking facility. The code guarantees that - * the task remains on the same CPU. - * * Don't use in new code. */ -static DECLARE_MUTEX(kernel_sem); +static __cacheline_aligned_in_smp DEFINE_SPINLOCK(kernel_flag); + /* - * Re-acquire the kernel semaphore. + * Acquire/release the underlying lock from the scheduler. * - * This function is called with preemption off. + * This is called with preemption disabled, and should + * return an error value if it cannot get the lock and + * TIF_NEED_RESCHED gets set. * - * We are executing in schedule() so the code must be extremely careful - * about recursion, both due to the down() and due to the enabling of - * preemption. schedule() will re-check the preemption flag after - * reacquiring the semaphore. + * If it successfully gets the lock, it should increment + * the preemption count like any spinlock does. + * + * (This works on UP too - _raw_spin_trylock will never + * return false in that case) */ int __lockfunc __reacquire_kernel_lock(void) { - struct task_struct *task = current; - int saved_lock_depth = task->lock_depth; - - BUG_ON(saved_lock_depth < 0); - - task->lock_depth = -1; - preempt_enable_no_resched(); - - down(&kernel_sem); - + while (!_raw_spin_trylock(&kernel_flag)) { + if (test_thread_flag(TIF_NEED_RESCHED)) + return -EAGAIN; + cpu_relax(); + } preempt_disable(); - task->lock_depth = saved_lock_depth; - return 0; } void __lockfunc __release_kernel_lock(void) { - up(&kernel_sem); + _raw_spin_unlock(&kernel_flag); + preempt_enable_no_resched(); } /* - * Getting the big kernel semaphore. + * These are the BKL spinlocks - we try to be polite about preemption. + * If SMP is not on (ie UP preemption), this all goes away because the + * _raw_spin_trylock() will always succeed. */ -void __lockfunc lock_kernel(void) +#ifdef CONFIG_PREEMPT +static inline void __lock_kernel(void) { - struct task_struct *task = current; - int depth = task->lock_depth + 1; + preempt_disable(); + if (unlikely(!_raw_spin_trylock(&kernel_flag))) { + /* + * If preemption was disabled even before this + * was called, there's nothing we can be polite + * about - just spin. + */ + if (preempt_count() > 1) { + _raw_spin_lock(&kernel_flag); + return; + } - if (likely(!depth)) /* - * No recursion worries - we set up lock_depth _after_ + * Otherwise, let's wait for the kernel lock + * with preemption enabled.. */ - down(&kernel_sem); + do { + preempt_enable(); + while (spin_is_locked(&kernel_flag)) + cpu_relax(); + preempt_disable(); + } while (!_raw_spin_trylock(&kernel_flag)); + } +} - task->lock_depth = depth; +#else + +/* + * Non-preemption case - just get the spinlock + */ +static inline void __lock_kernel(void) +{ + _raw_spin_lock(&kernel_flag); } +#endif -void __lockfunc unlock_kernel(void) +static inline void __unlock_kernel(void) { - struct task_struct *task = current; + /* + * the BKL is not covered by lockdep, so we open-code the + * unlocking sequence (and thus avoid the dep-chain ops): + */ + _raw_spin_unlock(&kernel_flag); + preempt_enable(); +} - BUG_ON(task->lock_depth < 0); +/* + * Getting the big kernel lock. + * + * This cannot happen asynchronously, so we only need to + * worry about other CPU's. + */ +void __lockfunc lock_kernel(void) +{ + int depth = current->lock_depth+1; + if (likely(!depth)) + __lock_kernel(); + current->lock_depth = depth; +} - if (likely(--task->lock_depth < 0)) - up(&kernel_sem); +void __lockfunc unlock_kernel(void) +{ + BUG_ON(current->lock_depth < 0); + if (likely(--current->lock_depth < 0)) + __unlock_kernel(); } EXPORT_SYMBOL(lock_kernel); diff --git a/lib/lmb.c b/lib/lmb.c index 83287d3869a3d8e52129982f85af166c5b1246fc..867f7b5a8231b9c2cc4fc81e1f269689259857e1 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -19,31 +19,42 @@ struct lmb lmb; +static int lmb_debug; + +static int __init early_lmb(char *p) +{ + if (p && strstr(p, "debug")) + lmb_debug = 1; + return 0; +} +early_param("lmb", early_lmb); + void lmb_dump_all(void) { -#ifdef DEBUG unsigned long i; - pr_debug("lmb_dump_all:\n"); - pr_debug(" memory.cnt = 0x%lx\n", lmb.memory.cnt); - pr_debug(" memory.size = 0x%llx\n", + if (!lmb_debug) + return; + + pr_info("lmb_dump_all:\n"); + pr_info(" memory.cnt = 0x%lx\n", lmb.memory.cnt); + pr_info(" memory.size = 0x%llx\n", (unsigned long long)lmb.memory.size); for (i=0; i < lmb.memory.cnt ;i++) { - pr_debug(" memory.region[0x%x].base = 0x%llx\n", + pr_info(" memory.region[0x%lx].base = 0x%llx\n", i, (unsigned long long)lmb.memory.region[i].base); - pr_debug(" .size = 0x%llx\n", + pr_info(" .size = 0x%llx\n", (unsigned long long)lmb.memory.region[i].size); } - pr_debug(" reserved.cnt = 0x%lx\n", lmb.reserved.cnt); - pr_debug(" reserved.size = 0x%lx\n", lmb.reserved.size); + pr_info(" reserved.cnt = 0x%lx\n", lmb.reserved.cnt); + pr_info(" reserved.size = 0x%lx\n", lmb.reserved.size); for (i=0; i < lmb.reserved.cnt ;i++) { - pr_debug(" reserved.region[0x%x].base = 0x%llx\n", + pr_info(" reserved.region[0x%lx].base = 0x%llx\n", i, (unsigned long long)lmb.reserved.region[i].base); - pr_debug(" .size = 0x%llx\n", + pr_info(" .size = 0x%llx\n", (unsigned long long)lmb.reserved.region[i].size); } -#endif /* DEBUG */ } static unsigned long lmb_addrs_overlap(u64 base1, u64 size1, u64 base2, @@ -286,8 +297,7 @@ static u64 __init lmb_alloc_nid_unreserved(u64 start, u64 end, j = lmb_overlaps_region(&lmb.reserved, base, size); if (j < 0) { /* this area isn't reserved, take it */ - if (lmb_add_region(&lmb.reserved, base, - lmb_align_up(size, align)) < 0) + if (lmb_add_region(&lmb.reserved, base, size) < 0) base = ~(u64)0; return base; } @@ -333,6 +343,10 @@ u64 __init lmb_alloc_nid(u64 size, u64 align, int nid, struct lmb_region *mem = &lmb.memory; int i; + BUG_ON(0 == size); + + size = lmb_align_up(size, align); + for (i = 0; i < mem->cnt; i++) { u64 ret = lmb_alloc_nid_region(&mem->region[i], nid_range, @@ -370,6 +384,8 @@ u64 __init __lmb_alloc_base(u64 size, u64 align, u64 max_addr) BUG_ON(0 == size); + size = lmb_align_up(size, align); + /* On some platforms, make sure we allocate lowmem */ /* Note that LMB_REAL_LIMIT may be LMB_ALLOC_ANYWHERE */ if (max_addr == LMB_ALLOC_ANYWHERE) @@ -393,8 +409,7 @@ u64 __init __lmb_alloc_base(u64 size, u64 align, u64 max_addr) j = lmb_overlaps_region(&lmb.reserved, base, size); if (j < 0) { /* this area isn't reserved, take it */ - if (lmb_add_region(&lmb.reserved, base, - lmb_align_up(size, align)) < 0) + if (lmb_add_region(&lmb.reserved, base, size) < 0) return 0; return base; } diff --git a/lib/parser.c b/lib/parser.c index 703c8c13b346c39c460d0dbe02e6f32af019d71b..4f0cbc03e0e86844840c28b08a279394215b4e31 100644 --- a/lib/parser.c +++ b/lib/parser.c @@ -182,18 +182,25 @@ int match_hex(substring_t *s, int *result) } /** - * match_strcpy: - copies the characters from a substring_t to a string - * @to: string to copy characters to. - * @s: &substring_t to copy + * match_strlcpy: - Copy the characters from a substring_t to a sized buffer + * @dest: where to copy to + * @src: &substring_t to copy + * @size: size of destination buffer * - * Description: Copies the set of characters represented by the given - * &substring_t @s to the c-style string @to. Caller guarantees that @to is - * large enough to hold the characters of @s. + * Description: Copy the characters in &substring_t @src to the + * c-style string @dest. Copy no more than @size - 1 characters, plus + * the terminating NUL. Return length of @src. */ -void match_strcpy(char *to, const substring_t *s) +size_t match_strlcpy(char *dest, const substring_t *src, size_t size) { - memcpy(to, s->from, s->to - s->from); - to[s->to - s->from] = '\0'; + size_t ret = src->to - src->from; + + if (size) { + size_t len = ret >= size ? size - 1 : ret; + memcpy(dest, src->from, len); + dest[len] = '\0'; + } + return ret; } /** @@ -206,9 +213,10 @@ void match_strcpy(char *to, const substring_t *s) */ char *match_strdup(const substring_t *s) { - char *p = kmalloc(s->to - s->from + 1, GFP_KERNEL); + size_t sz = s->to - s->from + 1; + char *p = kmalloc(sz, GFP_KERNEL); if (p) - match_strcpy(p, s); + match_strlcpy(p, s, sz); return p; } @@ -216,5 +224,5 @@ EXPORT_SYMBOL(match_token); EXPORT_SYMBOL(match_int); EXPORT_SYMBOL(match_octal); EXPORT_SYMBOL(match_hex); -EXPORT_SYMBOL(match_strcpy); +EXPORT_SYMBOL(match_strlcpy); EXPORT_SYMBOL(match_strdup); diff --git a/mm/filemap.c b/mm/filemap.c index 239d36163bbe53fbb2115595e82ed9aef3180b02..1e6a7d34874fd31f3e9549c7540a4ce28c2402c6 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -1461,6 +1461,11 @@ page_not_uptodate: */ ClearPageError(page); error = mapping->a_ops->readpage(file, page); + if (!error) { + wait_on_page_locked(page); + if (!PageUptodate(page)) + error = -EIO; + } page_cache_release(page); if (!error || error == AOP_TRUNCATED_PAGE) @@ -1655,7 +1660,7 @@ int should_remove_suid(struct dentry *dentry) } EXPORT_SYMBOL(should_remove_suid); -int __remove_suid(struct dentry *dentry, int kill) +static int __remove_suid(struct dentry *dentry, int kill) { struct iattr newattrs; diff --git a/mm/memory.c b/mm/memory.c index bbab1e37055e22df235af61ddd201fe4b9832283..fb5608a120edc77cffac3050ce7e5ebbcff94b8f 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -311,6 +311,21 @@ int __pte_alloc(struct mm_struct *mm, pmd_t *pmd, unsigned long address) if (!new) return -ENOMEM; + /* + * Ensure all pte setup (eg. pte page lock and page clearing) are + * visible before the pte is made visible to other CPUs by being + * put into page tables. + * + * The other side of the story is the pointer chasing in the page + * table walking code (when walking the page table without locking; + * ie. most of the time). Fortunately, these data accesses consist + * of a chain of data-dependent loads, meaning most CPUs (alpha + * being the notable exception) will already guarantee loads are + * seen in-order. See the alpha page table accessors for the + * smp_read_barrier_depends() barriers in page table walking code. + */ + smp_wmb(); /* Could be smp_wmb__xxx(before|after)_spin_lock */ + spin_lock(&mm->page_table_lock); if (!pmd_present(*pmd)) { /* Has another populated it ? */ mm->nr_ptes++; @@ -329,6 +344,8 @@ int __pte_alloc_kernel(pmd_t *pmd, unsigned long address) if (!new) return -ENOMEM; + smp_wmb(); /* See comment in __pte_alloc */ + spin_lock(&init_mm.page_table_lock); if (!pmd_present(*pmd)) { /* Has another populated it ? */ pmd_populate_kernel(&init_mm, pmd, new); @@ -969,7 +986,7 @@ struct page *follow_page(struct vm_area_struct *vma, unsigned long address, goto no_page_table; pmd = pmd_offset(pud, address); - if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd))) + if (pmd_none(*pmd)) goto no_page_table; if (pmd_huge(*pmd)) { @@ -978,6 +995,9 @@ struct page *follow_page(struct vm_area_struct *vma, unsigned long address, goto out; } + if (unlikely(pmd_bad(*pmd))) + goto no_page_table; + ptep = pte_offset_map_lock(mm, pmd, address, &ptl); if (!ptep) goto out; @@ -2616,6 +2636,8 @@ int __pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address) if (!new) return -ENOMEM; + smp_wmb(); /* See comment in __pte_alloc */ + spin_lock(&mm->page_table_lock); if (pgd_present(*pgd)) /* Another has populated it */ pud_free(mm, new); @@ -2637,6 +2659,8 @@ int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address) if (!new) return -ENOMEM; + smp_wmb(); /* See comment in __pte_alloc */ + spin_lock(&mm->page_table_lock); #ifndef __ARCH_HAS_4LEVEL_HACK if (pud_present(*pud)) /* Another has populated it */ diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index b17dca7249f8a41e0806e4465291f1dd2eba4913..833f854eabe50ad226696667db7e49d332840bb6 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -159,21 +159,58 @@ void register_page_bootmem_info_node(struct pglist_data *pgdat) } #endif /* !CONFIG_SPARSEMEM_VMEMMAP */ +static void grow_zone_span(struct zone *zone, unsigned long start_pfn, + unsigned long end_pfn) +{ + unsigned long old_zone_end_pfn; + + zone_span_writelock(zone); + + old_zone_end_pfn = zone->zone_start_pfn + zone->spanned_pages; + if (start_pfn < zone->zone_start_pfn) + zone->zone_start_pfn = start_pfn; + + zone->spanned_pages = max(old_zone_end_pfn, end_pfn) - + zone->zone_start_pfn; + + zone_span_writeunlock(zone); +} + +static void grow_pgdat_span(struct pglist_data *pgdat, unsigned long start_pfn, + unsigned long end_pfn) +{ + unsigned long old_pgdat_end_pfn = + pgdat->node_start_pfn + pgdat->node_spanned_pages; + + if (start_pfn < pgdat->node_start_pfn) + pgdat->node_start_pfn = start_pfn; + + pgdat->node_spanned_pages = max(old_pgdat_end_pfn, end_pfn) - + pgdat->node_start_pfn; +} + static int __add_zone(struct zone *zone, unsigned long phys_start_pfn) { struct pglist_data *pgdat = zone->zone_pgdat; int nr_pages = PAGES_PER_SECTION; int nid = pgdat->node_id; int zone_type; + unsigned long flags; zone_type = zone - pgdat->node_zones; if (!zone->wait_table) { - int ret = 0; + int ret; + ret = init_currently_empty_zone(zone, phys_start_pfn, nr_pages, MEMMAP_HOTPLUG); - if (ret < 0) + if (ret) return ret; } + pgdat_resize_lock(zone->zone_pgdat, &flags); + grow_zone_span(zone, phys_start_pfn, phys_start_pfn + nr_pages); + grow_pgdat_span(zone->zone_pgdat, phys_start_pfn, + phys_start_pfn + nr_pages); + pgdat_resize_unlock(zone->zone_pgdat, &flags); memmap_init_zone(nr_pages, nid, zone_type, phys_start_pfn, MEMMAP_HOTPLUG); return 0; @@ -299,36 +336,6 @@ int __remove_pages(struct zone *zone, unsigned long phys_start_pfn, } EXPORT_SYMBOL_GPL(__remove_pages); -static void grow_zone_span(struct zone *zone, - unsigned long start_pfn, unsigned long end_pfn) -{ - unsigned long old_zone_end_pfn; - - zone_span_writelock(zone); - - old_zone_end_pfn = zone->zone_start_pfn + zone->spanned_pages; - if (start_pfn < zone->zone_start_pfn) - zone->zone_start_pfn = start_pfn; - - zone->spanned_pages = max(old_zone_end_pfn, end_pfn) - - zone->zone_start_pfn; - - zone_span_writeunlock(zone); -} - -static void grow_pgdat_span(struct pglist_data *pgdat, - unsigned long start_pfn, unsigned long end_pfn) -{ - unsigned long old_pgdat_end_pfn = - pgdat->node_start_pfn + pgdat->node_spanned_pages; - - if (start_pfn < pgdat->node_start_pfn) - pgdat->node_start_pfn = start_pfn; - - pgdat->node_spanned_pages = max(old_pgdat_end_pfn, end_pfn) - - pgdat->node_start_pfn; -} - void online_page(struct page *page) { totalram_pages++; @@ -367,7 +374,6 @@ static int online_pages_range(unsigned long start_pfn, unsigned long nr_pages, int online_pages(unsigned long pfn, unsigned long nr_pages) { - unsigned long flags; unsigned long onlined_pages = 0; struct zone *zone; int need_zonelists_rebuild = 0; @@ -395,11 +401,6 @@ int online_pages(unsigned long pfn, unsigned long nr_pages) * memory_block->state_mutex. */ zone = page_zone(pfn_to_page(pfn)); - pgdat_resize_lock(zone->zone_pgdat, &flags); - grow_zone_span(zone, pfn, pfn + nr_pages); - grow_pgdat_span(zone->zone_pgdat, pfn, pfn + nr_pages); - pgdat_resize_unlock(zone->zone_pgdat, &flags); - /* * If this zone is not populated, then it is not in zonelist. * This means the page allocator ignores this zone. @@ -408,8 +409,15 @@ int online_pages(unsigned long pfn, unsigned long nr_pages) if (!populated_zone(zone)) need_zonelists_rebuild = 1; - walk_memory_resource(pfn, nr_pages, &onlined_pages, + ret = walk_memory_resource(pfn, nr_pages, &onlined_pages, online_pages_range); + if (ret) { + printk(KERN_DEBUG "online_pages %lx at %lx failed\n", + nr_pages, pfn); + memory_notify(MEM_CANCEL_ONLINE, &arg); + return ret; + } + zone->present_pages += onlined_pages; zone->zone_pgdat->node_present_pages += onlined_pages; diff --git a/mm/mprotect.c b/mm/mprotect.c index 4de546899dc140d139f218fc53ff0c358c6c5a42..a5bf31c273757848ae7614bd9fc3c8595c493705 100644 --- a/mm/mprotect.c +++ b/mm/mprotect.c @@ -26,6 +26,13 @@ #include #include +#ifndef pgprot_modify +static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot) +{ + return newprot; +} +#endif + static void change_pte_range(struct mm_struct *mm, pmd_t *pmd, unsigned long addr, unsigned long end, pgprot_t newprot, int dirty_accountable) @@ -192,7 +199,9 @@ success: * held in write mode. */ vma->vm_flags = newflags; - vma->vm_page_prot = vm_get_page_prot(newflags); + vma->vm_page_prot = pgprot_modify(vma->vm_page_prot, + vm_get_page_prot(newflags)); + if (vma_wants_writenotify(vma)) { vma->vm_page_prot = vm_get_page_prot(newflags & ~VM_SHARED); dirty_accountable = 1; diff --git a/mm/page_alloc.c b/mm/page_alloc.c index bdd5c432c426fdf6714ff90e1eebdfccfdccee8c..63835579323a7ca70722154f5b3e6560872da409 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -2862,8 +2862,6 @@ __meminit int init_currently_empty_zone(struct zone *zone, zone->zone_start_pfn = zone_start_pfn; - memmap_init(size, pgdat->node_id, zone_idx(zone), zone_start_pfn); - zone_init_free_lists(zone); return 0; @@ -3433,6 +3431,7 @@ static void __paginginit free_area_init_core(struct pglist_data *pgdat, ret = init_currently_empty_zone(zone, zone_start_pfn, size, MEMMAP_EARLY); BUG_ON(ret); + memmap_init(size, nid, j, zone_start_pfn); zone_start_pfn += size; } } diff --git a/mm/pdflush.c b/mm/pdflush.c index 1c96cfc9e0400cf0e6b3c4cf41cdccc03bff17c0..9d834aa4b9795264d87eef283c2492a99d67597b 100644 --- a/mm/pdflush.c +++ b/mm/pdflush.c @@ -207,7 +207,6 @@ int pdflush_operation(void (*fn)(unsigned long), unsigned long arg0) spin_lock_irqsave(&pdflush_lock, flags); if (list_empty(&pdflush_list)) { - spin_unlock_irqrestore(&pdflush_lock, flags); ret = -1; } else { struct pdflush_work *pdf; @@ -219,8 +218,9 @@ int pdflush_operation(void (*fn)(unsigned long), unsigned long arg0) pdf->fn = fn; pdf->arg0 = arg0; wake_up_process(pdf->who); - spin_unlock_irqrestore(&pdflush_lock, flags); } + spin_unlock_irqrestore(&pdflush_lock, flags); + return ret; } diff --git a/mm/slub.c b/mm/slub.c index d379b782fc8325cec775bc1daca939bbe06d6d75..a505a828ef411e08f149a413fb37f32da7c47e21 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -3762,7 +3762,7 @@ static int any_slab_objects(struct kmem_cache *s) if (!n) continue; - if (atomic_read(&n->total_objects)) + if (atomic_long_read(&n->total_objects)) return 1; } return 0; diff --git a/mm/vmstat.c b/mm/vmstat.c index 1a32130b958c418ec8a018aa676c73bb3d7cde32..db9eabb2c5b3a992a04ac2396bf791b72bbdcf94 100644 --- a/mm/vmstat.c +++ b/mm/vmstat.c @@ -41,7 +41,9 @@ static void sum_vm_events(unsigned long *ret, cpumask_t *cpumask) */ void all_vm_events(unsigned long *ret) { + get_online_cpus(); sum_vm_events(ret, &cpu_online_map); + put_online_cpus(); } EXPORT_SYMBOL_GPL(all_vm_events); diff --git a/net/9p/Kconfig b/net/9p/Kconfig index bafc50c9e6ff6891e4fb2b4fbab7f61ab9dc92ca..ff34c5acc1309ea7cdb2c8e60e73740cd23264a6 100644 --- a/net/9p/Kconfig +++ b/net/9p/Kconfig @@ -13,16 +13,6 @@ menuconfig NET_9P If unsure, say N. -config NET_9P_FD - depends on NET_9P - default y if NET_9P - tristate "9P File Descriptor Transports (Experimental)" - help - This builds support for file descriptor transports for 9p - which includes support for TCP/IP, named pipes, or passed - file descriptors. TCP/IP is the default transport for 9p, - so if you are going to use 9p, you'll likely want this. - config NET_9P_VIRTIO depends on NET_9P && EXPERIMENTAL && VIRTIO tristate "9P Virtio Transport (Experimental)" diff --git a/net/9p/Makefile b/net/9p/Makefile index 8a105110189830f5b527047ac4e299462f038710..519219480db1a7080e646d612000f3f351cdcc2a 100644 --- a/net/9p/Makefile +++ b/net/9p/Makefile @@ -1,5 +1,4 @@ obj-$(CONFIG_NET_9P) := 9pnet.o -obj-$(CONFIG_NET_9P_FD) += 9pnet_fd.o obj-$(CONFIG_NET_9P_VIRTIO) += 9pnet_virtio.o 9pnet-objs := \ @@ -9,8 +8,6 @@ obj-$(CONFIG_NET_9P_VIRTIO) += 9pnet_virtio.o error.o \ fcprint.o \ util.o \ - -9pnet_fd-objs := \ trans_fd.o \ 9pnet_virtio-objs := \ diff --git a/net/9p/client.c b/net/9p/client.c index 84e087e2414606ce56a3903eaae048ec1a2066ef..2ffe40cf2f01799634c478443284b80f62c9289c 100644 --- a/net/9p/client.c +++ b/net/9p/client.c @@ -64,21 +64,30 @@ static match_table_t tokens = { * @options: options string passed from mount * @v9ses: existing v9fs session information * + * Return 0 upon success, -ERRNO upon failure */ -static void parse_opts(char *options, struct p9_client *clnt) +static int parse_opts(char *opts, struct p9_client *clnt) { + char *options; char *p; substring_t args[MAX_OPT_ARGS]; int option; - int ret; + int ret = 0; clnt->trans_mod = v9fs_default_trans(); clnt->dotu = 1; clnt->msize = 8192; - if (!options) - return; + if (!opts) + return 0; + + options = kstrdup(opts, GFP_KERNEL); + if (!options) { + P9_DPRINTK(P9_DEBUG_ERROR, + "failed to allocate copy of option string\n"); + return -ENOMEM; + } while ((p = strsep(&options, ",")) != NULL) { int token; @@ -86,10 +95,11 @@ static void parse_opts(char *options, struct p9_client *clnt) continue; token = match_token(p, tokens, args); if (token < Opt_trans) { - ret = match_int(&args[0], &option); - if (ret < 0) { + int r = match_int(&args[0], &option); + if (r < 0) { P9_DPRINTK(P9_DEBUG_ERROR, "integer field, but no integer?\n"); + ret = r; continue; } } @@ -107,6 +117,8 @@ static void parse_opts(char *options, struct p9_client *clnt) continue; } } + kfree(options); + return ret; } @@ -138,16 +150,20 @@ struct p9_client *p9_client_create(const char *dev_name, char *options) if (!clnt) return ERR_PTR(-ENOMEM); + clnt->trans = NULL; spin_lock_init(&clnt->lock); INIT_LIST_HEAD(&clnt->fidlist); clnt->fidpool = p9_idpool_create(); - if (!clnt->fidpool) { + if (IS_ERR(clnt->fidpool)) { err = PTR_ERR(clnt->fidpool); clnt->fidpool = NULL; goto error; } - parse_opts(options, clnt); + err = parse_opts(options, clnt); + if (err < 0) + goto error; + if (clnt->trans_mod == NULL) { err = -EPROTONOSUPPORT; P9_DPRINTK(P9_DEBUG_ERROR, diff --git a/net/9p/conv.c b/net/9p/conv.c index 3fe35d532c87a0c2f17afb2baf961077a954f96e..44547201f5bcce723787cbeeee1c5a541a51ba3e 100644 --- a/net/9p/conv.c +++ b/net/9p/conv.c @@ -197,7 +197,7 @@ static void buf_get_qid(struct cbuf *bufp, struct p9_qid *qid) /** * p9_size_wstat - calculate the size of a variable length stat struct - * @stat: metadata (stat) structure + * @wstat: metadata (stat) structure * @dotu: non-zero if 9P2000.u * */ @@ -511,6 +511,12 @@ p9_create_common(struct cbuf *bufp, u32 size, u8 id) return fc; } +/** + * p9_set_tag - set the tag field of an &p9_fcall structure + * @fc: fcall structure to set tag within + * @tag: tag id to set + */ + void p9_set_tag(struct p9_fcall *fc, u16 tag) { fc->tag = tag; @@ -518,6 +524,12 @@ void p9_set_tag(struct p9_fcall *fc, u16 tag) } EXPORT_SYMBOL(p9_set_tag); +/** + * p9_create_tversion - allocates and creates a T_VERSION request + * @msize: requested maximum data size + * @version: version string to negotiate + * + */ struct p9_fcall *p9_create_tversion(u32 msize, char *version) { int size; @@ -542,6 +554,16 @@ error: } EXPORT_SYMBOL(p9_create_tversion); +/** + * p9_create_tauth - allocates and creates a T_AUTH request + * @afid: handle to use for authentication protocol + * @uname: user name attempting to authenticate + * @aname: mount specifier for remote server + * @n_uname: numeric id for user attempting to authneticate + * @dotu: 9P2000.u extension flag + * + */ + struct p9_fcall *p9_create_tauth(u32 afid, char *uname, char *aname, u32 n_uname, int dotu) { @@ -580,6 +602,18 @@ error: } EXPORT_SYMBOL(p9_create_tauth); +/** + * p9_create_tattach - allocates and creates a T_ATTACH request + * @fid: handle to use for the new mount point + * @afid: handle to use for authentication protocol + * @uname: user name attempting to attach + * @aname: mount specifier for remote server + * @n_uname: numeric id for user attempting to attach + * @n_uname: numeric id for user attempting to attach + * @dotu: 9P2000.u extension flag + * + */ + struct p9_fcall * p9_create_tattach(u32 fid, u32 afid, char *uname, char *aname, u32 n_uname, int dotu) @@ -616,6 +650,12 @@ error: } EXPORT_SYMBOL(p9_create_tattach); +/** + * p9_create_tflush - allocates and creates a T_FLUSH request + * @oldtag: tag id for the transaction we are attempting to cancel + * + */ + struct p9_fcall *p9_create_tflush(u16 oldtag) { int size; @@ -639,6 +679,15 @@ error: } EXPORT_SYMBOL(p9_create_tflush); +/** + * p9_create_twalk - allocates and creates a T_FLUSH request + * @fid: handle we are traversing from + * @newfid: a new handle for this transaction + * @nwname: number of path elements to traverse + * @wnames: array of path elements + * + */ + struct p9_fcall *p9_create_twalk(u32 fid, u32 newfid, u16 nwname, char **wnames) { @@ -677,6 +726,13 @@ error: } EXPORT_SYMBOL(p9_create_twalk); +/** + * p9_create_topen - allocates and creates a T_OPEN request + * @fid: handle we are trying to open + * @mode: what mode we are trying to open the file in + * + */ + struct p9_fcall *p9_create_topen(u32 fid, u8 mode) { int size; @@ -701,6 +757,19 @@ error: } EXPORT_SYMBOL(p9_create_topen); +/** + * p9_create_tcreate - allocates and creates a T_CREATE request + * @fid: handle of directory we are trying to create in + * @name: name of the file we are trying to create + * @perm: permissions for the file we are trying to create + * @mode: what mode we are trying to open the file in + * @extension: 9p2000.u extension string (for special files) + * @dotu: 9p2000.u enabled flag + * + * Note: Plan 9 create semantics include opening the resulting file + * which is why mode is included. + */ + struct p9_fcall *p9_create_tcreate(u32 fid, char *name, u32 perm, u8 mode, char *extension, int dotu) { @@ -736,6 +805,13 @@ error: } EXPORT_SYMBOL(p9_create_tcreate); +/** + * p9_create_tread - allocates and creates a T_READ request + * @fid: handle of the file we are trying to read + * @offset: offset to start reading from + * @count: how many bytes to read + */ + struct p9_fcall *p9_create_tread(u32 fid, u64 offset, u32 count) { int size; @@ -761,6 +837,17 @@ error: } EXPORT_SYMBOL(p9_create_tread); +/** + * p9_create_twrite - allocates and creates a T_WRITE request from the kernel + * @fid: handle of the file we are trying to write + * @offset: offset to start writing at + * @count: how many bytes to write + * @data: data to write + * + * This function will create a requst with data buffers from the kernel + * such as the page cache. + */ + struct p9_fcall *p9_create_twrite(u32 fid, u64 offset, u32 count, const char *data) { @@ -794,6 +881,16 @@ error: } EXPORT_SYMBOL(p9_create_twrite); +/** + * p9_create_twrite_u - allocates and creates a T_WRITE request from userspace + * @fid: handle of the file we are trying to write + * @offset: offset to start writing at + * @count: how many bytes to write + * @data: data to write + * + * This function will create a request with data buffers from userspace + */ + struct p9_fcall *p9_create_twrite_u(u32 fid, u64 offset, u32 count, const char __user *data) { @@ -827,6 +924,14 @@ error: } EXPORT_SYMBOL(p9_create_twrite_u); +/** + * p9_create_tclunk - allocate a request to forget about a file handle + * @fid: handle of the file we closing or forgetting about + * + * clunk is used both to close open files and to discard transient handles + * which may be created during meta-data operations and hierarchy traversal. + */ + struct p9_fcall *p9_create_tclunk(u32 fid) { int size; @@ -850,6 +955,12 @@ error: } EXPORT_SYMBOL(p9_create_tclunk); +/** + * p9_create_tremove - allocate and create a request to remove a file + * @fid: handle of the file or directory we are removing + * + */ + struct p9_fcall *p9_create_tremove(u32 fid) { int size; @@ -873,6 +984,12 @@ error: } EXPORT_SYMBOL(p9_create_tremove); +/** + * p9_create_tstat - allocate and populate a request for attributes + * @fid: handle of the file or directory we are trying to get the attributes of + * + */ + struct p9_fcall *p9_create_tstat(u32 fid) { int size; @@ -896,6 +1013,14 @@ error: } EXPORT_SYMBOL(p9_create_tstat); +/** + * p9_create_tstat - allocate and populate a request to change attributes + * @fid: handle of the file or directory we are trying to change + * @wstat: &p9_stat structure with attributes we wish to set + * @dotu: 9p2000.u enabled flag + * + */ + struct p9_fcall *p9_create_twstat(u32 fid, struct p9_wstat *wstat, int dotu) { @@ -922,3 +1047,4 @@ error: return fc; } EXPORT_SYMBOL(p9_create_twstat); + diff --git a/net/9p/error.c b/net/9p/error.c index 64104b9cb422421ee518cfb8371d9e5c8f658483..fdebe4314062c01e02636d5201a2068ee57a640c 100644 --- a/net/9p/error.c +++ b/net/9p/error.c @@ -33,6 +33,13 @@ #include #include +/** + * struct errormap - map string errors from Plan 9 to Linux numeric ids + * @name: string sent over 9P + * @val: numeric id most closely representing @name + * @namelen: length of string + * @list: hash-table list for string lookup + */ struct errormap { char *name; int val; @@ -177,8 +184,7 @@ static struct errormap errmap[] = { }; /** - * p9_error_init - preload - * @errstr: error string + * p9_error_init - preload mappings into hash list * */ @@ -206,6 +212,7 @@ EXPORT_SYMBOL(p9_error_init); /** * errstr2errno - convert error string to error number * @errstr: error string + * @len: length of error string * */ @@ -230,8 +237,8 @@ int p9_errstr2errno(char *errstr, int len) if (errno == 0) { /* TODO: if error isn't found, add it dynamically */ errstr[len] = 0; - printk(KERN_ERR "%s: errstr :%s: not found\n", __func__, - errstr); + printk(KERN_ERR "%s: server reported unknown error %s\n", + __func__, errstr); errno = 1; } diff --git a/net/9p/fcprint.c b/net/9p/fcprint.c index 40244fbd9b0d15d2f66eb70cc4ff8f5d0a1d9b59..53dd8e28dd8a026a6dcfed308eeaf66628febfba 100644 --- a/net/9p/fcprint.c +++ b/net/9p/fcprint.c @@ -142,6 +142,14 @@ p9_printdata(char *buf, int buflen, u8 *data, int datalen) return p9_dumpdata(buf, buflen, data, datalen < 16?datalen:16); } +/** + * p9_printfcall - decode and print a protocol structure into a buffer + * @buf: buffer to deposit decoded structure into + * @buflen: available space in buffer + * @fc: protocol rpc structure of type &p9_fcall + * @extended: whether or not session is operating with extended protocol + */ + int p9_printfcall(char *buf, int buflen, struct p9_fcall *fc, int extended) { diff --git a/net/9p/mod.c b/net/9p/mod.c index c285aab2af04ba78683e98f45175815f1aadbbab..bdee1fb7cc62909a565717e7fd27a6c0903a1895 100644 --- a/net/9p/mod.c +++ b/net/9p/mod.c @@ -39,9 +39,6 @@ module_param_named(debug, p9_debug_level, uint, 0); MODULE_PARM_DESC(debug, "9P debugging level"); #endif -extern int p9_mux_global_init(void); -extern void p9_mux_global_exit(void); - /* * Dynamic Transport Registration Routines * @@ -52,7 +49,7 @@ static struct p9_trans_module *v9fs_default_transport; /** * v9fs_register_trans - register a new transport with 9p - * @m - structure describing the transport module and entry points + * @m: structure describing the transport module and entry points * */ void v9fs_register_trans(struct p9_trans_module *m) @@ -65,7 +62,7 @@ EXPORT_SYMBOL(v9fs_register_trans); /** * v9fs_match_trans - match transport versus registered transports - * @arg: string identifying transport + * @name: string identifying transport * */ struct p9_trans_module *v9fs_match_trans(const substring_t *name) @@ -110,6 +107,7 @@ static int __init init_p9(void) p9_error_init(); printk(KERN_INFO "Installing 9P2000 support\n"); + p9_trans_fd_init(); return ret; } diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index f624dff76852f1881d266320f8ea1362c9a8eb1d..4507f744f44e527cc140b6b5601e556c10bfd361 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c @@ -47,12 +47,29 @@ #define SCHED_TIMEOUT 10 #define MAXPOLLWADDR 2 +/** + * struct p9_fd_opts - per-transport options + * @rfd: file descriptor for reading (trans=fd) + * @wfd: file descriptor for writing (trans=fd) + * @port: port to connect to (trans=tcp) + * + */ + struct p9_fd_opts { int rfd; int wfd; u16 port; }; + +/** + * struct p9_trans_fd - transport state + * @rd: reference to file to read from + * @wr: reference of file to write to + * @conn: connection state reference + * + */ + struct p9_trans_fd { struct file *rd; struct file *wr; @@ -90,10 +107,24 @@ enum { }; struct p9_req; - typedef void (*p9_conn_req_callback)(struct p9_req *req, void *a); + +/** + * struct p9_req - fd mux encoding of an rpc transaction + * @lock: protects req_list + * @tag: numeric tag for rpc transaction + * @tcall: request &p9_fcall structure + * @rcall: response &p9_fcall structure + * @err: error state + * @cb: callback for when response is received + * @cba: argument to pass to callback + * @flush: flag to indicate RPC has been flushed + * @req_list: list link for higher level objects to chain requests + * + */ + struct p9_req { - spinlock_t lock; /* protect request structure */ + spinlock_t lock; int tag; struct p9_fcall *tcall; struct p9_fcall *rcall; @@ -104,7 +135,39 @@ struct p9_req { struct list_head req_list; }; -struct p9_mux_poll_task; +struct p9_mux_poll_task { + struct task_struct *task; + struct list_head mux_list; + int muxnum; +}; + +/** + * struct p9_conn - fd mux connection state information + * @lock: protects mux_list (?) + * @mux_list: list link for mux to manage multiple connections (?) + * @poll_task: task polling on this connection + * @msize: maximum size for connection (dup) + * @extended: 9p2000.u flag (dup) + * @trans: reference to transport instance for this connection + * @tagpool: id accounting for transactions + * @err: error state + * @equeue: event wait_q (?) + * @req_list: accounting for requests which have been sent + * @unsent_req_list: accounting for requests that haven't been sent + * @rcall: current response &p9_fcall structure + * @rpos: read position in current frame + * @rbuf: current read buffer + * @wpos: write position for current frame + * @wsize: amount of data to write for current frame + * @wbuf: current write buffer + * @poll_wait: array of wait_q's for various worker threads + * @poll_waddr: ???? + * @pt: poll state + * @rq: current read work + * @wq: current write work + * @wsched: ???? + * + */ struct p9_conn { spinlock_t lock; /* protect lock structure */ @@ -132,11 +195,16 @@ struct p9_conn { unsigned long wsched; }; -struct p9_mux_poll_task { - struct task_struct *task; - struct list_head mux_list; - int muxnum; -}; +/** + * struct p9_mux_rpc - fd mux rpc accounting structure + * @m: connection this request was issued on + * @err: error state + * @tcall: request &p9_fcall + * @rcall: response &p9_fcall + * @wqueue: wait queue that client is blocked on for this rpc + * + * Bug: isn't this information duplicated elsewhere like &p9_req + */ struct p9_mux_rpc { struct p9_conn *m; @@ -207,10 +275,12 @@ static void p9_mux_put_tag(struct p9_conn *m, u16 tag) /** * p9_mux_calc_poll_procs - calculates the number of polling procs - * based on the number of mounted v9fs filesystems. + * @muxnum: number of mounts * + * Calculation is based on the number of mounted v9fs filesystems. * The current implementation returns sqrt of the number of mounts. */ + static int p9_mux_calc_poll_procs(int muxnum) { int n; @@ -331,12 +401,11 @@ static void p9_mux_poll_stop(struct p9_conn *m) /** * p9_conn_create - allocate and initialize the per-session mux data - * Creates the polling task if this is the first session. + * @trans: transport structure * - * @trans - transport structure - * @msize - maximum message size - * @extended - extended flag + * Note: Creates the polling task if this is the first session. */ + static struct p9_conn *p9_conn_create(struct p9_trans *trans) { int i, n; @@ -406,7 +475,10 @@ static struct p9_conn *p9_conn_create(struct p9_trans *trans) /** * p9_mux_destroy - cancels all pending requests and frees mux resources + * @m: mux to destroy + * */ + static void p9_conn_destroy(struct p9_conn *m) { P9_DPRINTK(P9_DEBUG_MUX, "mux %p prev %p next %p\n", m, @@ -429,9 +501,14 @@ static void p9_conn_destroy(struct p9_conn *m) } /** - * p9_pollwait - called by files poll operation to add v9fs-poll task - * to files wait queue + * p9_pollwait - add poll task to the wait queue + * @filp: file pointer being polled + * @wait_address: wait_q to block on + * @p: poll state + * + * called by files poll operation to add v9fs-poll task to files wait queue */ + static void p9_pollwait(struct file *filp, wait_queue_head_t *wait_address, poll_table *p) { @@ -462,7 +539,10 @@ p9_pollwait(struct file *filp, wait_queue_head_t *wait_address, poll_table *p) /** * p9_poll_mux - polls a mux and schedules read or write works if necessary + * @m: connection to poll + * */ + static void p9_poll_mux(struct p9_conn *m) { int n; @@ -499,9 +579,14 @@ static void p9_poll_mux(struct p9_conn *m) } /** - * p9_poll_proc - polls all v9fs transports for new events and queues - * the appropriate work to the work queue + * p9_poll_proc - poll worker thread + * @a: thread state and arguments + * + * polls all v9fs transports for new events and queues the appropriate + * work to the work queue + * */ + static int p9_poll_proc(void *a) { struct p9_conn *m, *mtmp; @@ -527,7 +612,10 @@ static int p9_poll_proc(void *a) /** * p9_write_work - called when a transport can send some data + * @work: container for work to be done + * */ + static void p9_write_work(struct work_struct *work) { int n, err; @@ -638,7 +726,10 @@ static void process_request(struct p9_conn *m, struct p9_req *req) /** * p9_read_work - called when there is some data to be read from a transport + * @work: container of work to be done + * */ + static void p9_read_work(struct work_struct *work) { int n, err; @@ -793,7 +884,9 @@ error: * @tc: request to be sent * @cb: callback function to call when response is received * @cba: parameter to pass to the callback function + * */ + static struct p9_req *p9_send_request(struct p9_conn *m, struct p9_fcall *tc, p9_conn_req_callback cb, void *cba) @@ -961,10 +1054,12 @@ p9_conn_rpc_cb(struct p9_req *req, void *a) /** * p9_fd_rpc- sends 9P request and waits until a response is available. * The function can be interrupted. - * @m: mux data + * @t: transport data * @tc: request to be sent * @rc: pointer where a pointer to the response is stored + * */ + int p9_fd_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc) { @@ -1041,8 +1136,10 @@ p9_fd_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc) * @m: mux data * @tc: request to be sent * @cb: callback function to be called when response arrives - * @cba: value to pass to the callback function + * @a: value to pass to the callback function + * */ + int p9_conn_rpcnb(struct p9_conn *m, struct p9_fcall *tc, p9_conn_req_callback cb, void *a) { @@ -1065,7 +1162,9 @@ int p9_conn_rpcnb(struct p9_conn *m, struct p9_fcall *tc, * p9_conn_cancel - cancel all pending requests with error * @m: mux data * @err: error code + * */ + void p9_conn_cancel(struct p9_conn *m, int err) { struct p9_req *req, *rtmp; @@ -1097,35 +1196,46 @@ void p9_conn_cancel(struct p9_conn *m, int err) } /** - * v9fs_parse_options - parse mount options into session structure + * parse_options - parse mount options into session structure * @options: options string passed from mount - * @v9ses: existing v9fs session information + * @opts: transport-specific structure to parse options into * + * Returns 0 upon success, -ERRNO upon failure */ -static void parse_opts(char *options, struct p9_fd_opts *opts) +static int parse_opts(char *params, struct p9_fd_opts *opts) { char *p; substring_t args[MAX_OPT_ARGS]; int option; + char *options; int ret; opts->port = P9_PORT; opts->rfd = ~0; opts->wfd = ~0; - if (!options) - return; + if (!params) + return 0; + + options = kstrdup(params, GFP_KERNEL); + if (!options) { + P9_DPRINTK(P9_DEBUG_ERROR, + "failed to allocate copy of option string\n"); + return -ENOMEM; + } while ((p = strsep(&options, ",")) != NULL) { int token; + int r; if (!*p) continue; token = match_token(p, tokens, args); - ret = match_int(&args[0], &option); - if (ret < 0) { + r = match_int(&args[0], &option); + if (r < 0) { P9_DPRINTK(P9_DEBUG_ERROR, "integer field, but no integer?\n"); + ret = r; continue; } switch (token) { @@ -1142,6 +1252,8 @@ static void parse_opts(char *options, struct p9_fd_opts *opts) continue; } } + kfree(options); + return 0; } static int p9_fd_open(struct p9_trans *trans, int rfd, int wfd) @@ -1193,11 +1305,12 @@ static int p9_socket_open(struct p9_trans *trans, struct socket *csocket) /** * p9_fd_read- read from a fd - * @v9ses: session information + * @trans: transport instance state * @v: buffer to receive data into * @len: size of receive buffer * */ + static int p9_fd_read(struct p9_trans *trans, void *v, int len) { int ret; @@ -1220,11 +1333,12 @@ static int p9_fd_read(struct p9_trans *trans, void *v, int len) /** * p9_fd_write - write to a socket - * @v9ses: session information + * @trans: transport instance state * @v: buffer to send data from * @len: size of send buffer * */ + static int p9_fd_write(struct p9_trans *trans, void *v, int len) { int ret; @@ -1296,6 +1410,7 @@ end: * @trans: private socket structure * */ + static void p9_fd_close(struct p9_trans *trans) { struct p9_trans_fd *ts; @@ -1318,6 +1433,23 @@ static void p9_fd_close(struct p9_trans *trans) kfree(ts); } +/* + * stolen from NFS - maybe should be made a generic function? + */ +static inline int valid_ipaddr4(const char *buf) +{ + int rc, count, in[4]; + + rc = sscanf(buf, "%d.%d.%d.%d", &in[0], &in[1], &in[2], &in[3]); + if (rc != 4) + return -EINVAL; + for (count = 0; count < 4; count++) { + if (in[count] > 255) + return -EINVAL; + } + return 0; +} + static struct p9_trans * p9_trans_create_tcp(const char *addr, char *args, int msize, unsigned char dotu) { @@ -1328,7 +1460,12 @@ p9_trans_create_tcp(const char *addr, char *args, int msize, unsigned char dotu) struct p9_fd_opts opts; struct p9_trans_fd *p; - parse_opts(args, &opts); + err = parse_opts(args, &opts); + if (err < 0) + return ERR_PTR(err); + + if (valid_ipaddr4(addr) < 0) + return ERR_PTR(-EINVAL); csocket = NULL; trans = kmalloc(sizeof(struct p9_trans), GFP_KERNEL); @@ -1508,7 +1645,7 @@ static struct p9_trans_module p9_fd_trans = { .create = p9_trans_create_fd, }; -static int __init p9_trans_fd_init(void) +int p9_trans_fd_init(void) { int ret = p9_mux_global_init(); if (ret) { @@ -1522,9 +1659,4 @@ static int __init p9_trans_fd_init(void) return 0; } - -module_init(p9_trans_fd_init); - -MODULE_AUTHOR("Latchesar Ionkov "); -MODULE_AUTHOR("Eric Van Hensbergen "); -MODULE_LICENSE("GPL"); +EXPORT_SYMBOL(p9_trans_fd_init); diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c index de7a9f532edc282d6ca0c8e8abc67fbef6633ab6..42adc052b149251a46e3ac8a1bf039c91f00417f 100644 --- a/net/9p/trans_virtio.c +++ b/net/9p/trans_virtio.c @@ -49,29 +49,75 @@ #define VIRTQUEUE_NUM 128 /* a single mutex to manage channel initialization and attachment */ -static DECLARE_MUTEX(virtio_9p_lock); +static DEFINE_MUTEX(virtio_9p_lock); /* global which tracks highest initialized channel */ static int chan_index; #define P9_INIT_MAXTAG 16 -#define REQ_STATUS_IDLE 0 -#define REQ_STATUS_SENT 1 -#define REQ_STATUS_RCVD 2 -#define REQ_STATUS_FLSH 3 + +/** + * enum p9_req_status_t - virtio request status + * @REQ_STATUS_IDLE: request slot unused + * @REQ_STATUS_SENT: request sent to server + * @REQ_STATUS_RCVD: response received from server + * @REQ_STATUS_FLSH: request has been flushed + * + * The @REQ_STATUS_IDLE state is used to mark a request slot as unused + * but use is actually tracked by the idpool structure which handles tag + * id allocation. + * + */ + +enum p9_req_status_t { + REQ_STATUS_IDLE, + REQ_STATUS_SENT, + REQ_STATUS_RCVD, + REQ_STATUS_FLSH, +}; + +/** + * struct p9_req_t - virtio request slots + * @status: status of this request slot + * @wq: wait_queue for the client to block on for this request + * + * The virtio transport uses an array to track outstanding requests + * instead of a list. While this may incurr overhead during initial + * allocation or expansion, it makes request lookup much easier as the + * tag id is a index into an array. (We use tag+1 so that we can accomodate + * the -1 tag for the T_VERSION request). + * This also has the nice effect of only having to allocate wait_queues + * once, instead of constantly allocating and freeing them. Its possible + * other resources could benefit from this scheme as well. + * + */ struct p9_req_t { int status; wait_queue_head_t *wq; }; -/* We keep all per-channel information in a structure. +/** + * struct virtio_chan - per-instance transport information + * @initialized: whether the channel is initialized + * @inuse: whether the channel is in use + * @lock: protects multiple elements within this structure + * @vdev: virtio dev associated with this channel + * @vq: virtio queue associated with this channel + * @tagpool: accounting for tag ids (and request slots) + * @reqs: array of request slots + * @max_tag: current number of request_slots allocated + * @sg: scatter gather list which is used to pack a request (protected?) + * + * We keep all per-channel information in a structure. * This structure is allocated within the devices dev->mem space. * A pointer to the structure will get put in the transport private. + * */ + static struct virtio_chan { - bool initialized; /* channel is initialized */ - bool inuse; /* channel is in use */ + bool initialized; + bool inuse; spinlock_t lock; @@ -86,7 +132,19 @@ static struct virtio_chan { struct scatterlist sg[VIRTQUEUE_NUM]; } channels[MAX_9P_CHAN]; -/* Lookup requests by tag */ +/** + * p9_lookup_tag - Lookup requests by tag + * @c: virtio channel to lookup tag within + * @tag: numeric id for transaction + * + * this is a simple array lookup, but will grow the + * request_slots as necessary to accomodate transaction + * ids which did not previously have a slot. + * + * Bugs: there is currently no upper limit on request slots set + * here, but that should be constrained by the id accounting. + */ + static struct p9_req_t *p9_lookup_tag(struct virtio_chan *c, u16 tag) { /* This looks up the original request by tag so we know which @@ -130,11 +188,20 @@ static unsigned int rest_of_page(void *data) return PAGE_SIZE - ((unsigned long)data % PAGE_SIZE); } +/** + * p9_virtio_close - reclaim resources of a channel + * @trans: transport state + * + * This reclaims a channel by freeing its resources and + * reseting its inuse flag. + * + */ + static void p9_virtio_close(struct p9_trans *trans) { struct virtio_chan *chan = trans->priv; int count; - unsigned int flags; + unsigned long flags; spin_lock_irqsave(&chan->lock, flags); p9_idpool_destroy(chan->tagpool); @@ -144,13 +211,26 @@ static void p9_virtio_close(struct p9_trans *trans) chan->max_tag = 0; spin_unlock_irqrestore(&chan->lock, flags); - down(&virtio_9p_lock); + mutex_lock(&virtio_9p_lock); chan->inuse = false; - up(&virtio_9p_lock); + mutex_unlock(&virtio_9p_lock); kfree(trans); } +/** + * req_done - callback which signals activity from the server + * @vq: virtio queue activity was received on + * + * This notifies us that the server has triggered some activity + * on the virtio channel - most likely a response to request we + * sent. Figure out which requests now have responses and wake up + * those threads. + * + * Bugs: could do with some additional sanity checking, but appears to work. + * + */ + static void req_done(struct virtqueue *vq) { struct virtio_chan *chan = vq->vdev->priv; @@ -169,6 +249,20 @@ static void req_done(struct virtqueue *vq) spin_unlock_irqrestore(&chan->lock, flags); } +/** + * pack_sg_list - pack a scatter gather list from a linear buffer + * @sg: scatter/gather list to pack into + * @start: which segment of the sg_list to start at + * @limit: maximum segment to pack data to + * @data: data to pack into scatter/gather list + * @count: amount of data to pack into the scatter/gather list + * + * sg_lists have multiple segments of various sizes. This will pack + * arbitrary data into an existing scatter gather list, segmenting the + * data as necessary within constraints. + * + */ + static int pack_sg_list(struct scatterlist *sg, int start, int limit, char *data, int count) @@ -189,6 +283,14 @@ pack_sg_list(struct scatterlist *sg, int start, int limit, char *data, return index-start; } +/** + * p9_virtio_rpc - issue a request and wait for a response + * @t: transport state + * @tc: &p9_fcall request to transmit + * @rc: &p9_fcall to put reponse into + * + */ + static int p9_virtio_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc) { @@ -263,16 +365,26 @@ p9_virtio_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc) return 0; } +/** + * p9_virtio_probe - probe for existence of 9P virtio channels + * @vdev: virtio device to probe + * + * This probes for existing virtio channels. At present only + * a single channel is in use, so in the future more work may need + * to be done here. + * + */ + static int p9_virtio_probe(struct virtio_device *vdev) { int err; struct virtio_chan *chan; int index; - down(&virtio_9p_lock); + mutex_lock(&virtio_9p_lock); index = chan_index++; chan = &channels[index]; - up(&virtio_9p_lock); + mutex_unlock(&virtio_9p_lock); if (chan_index > MAX_9P_CHAN) { printk(KERN_ERR "9p: virtio: Maximum channels exceeded\n"); @@ -301,17 +413,34 @@ static int p9_virtio_probe(struct virtio_device *vdev) out_free_vq: vdev->config->del_vq(chan->vq); fail: - down(&virtio_9p_lock); + mutex_lock(&virtio_9p_lock); chan_index--; - up(&virtio_9p_lock); + mutex_unlock(&virtio_9p_lock); return err; } -/* This sets up a transport channel for 9p communication. Right now + +/** + * p9_virtio_create - allocate a new virtio channel + * @devname: string identifying the channel to connect to (unused) + * @args: args passed from sys_mount() for per-transport options (unused) + * @msize: requested maximum packet size + * @extended: 9p2000.u enabled flag + * + * This sets up a transport channel for 9p communication. Right now * we only match the first available channel, but eventually we couldlook up * alternate channels by matching devname versus a virtio_config entry. * We use a simple reference count mechanism to ensure that only a single - * mount has a channel open at a time. */ + * mount has a channel open at a time. + * + * Bugs: doesn't allow identification of a specific channel + * to allocate, channels are allocated sequentially. This was + * a pragmatic decision to get things rolling, but ideally some + * way of identifying the channel to attach to would be nice + * if we are going to support multiple channels. + * + */ + static struct p9_trans * p9_virtio_create(const char *devname, char *args, int msize, unsigned char extended) @@ -320,7 +449,7 @@ p9_virtio_create(const char *devname, char *args, int msize, struct virtio_chan *chan = channels; int index = 0; - down(&virtio_9p_lock); + mutex_lock(&virtio_9p_lock); while (index < MAX_9P_CHAN) { if (chan->initialized && !chan->inuse) { chan->inuse = true; @@ -330,7 +459,7 @@ p9_virtio_create(const char *devname, char *args, int msize, chan = &channels[index]; } } - up(&virtio_9p_lock); + mutex_unlock(&virtio_9p_lock); if (index >= MAX_9P_CHAN) { printk(KERN_ERR "9p: no channels available\n"); @@ -360,6 +489,12 @@ p9_virtio_create(const char *devname, char *args, int msize, return trans; } +/** + * p9_virtio_remove - clean up resources associated with a virtio device + * @vdev: virtio device to remove + * + */ + static void p9_virtio_remove(struct virtio_device *vdev) { struct virtio_chan *chan = vdev->priv; diff --git a/net/9p/util.c b/net/9p/util.c index ef7215565d881de05e00c7214623f3a8fa759b8f..958fc58cd1ffbb0723552b180302c569387adfb4 100644 --- a/net/9p/util.c +++ b/net/9p/util.c @@ -32,11 +32,23 @@ #include #include +/** + * struct p9_idpool - per-connection accounting for tag idpool + * @lock: protects the pool + * @pool: idr to allocate tag id from + * + */ + struct p9_idpool { spinlock_t lock; struct idr pool; }; +/** + * p9_idpool_create - create a new per-connection id pool + * + */ + struct p9_idpool *p9_idpool_create(void) { struct p9_idpool *p; @@ -52,6 +64,11 @@ struct p9_idpool *p9_idpool_create(void) } EXPORT_SYMBOL(p9_idpool_create); +/** + * p9_idpool_destroy - create a new per-connection id pool + * @p: idpool to destory + */ + void p9_idpool_destroy(struct p9_idpool *p) { idr_destroy(&p->pool); @@ -61,9 +78,9 @@ EXPORT_SYMBOL(p9_idpool_destroy); /** * p9_idpool_get - allocate numeric id from pool - * @p - pool to allocate from + * @p: pool to allocate from * - * XXX - This seems to be an awful generic function, should it be in idr.c with + * Bugs: This seems to be an awful generic function, should it be in idr.c with * the lock included in struct idr? */ @@ -71,7 +88,7 @@ int p9_idpool_get(struct p9_idpool *p) { int i = 0; int error; - unsigned int flags; + unsigned long flags; retry: if (idr_pre_get(&p->pool, GFP_KERNEL) == 0) @@ -94,15 +111,16 @@ EXPORT_SYMBOL(p9_idpool_get); /** * p9_idpool_put - release numeric id from pool - * @p - pool to allocate from + * @id: numeric id which is being released + * @p: pool to release id into * - * XXX - This seems to be an awful generic function, should it be in idr.c with + * Bugs: This seems to be an awful generic function, should it be in idr.c with * the lock included in struct idr? */ void p9_idpool_put(int id, struct p9_idpool *p) { - unsigned int flags; + unsigned long flags; spin_lock_irqsave(&p->lock, flags); idr_remove(&p->pool, id); spin_unlock_irqrestore(&p->lock, flags); @@ -111,11 +129,13 @@ EXPORT_SYMBOL(p9_idpool_put); /** * p9_idpool_check - check if the specified id is available - * @id - id to check - * @p - pool + * @id: id to check + * @p: pool to check */ + int p9_idpool_check(int id, struct p9_idpool *p) { return idr_find(&p->pool, id) != NULL; } EXPORT_SYMBOL(p9_idpool_check); + diff --git a/net/atm/br2684.c b/net/atm/br2684.c index 1b228065e745c812ee8db3d6ca0b3bb68586b796..9d52ebfc1962b360774f55e728b32ea0d8388654 100644 --- a/net/atm/br2684.c +++ b/net/atm/br2684.c @@ -346,9 +346,9 @@ static void br2684_push(struct atm_vcc *atmvcc, struct sk_buff *skb) /* skb==NULL means VCC is being destroyed */ br2684_close_vcc(brvcc); if (list_empty(&brdev->brvccs)) { - read_lock(&devs_lock); + write_lock_irq(&devs_lock); list_del(&brdev->br2684_devs); - read_unlock(&devs_lock); + write_unlock_irq(&devs_lock); unregister_netdev(net_dev); free_netdev(net_dev); } diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 77a981a1ee52249d5fbed7966f294afe7730ffb3..c2397f503b0f94e850d7da40b68e53fb16b9f9ae 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -273,15 +273,13 @@ int br_add_bridge(const char *name) rtnl_lock(); if (strchr(dev->name, '%')) { ret = dev_alloc_name(dev, dev->name); - if (ret < 0) { - free_netdev(dev); - goto out; - } + if (ret < 0) + goto out_free; } ret = register_netdevice(dev); if (ret) - goto out; + goto out_free; ret = br_sysfs_addbr(dev); if (ret) @@ -289,6 +287,10 @@ int br_add_bridge(const char *name) out: rtnl_unlock(); return ret; + +out_free: + free_netdev(dev); + goto out; } int br_del_bridge(const char *name) diff --git a/net/can/af_can.c b/net/can/af_can.c index 2759b76f731c30461d6205db15e1c2bad4efb8c4..7e8ca2836452a5053c4695691ceba78a9d4605d1 100644 --- a/net/can/af_can.c +++ b/net/can/af_can.c @@ -208,6 +208,7 @@ static int can_create(struct net *net, struct socket *sock, int protocol) */ int can_send(struct sk_buff *skb, int loop) { + struct sk_buff *newskb = NULL; int err; if (skb->dev->type != ARPHRD_CAN) { @@ -244,8 +245,7 @@ int can_send(struct sk_buff *skb, int loop) * If the interface is not capable to do loopback * itself, we do it here. */ - struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC); - + newskb = skb_clone(skb, GFP_ATOMIC); if (!newskb) { kfree_skb(skb); return -ENOMEM; @@ -254,7 +254,6 @@ int can_send(struct sk_buff *skb, int loop) newskb->sk = skb->sk; newskb->ip_summed = CHECKSUM_UNNECESSARY; newskb->pkt_type = PACKET_BROADCAST; - netif_rx(newskb); } } else { /* indication for the CAN driver: no loopback required */ @@ -266,11 +265,20 @@ int can_send(struct sk_buff *skb, int loop) if (err > 0) err = net_xmit_errno(err); + if (err) { + if (newskb) + kfree_skb(newskb); + return err; + } + + if (newskb) + netif_rx(newskb); + /* update statistics */ can_stats.tx_frames++; can_stats.tx_frames_delta++; - return err; + return 0; } EXPORT_SYMBOL(can_send); diff --git a/net/core/dev.c b/net/core/dev.c index d334446a8eaf8e4cfdd5953be2c03d9cbe1d0e98..a1607bc0cd4cd3601b2183616845b564a1057c52 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -994,6 +994,8 @@ int dev_open(struct net_device *dev) { int ret = 0; + ASSERT_RTNL(); + /* * Is it already up? */ @@ -1060,6 +1062,8 @@ int dev_open(struct net_device *dev) */ int dev_close(struct net_device *dev) { + ASSERT_RTNL(); + might_sleep(); if (!(dev->flags & IFF_UP)) @@ -4480,17 +4484,19 @@ static void __net_exit default_device_exit(struct net *net) rtnl_lock(); for_each_netdev_safe(net, dev, next) { int err; + char fb_name[IFNAMSIZ]; /* Ignore unmoveable devices (i.e. loopback) */ if (dev->features & NETIF_F_NETNS_LOCAL) continue; /* Push remaing network devices to init_net */ - err = dev_change_net_namespace(dev, &init_net, "dev%d"); + snprintf(fb_name, IFNAMSIZ, "dev%d", dev->ifindex); + err = dev_change_net_namespace(dev, &init_net, fb_name); if (err) { - printk(KERN_WARNING "%s: failed to move %s to init_net: %d\n", + printk(KERN_EMERG "%s: failed to move %s to init_net: %d\n", __func__, dev->name, err); - unregister_netdevice(dev); + BUG(); } } rtnl_unlock(); diff --git a/net/core/netpoll.c b/net/core/netpoll.c index b04d643fc3c704cf21619251713ca190f3986554..8fb134da0346ef02629f03e690afa8bda4fda0f1 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c @@ -419,7 +419,7 @@ static void arp_reply(struct sk_buff *skb) return; size = arp_hdr_len(skb->dev); - send_skb = find_skb(np, size + LL_RESERVED_SPACE(np->dev), + send_skb = find_skb(np, size + LL_ALLOCATED_SPACE(np->dev), LL_RESERVED_SPACE(np->dev)); if (!send_skb) diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 4fe605fa6f8a27dd2c346bedcb78caa09fdf8e81..5c459f2b7985211e0dd8d067e925c20f2e35b958 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -200,7 +200,9 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, goto nodata; /* - * See comment in sk_buff definition, just before the 'tail' member + * Only clear those fields we need to clear, not those that we will + * actually initialise below. Hence, don't put any more fields after + * the tail pointer in struct sk_buff! */ memset(skb, 0, offsetof(struct sk_buff, tail)); skb->truesize = size + sizeof(struct sk_buff); diff --git a/net/core/sock.c b/net/core/sock.c index fa76f04fa9c6fd443937702f4f869417bf217c4f..88094cb09c06c0749fc768338d93bf8d4b5208c3 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -270,7 +270,7 @@ int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) int err = 0; int skb_len; - /* Cast skb->rcvbuf to unsigned... It's pointless, but reduces + /* Cast sk->rcvbuf to unsigned... It's pointless, but reduces number of warnings when compiling with -W --ANK */ if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >= diff --git a/net/dccp/feat.c b/net/dccp/feat.c index 4a4f6ce4498d42c77dde9b7a5867575210931b31..933a0ecf8d463b0649fd69f78335533d86950517 100644 --- a/net/dccp/feat.c +++ b/net/dccp/feat.c @@ -32,7 +32,7 @@ int dccp_feat_change(struct dccp_minisock *dmsk, u8 type, u8 feature, if (len > 3) { DCCP_WARN("invalid length %d\n", len); - return 1; + return -EINVAL; } /* XXX add further sanity checks */ diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index 2f665a516476a019460046d61195310aecf5654a..f50e88bf2661b5cb3f353433007aad7415410ab4 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -235,14 +235,14 @@ static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu) else min_mtu -= 21; - if (dst->metrics[RTAX_MTU-1] > mtu && mtu >= min_mtu) { + if (dst_metric(dst, RTAX_MTU) > mtu && mtu >= min_mtu) { if (!(dst_metric_locked(dst, RTAX_MTU))) { dst->metrics[RTAX_MTU-1] = mtu; dst_set_expires(dst, dn_rt_mtu_expires); } if (!(dst_metric_locked(dst, RTAX_ADVMSS))) { u32 mss = mtu - DN_MAX_NSP_DATA_HEADER; - if (dst->metrics[RTAX_ADVMSS-1] > mss) + if (dst_metric(dst, RTAX_ADVMSS) > mss) dst->metrics[RTAX_ADVMSS-1] = mss; } } @@ -805,12 +805,12 @@ static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res) rt->u.dst.neighbour = n; } - if (rt->u.dst.metrics[RTAX_MTU-1] == 0 || - rt->u.dst.metrics[RTAX_MTU-1] > rt->u.dst.dev->mtu) + if (dst_metric(&rt->u.dst, RTAX_MTU) == 0 || + dst_metric(&rt->u.dst, RTAX_MTU) > rt->u.dst.dev->mtu) rt->u.dst.metrics[RTAX_MTU-1] = rt->u.dst.dev->mtu; mss = dn_mss_from_pmtu(dev, dst_mtu(&rt->u.dst)); - if (rt->u.dst.metrics[RTAX_ADVMSS-1] == 0 || - rt->u.dst.metrics[RTAX_ADVMSS-1] > mss) + if (dst_metric(&rt->u.dst, RTAX_ADVMSS) == 0 || + dst_metric(&rt->u.dst, RTAX_ADVMSS) > mss) rt->u.dst.metrics[RTAX_ADVMSS-1] = mss; return 0; } diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c index 68d154480043577572b976b871bdeb7188075a72..7c9bb13b1539daf0e31465a31a41b0282fd429dd 100644 --- a/net/econet/af_econet.c +++ b/net/econet/af_econet.c @@ -340,7 +340,7 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, dev_hold(dev); - skb = sock_alloc_send_skb(sk, len+LL_RESERVED_SPACE(dev), + skb = sock_alloc_send_skb(sk, len+LL_ALLOCATED_SPACE(dev), msg->msg_flags & MSG_DONTWAIT, &err); if (skb==NULL) goto out_unlock; diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 68b72a7a180606e1e3469e6c6ece800aaab089d7..418862f1bf221925e08f4cc04891165f81b25776 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -570,7 +570,7 @@ struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip, * Allocate a buffer */ - skb = alloc_skb(arp_hdr_len(dev) + LL_RESERVED_SPACE(dev), GFP_ATOMIC); + skb = alloc_skb(arp_hdr_len(dev) + LL_ALLOCATED_SPACE(dev), GFP_ATOMIC); if (skb == NULL) return NULL; diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index 05afb576d93524624e25cafed22818719cc6aaf3..2c0e4572cc9042e76fca92f5c08303d1489f513c 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c @@ -338,7 +338,7 @@ static int cipso_v4_cache_check(const unsigned char *key, return -ENOENT; hash = cipso_v4_map_cache_hash(key, key_len); - bkt = hash & (CIPSO_V4_CACHE_BUCKETBITS - 1); + bkt = hash & (CIPSO_V4_CACHE_BUCKETS - 1); spin_lock_bh(&cipso_v4_cache[bkt].lock); list_for_each_entry(entry, &cipso_v4_cache[bkt].list, list) { if (entry->hash == hash && @@ -417,7 +417,7 @@ int cipso_v4_cache_add(const struct sk_buff *skb, atomic_inc(&secattr->cache->refcount); entry->lsm_data = secattr->cache; - bkt = entry->hash & (CIPSO_V4_CACHE_BUCKETBITS - 1); + bkt = entry->hash & (CIPSO_V4_CACHE_BUCKETS - 1); spin_lock_bh(&cipso_v4_cache[bkt].lock); if (cipso_v4_cache[bkt].size < cipso_v4_cache_bucketsize) { list_add(&entry->list, &cipso_v4_cache[bkt].list); diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 6250f4239b619e516e694207be49e29c2988c9ea..2769dc4a4c84418ddafd0316a96574dfe50d0911 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -292,7 +292,7 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size) struct iphdr *pip; struct igmpv3_report *pig; - skb = alloc_skb(size + LL_RESERVED_SPACE(dev), GFP_ATOMIC); + skb = alloc_skb(size + LL_ALLOCATED_SPACE(dev), GFP_ATOMIC); if (skb == NULL) return NULL; @@ -653,7 +653,7 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc, return -1; } - skb=alloc_skb(IGMP_SIZE+LL_RESERVED_SPACE(dev), GFP_ATOMIC); + skb=alloc_skb(IGMP_SIZE+LL_ALLOCATED_SPACE(dev), GFP_ATOMIC); if (skb == NULL) { ip_rt_put(rt); return -1; diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index 7b4bad6d572ffe4093b9b4bed126fc02fd274f0b..ff77a4a7f9ecae8d431020b1d05db46972720d97 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c @@ -397,7 +397,7 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, iph = ip_hdr(skb); /* - * RFC1122: 3.1.2.2 MUST silently discard any IP frame that fails the checksum. + * RFC1122: 3.2.1.2 MUST silently discard any IP frame that fails the checksum. * * Is the datagram acceptable? * diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index 89dee4346f6065184dce57a0584412fd210cd130..ed45037ce9be644e31070380375140a23400b8fc 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c @@ -710,14 +710,14 @@ static void __init ic_bootp_send_if(struct ic_device *d, unsigned long jiffies_d struct net_device *dev = d->dev; struct sk_buff *skb; struct bootp_pkt *b; - int hh_len = LL_RESERVED_SPACE(dev); struct iphdr *h; /* Allocate packet */ - skb = alloc_skb(sizeof(struct bootp_pkt) + hh_len + 15, GFP_KERNEL); + skb = alloc_skb(sizeof(struct bootp_pkt) + LL_ALLOCATED_SPACE(dev) + 15, + GFP_KERNEL); if (!skb) return; - skb_reserve(skb, hh_len); + skb_reserve(skb, LL_RESERVED_SPACE(dev)); b = (struct bootp_pkt *) skb_put(skb, sizeof(struct bootp_pkt)); memset(b, 0, sizeof(struct bootp_pkt)); diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 11d7f753a8206bb6b28335deaf1982a8f8cc1ef1..fead049daf4399b94d6e8322ac7aa1e25b17999f 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -322,7 +322,6 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length, unsigned int flags) { struct inet_sock *inet = inet_sk(sk); - int hh_len; struct iphdr *iph; struct sk_buff *skb; unsigned int iphlen; @@ -336,13 +335,12 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length, if (flags&MSG_PROBE) goto out; - hh_len = LL_RESERVED_SPACE(rt->u.dst.dev); - - skb = sock_alloc_send_skb(sk, length+hh_len+15, - flags&MSG_DONTWAIT, &err); + skb = sock_alloc_send_skb(sk, + length + LL_ALLOCATED_SPACE(rt->u.dst.dev) + 15, + flags & MSG_DONTWAIT, &err); if (skb == NULL) goto error; - skb_reserve(skb, hh_len); + skb_reserve(skb, LL_RESERVED_SPACE(rt->u.dst.dev)); skb->priority = sk->sk_priority; skb->mark = sk->sk_mark; diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 5e3685c5c407ac2e6b24c13eaf055319d2d341aa..92f90ae46f4a3cc453ebf17c3a97d1df508394a6 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1468,14 +1468,14 @@ unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph, /* BSD 4.2 compatibility hack :-( */ if (mtu == 0 && - old_mtu >= rth->u.dst.metrics[RTAX_MTU-1] && + old_mtu >= dst_metric(&rth->u.dst, RTAX_MTU) && old_mtu >= 68 + (iph->ihl << 2)) old_mtu -= iph->ihl << 2; mtu = guess_mtu(old_mtu); } - if (mtu <= rth->u.dst.metrics[RTAX_MTU-1]) { - if (mtu < rth->u.dst.metrics[RTAX_MTU-1]) { + if (mtu <= dst_metric(&rth->u.dst, RTAX_MTU)) { + if (mtu < dst_metric(&rth->u.dst, RTAX_MTU)) { dst_confirm(&rth->u.dst); if (mtu < ip_rt_min_pmtu) { mtu = ip_rt_min_pmtu; @@ -1497,7 +1497,7 @@ unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph, static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu) { - if (dst->metrics[RTAX_MTU-1] > mtu && mtu >= 68 && + if (dst_metric(dst, RTAX_MTU) > mtu && mtu >= 68 && !(dst_metric_locked(dst, RTAX_MTU))) { if (mtu < ip_rt_min_pmtu) { mtu = ip_rt_min_pmtu; @@ -1613,7 +1613,7 @@ static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag) sizeof(rt->u.dst.metrics)); if (fi->fib_mtu == 0) { rt->u.dst.metrics[RTAX_MTU-1] = rt->u.dst.dev->mtu; - if (rt->u.dst.metrics[RTAX_LOCK-1] & (1 << RTAX_MTU) && + if (dst_metric_locked(&rt->u.dst, RTAX_MTU) && rt->rt_gateway != rt->rt_dst && rt->u.dst.dev->mtu > 576) rt->u.dst.metrics[RTAX_MTU-1] = 576; @@ -1624,14 +1624,14 @@ static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag) } else rt->u.dst.metrics[RTAX_MTU-1]= rt->u.dst.dev->mtu; - if (rt->u.dst.metrics[RTAX_HOPLIMIT-1] == 0) + if (dst_metric(&rt->u.dst, RTAX_HOPLIMIT) == 0) rt->u.dst.metrics[RTAX_HOPLIMIT-1] = sysctl_ip_default_ttl; - if (rt->u.dst.metrics[RTAX_MTU-1] > IP_MAX_MTU) + if (dst_metric(&rt->u.dst, RTAX_MTU) > IP_MAX_MTU) rt->u.dst.metrics[RTAX_MTU-1] = IP_MAX_MTU; - if (rt->u.dst.metrics[RTAX_ADVMSS-1] == 0) + if (dst_metric(&rt->u.dst, RTAX_ADVMSS) == 0) rt->u.dst.metrics[RTAX_ADVMSS-1] = max_t(unsigned int, rt->u.dst.dev->mtu - 40, ip_rt_min_advmss); - if (rt->u.dst.metrics[RTAX_ADVMSS-1] > 65535 - 40) + if (dst_metric(&rt->u.dst, RTAX_ADVMSS) > 65535 - 40) rt->u.dst.metrics[RTAX_ADVMSS-1] = 65535 - 40; #ifdef CONFIG_NET_CLS_ROUTE diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index eda4f4a233f36e940fe81cf83188dcbc2817e0fa..b54d9d37b636a79b26de0f0ee36e9f6024ba453e 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -66,6 +66,7 @@ #include #include #include +#include #include #include #include @@ -113,8 +114,6 @@ int sysctl_tcp_abc __read_mostly; #define FLAG_FORWARD_PROGRESS (FLAG_ACKED|FLAG_DATA_SACKED) #define FLAG_ANY_PROGRESS (FLAG_FORWARD_PROGRESS|FLAG_SND_UNA_ADVANCED) -#define IsSackFrto() (sysctl_tcp_frto == 0x2) - #define TCP_REMNANT (TCP_FLAG_FIN|TCP_FLAG_URG|TCP_FLAG_SYN|TCP_FLAG_PSH) #define TCP_HP_BITS (~(TCP_RESERVED_BITS|TCP_FLAG_PSH)) @@ -605,7 +604,7 @@ static u32 tcp_rto_min(struct sock *sk) u32 rto_min = TCP_RTO_MIN; if (dst && dst_metric_locked(dst, RTAX_RTO_MIN)) - rto_min = dst->metrics[RTAX_RTO_MIN - 1]; + rto_min = dst_metric(dst, RTAX_RTO_MIN); return rto_min; } @@ -769,7 +768,7 @@ void tcp_update_metrics(struct sock *sk) dst->metrics[RTAX_RTTVAR - 1] = m; else dst->metrics[RTAX_RTTVAR-1] -= - (dst->metrics[RTAX_RTTVAR-1] - m)>>2; + (dst_metric(dst, RTAX_RTTVAR) - m)>>2; } if (tp->snd_ssthresh >= 0xFFFF) { @@ -788,21 +787,21 @@ void tcp_update_metrics(struct sock *sk) dst->metrics[RTAX_SSTHRESH-1] = max(tp->snd_cwnd >> 1, tp->snd_ssthresh); if (!dst_metric_locked(dst, RTAX_CWND)) - dst->metrics[RTAX_CWND-1] = (dst->metrics[RTAX_CWND-1] + tp->snd_cwnd) >> 1; + dst->metrics[RTAX_CWND-1] = (dst_metric(dst, RTAX_CWND) + tp->snd_cwnd) >> 1; } else { /* Else slow start did not finish, cwnd is non-sense, ssthresh may be also invalid. */ if (!dst_metric_locked(dst, RTAX_CWND)) - dst->metrics[RTAX_CWND-1] = (dst->metrics[RTAX_CWND-1] + tp->snd_ssthresh) >> 1; - if (dst->metrics[RTAX_SSTHRESH-1] && + dst->metrics[RTAX_CWND-1] = (dst_metric(dst, RTAX_CWND) + tp->snd_ssthresh) >> 1; + if (dst_metric(dst, RTAX_SSTHRESH) && !dst_metric_locked(dst, RTAX_SSTHRESH) && - tp->snd_ssthresh > dst->metrics[RTAX_SSTHRESH-1]) + tp->snd_ssthresh > dst_metric(dst, RTAX_SSTHRESH)) dst->metrics[RTAX_SSTHRESH-1] = tp->snd_ssthresh; } if (!dst_metric_locked(dst, RTAX_REORDERING)) { - if (dst->metrics[RTAX_REORDERING-1] < tp->reordering && + if (dst_metric(dst, RTAX_REORDERING) < tp->reordering && tp->reordering != sysctl_tcp_reordering) dst->metrics[RTAX_REORDERING-1] = tp->reordering; } @@ -1685,6 +1684,11 @@ static inline void tcp_reset_reno_sack(struct tcp_sock *tp) tp->sacked_out = 0; } +static int tcp_is_sackfrto(const struct tcp_sock *tp) +{ + return (sysctl_tcp_frto == 0x2) && !tcp_is_reno(tp); +} + /* F-RTO can only be used if TCP has never retransmitted anything other than * head (SACK enhanced variant from Appendix B of RFC4138 is more robust here) */ @@ -1701,7 +1705,7 @@ int tcp_use_frto(struct sock *sk) if (icsk->icsk_mtup.probe_size) return 0; - if (IsSackFrto()) + if (tcp_is_sackfrto(tp)) return 1; /* Avoid expensive walking of rexmit queue if possible */ @@ -1791,7 +1795,7 @@ void tcp_enter_frto(struct sock *sk) /* Earlier loss recovery underway (see RFC4138; Appendix B). * The last condition is necessary at least in tp->frto_counter case. */ - if (IsSackFrto() && (tp->frto_counter || + if (tcp_is_sackfrto(tp) && (tp->frto_counter || ((1 << icsk->icsk_ca_state) & (TCPF_CA_Recovery|TCPF_CA_Loss))) && after(tp->high_seq, tp->snd_una)) { tp->frto_highmark = tp->high_seq; @@ -1838,9 +1842,16 @@ static void tcp_enter_frto_loss(struct sock *sk, int allowed_segments, int flag) TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS; } - /* Don't lost mark skbs that were fwd transmitted after RTO */ - if (!(TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED) && - !after(TCP_SKB_CB(skb)->end_seq, tp->frto_highmark)) { + /* Marking forward transmissions that were made after RTO lost + * can cause unnecessary retransmissions in some scenarios, + * SACK blocks will mitigate that in some but not in all cases. + * We used to not mark them but it was causing break-ups with + * receivers that do only in-order receival. + * + * TODO: we could detect presence of such receiver and select + * different behavior per flow. + */ + if (!(TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED)) { TCP_SKB_CB(skb)->sacked |= TCPCB_LOST; tp->lost_out += tcp_skb_pcount(skb); } @@ -1856,7 +1867,7 @@ static void tcp_enter_frto_loss(struct sock *sk, int allowed_segments, int flag) tp->reordering = min_t(unsigned int, tp->reordering, sysctl_tcp_reordering); tcp_set_ca_state(sk, TCP_CA_Loss); - tp->high_seq = tp->frto_highmark; + tp->high_seq = tp->snd_nxt; TCP_ECN_queue_cwr(tp); tcp_clear_retrans_hints_partial(tp); @@ -2478,7 +2489,7 @@ static void tcp_try_to_open(struct sock *sk, int flag) tcp_verify_left_out(tp); - if (tp->retrans_out == 0) + if (!tp->frto_counter && tp->retrans_out == 0) tp->retrans_stamp = 0; if (flag & FLAG_ECE) @@ -3123,7 +3134,7 @@ static int tcp_process_frto(struct sock *sk, int flag) return 1; } - if (!IsSackFrto() || tcp_is_reno(tp)) { + if (!tcp_is_sackfrto(tp)) { /* RFC4138 shortcoming in step 2; should also have case c): * ACK isn't duplicate nor advances window, e.g., opposite dir * data, winupdate diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 0af2e055f883c626b17adb0b4cb2fb4141738ff1..48cdce9c696c24b54eb4583f3cf27cab6b02d967 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -780,7 +780,7 @@ slow_path: * Allocate buffer. */ - if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_RESERVED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) { + if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_ALLOCATED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) { NETDEBUG(KERN_INFO "IPv6: frag: no memory for new fragment!\n"); IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS); diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 54f91efdae58cdcded9923675b34ea0bec580f04..fd632dd7f98d834049a7f75532ea42db5ee092d7 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c @@ -1411,7 +1411,7 @@ static struct sk_buff *mld_newpack(struct net_device *dev, int size) IPV6_TLV_PADN, 0 }; /* we assume size > sizeof(ra) here */ - skb = sock_alloc_send_skb(sk, size + LL_RESERVED_SPACE(dev), 1, &err); + skb = sock_alloc_send_skb(sk, size + LL_ALLOCATED_SPACE(dev), 1, &err); if (!skb) return NULL; @@ -1790,7 +1790,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) payload_len = len + sizeof(ra); full_len = sizeof(struct ipv6hdr) + payload_len; - skb = sock_alloc_send_skb(sk, LL_RESERVED_SPACE(dev) + full_len, 1, &err); + skb = sock_alloc_send_skb(sk, LL_ALLOCATED_SPACE(dev) + full_len, 1, &err); if (skb == NULL) { rcu_read_lock(); diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 2c74885f835514c431a43b2c9cdaa787b29267ea..a55fc05b81251463ccc6ed07dac1d8ba9c545491 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -479,7 +479,7 @@ static void __ndisc_send(struct net_device *dev, skb = sock_alloc_send_skb(sk, (MAX_HEADER + sizeof(struct ipv6hdr) + - len + LL_RESERVED_SPACE(dev)), + len + LL_ALLOCATED_SPACE(dev)), 1, &err); if (!skb) { ND_PRINTK0(KERN_ERR @@ -1521,7 +1521,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh, buff = sock_alloc_send_skb(sk, (MAX_HEADER + sizeof(struct ipv6hdr) + - len + LL_RESERVED_SPACE(dev)), + len + LL_ALLOCATED_SPACE(dev)), 1, &err); if (buff == NULL) { ND_PRINTK0(KERN_ERR diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 396f0ea11090a98d6a07898d0e79d58fb7652313..232e0dc45bf58a91526d3f292eb7b90b654fcac3 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -609,7 +609,6 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length, struct ipv6_pinfo *np = inet6_sk(sk); struct ipv6hdr *iph; struct sk_buff *skb; - unsigned int hh_len; int err; if (length > rt->u.dst.dev->mtu) { @@ -619,13 +618,12 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length, if (flags&MSG_PROBE) goto out; - hh_len = LL_RESERVED_SPACE(rt->u.dst.dev); - - skb = sock_alloc_send_skb(sk, length+hh_len+15, - flags&MSG_DONTWAIT, &err); + skb = sock_alloc_send_skb(sk, + length + LL_ALLOCATED_SPACE(rt->u.dst.dev) + 15, + flags & MSG_DONTWAIT, &err); if (skb == NULL) goto error; - skb_reserve(skb, hh_len); + skb_reserve(skb, LL_RESERVED_SPACE(rt->u.dst.dev)); skb->priority = sk->sk_priority; skb->mark = sk->sk_mark; diff --git a/net/ipv6/route.c b/net/ipv6/route.c index a493ad9b891475bdd7cd0c11b18688d8fe306f31..12bba0880345474e13a02bf42f6ab44cdbeb19e7 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1243,11 +1243,11 @@ install_route: } } - if (rt->u.dst.metrics[RTAX_HOPLIMIT-1] == 0) + if (dst_metric(&rt->u.dst, RTAX_HOPLIMIT) == 0) rt->u.dst.metrics[RTAX_HOPLIMIT-1] = -1; - if (!rt->u.dst.metrics[RTAX_MTU-1]) + if (!dst_metric(&rt->u.dst, RTAX_MTU)) rt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(dev); - if (!rt->u.dst.metrics[RTAX_ADVMSS-1]) + if (!dst_metric(&rt->u.dst, RTAX_ADVMSS)) rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(net, dst_mtu(&rt->u.dst)); rt->u.dst.dev = dev; rt->rt6i_idev = idev; diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 4b2f1033994e2d1f6c2c94ca18b7e202956f3688..5a6fab95569fa14e12f40d74121ef7ba5321a0fd 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -596,9 +596,9 @@ static int ipip6_rcv(struct sk_buff *skb) } icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); - kfree_skb(skb); read_unlock(&ipip6_lock); out: + kfree_skb(skb); return 0; } diff --git a/net/irda/discovery.c b/net/irda/discovery.c index bfacef8b76f44b6228e15b3025c3ea31d7d14ed4..a6f99b5a14995ff62e5620f042ca0821f3552cc3 100644 --- a/net/irda/discovery.c +++ b/net/irda/discovery.c @@ -40,6 +40,8 @@ #include +#include + /* * Function irlmp_add_discovery (cachelog, discovery) * @@ -87,7 +89,7 @@ void irlmp_add_discovery(hashbin_t *cachelog, discovery_t *new) */ hashbin_remove_this(cachelog, (irda_queue_t *) node); /* Check if hints bits are unchanged */ - if(u16ho(node->data.hints) == u16ho(new->data.hints)) + if (get_unaligned((__u16 *)node->data.hints) == get_unaligned((__u16 *)new->data.hints)) /* Set time of first discovery for this node */ new->firststamp = node->firststamp; kfree(node); @@ -281,9 +283,9 @@ struct irda_device_info *irlmp_copy_discoveries(hashbin_t *log, int *pn, /* Mask out the ones we don't want : * We want to match the discovery mask, and to get only * the most recent one (unless we want old ones) */ - if ((u16ho(discovery->data.hints) & mask) && + if ((get_unaligned((__u16 *)discovery->data.hints) & mask) && ((old_entries) || - ((jiffies - discovery->firststamp) < j_timeout)) ) { + ((jiffies - discovery->firststamp) < j_timeout))) { /* Create buffer as needed. * As this function get called a lot and most time * we don't have anything to put in the log (we are diff --git a/net/irda/irlmp.c b/net/irda/irlmp.c index 1f81f8e7c61da790b969f14e84952b9b349384c6..7bf5b913828babd3daeddc4e12df3b12224ad668 100644 --- a/net/irda/irlmp.c +++ b/net/irda/irlmp.c @@ -1062,7 +1062,8 @@ void irlmp_discovery_expiry(discinfo_t *expiries, int number) for(i = 0; i < number; i++) { /* Check if we should notify client */ if ((client->expir_callback) && - (client->hint_mask.word & u16ho(expiries[i].hints) + (client->hint_mask.word & + get_unaligned((__u16 *)expiries[i].hints) & 0x7f7f) ) client->expir_callback(&(expiries[i]), EXPIRY_TIMEOUT, @@ -1086,7 +1087,7 @@ discovery_t *irlmp_get_discovery_response(void) IRDA_ASSERT(irlmp != NULL, return NULL;); - u16ho(irlmp->discovery_rsp.data.hints) = irlmp->hints.word; + put_unaligned(irlmp->hints.word, (__u16 *)irlmp->discovery_rsp.data.hints); /* * Set character set for device name (we use ASCII), and diff --git a/net/irda/irnet/irnet_irda.c b/net/irda/irnet/irnet_irda.c index 75497e55927d695a3eee228833c68097edeb86ae..cf9a4b531a98f5d73386cb7f8d2c7db3837239cf 100644 --- a/net/irda/irnet/irnet_irda.c +++ b/net/irda/irnet/irnet_irda.c @@ -10,6 +10,7 @@ #include "irnet_irda.h" /* Private header */ #include +#include /* * PPP disconnect work: we need to make sure we're in @@ -1673,7 +1674,7 @@ irnet_discovery_indication(discinfo_t * discovery, /* Notify the control channel */ irnet_post_event(NULL, IRNET_DISCOVER, discovery->saddr, discovery->daddr, discovery->info, - u16ho(discovery->hints)); + get_unaligned((__u16 *)discovery->hints)); DEXIT(IRDA_OCB_TRACE, "\n"); } @@ -1704,7 +1705,7 @@ irnet_expiry_indication(discinfo_t * expiry, /* Notify the control channel */ irnet_post_event(NULL, IRNET_EXPIRE, expiry->saddr, expiry->daddr, expiry->info, - u16ho(expiry->hints)); + get_unaligned((__u16 *)expiry->hints)); DEXIT(IRDA_OCB_TRACE, "\n"); } diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c index 879e7210458ad3ae8965b0d8cc7211cd614a83c2..19efc3a6a9327cfd343ab5e62de2a993ec6821bf 100644 --- a/net/mac80211/debugfs_key.c +++ b/net/mac80211/debugfs_key.c @@ -255,14 +255,23 @@ void ieee80211_debugfs_key_remove(struct ieee80211_key *key) void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata) { char buf[50]; + struct ieee80211_key *key; if (!sdata->debugfsdir) return; - sprintf(buf, "../keys/%d", sdata->default_key->debugfs.cnt); - sdata->debugfs.default_key = - debugfs_create_symlink("default_key", sdata->debugfsdir, buf); + /* this is running under the key lock */ + + key = sdata->default_key; + if (key) { + sprintf(buf, "../keys/%d", key->debugfs.cnt); + sdata->debugfs.default_key = + debugfs_create_symlink("default_key", + sdata->debugfsdir, buf); + } else + ieee80211_debugfs_key_remove_default(sdata); } + void ieee80211_debugfs_key_remove_default(struct ieee80211_sub_if_data *sdata) { if (!sdata) diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 80954a512185ca66ab65bbc087bce1b8f3a0b743..06e88a5a036d2ebce586a94f0bf7a635ca8a6405 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -54,6 +54,15 @@ int ieee80211_if_add(struct net_device *dev, const char *name, if (!ndev) return -ENOMEM; + ndev->needed_headroom = local->tx_headroom + + 4*6 /* four MAC addresses */ + + 2 + 2 + 2 + 2 /* ctl, dur, seq, qos */ + + 6 /* mesh */ + + 8 /* rfc1042/bridge tunnel */ + - ETH_HLEN /* ethernet hard_header_len */ + + IEEE80211_ENCRYPT_HEADROOM; + ndev->needed_tailroom = IEEE80211_ENCRYPT_TAILROOM; + ret = dev_alloc_name(ndev, ndev->name); if (ret < 0) goto fail; diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 9ad4e3631b6bd4b5ac012f53457abcaa41e2ec47..915afadb06028b270e7229074a325c66836a3e85 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -1766,6 +1766,7 @@ fail_wep: fail_rate: ieee80211_debugfs_remove_netdev(IEEE80211_DEV_TO_SUB_IF(local->mdev)); unregister_netdevice(local->mdev); + local->mdev = NULL; fail_dev: rtnl_unlock(); sta_info_stop(local); @@ -1773,8 +1774,10 @@ fail_sta_info: debugfs_hw_del(local); destroy_workqueue(local->hw.workqueue); fail_workqueue: - ieee80211_if_free(local->mdev); - local->mdev = NULL; + if (local->mdev != NULL) { + ieee80211_if_free(local->mdev); + local->mdev = NULL; + } fail_mdev_alloc: wiphy_unregister(local->hw.wiphy); return result; diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index f76bc26ae4d219301dcde04bda7b62d350007ba1..697ef67f96b6796bc60aaefa88720e67191ff007 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -397,7 +397,7 @@ int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr, put_unaligned(cpu_to_le32(sdata->u.sta.mesh_seqnum), &meshhdr->seqnum); sdata->u.sta.mesh_seqnum++; - return 5; + return 6; } void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata) diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index 3df809222d1cbcfc1c88605d0406303ed1d25098..af0cd1e3e2131136026b0851aad60f42db31825f 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c @@ -120,7 +120,7 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags, *pos++ = WLAN_EID_PREP; break; default: - kfree(skb); + kfree_skb(skb); return -ENOTSUPP; break; } diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 5845dc21ce854ea535cb9fa69af2cbcb2b4d4889..99c2d360888ef30cc7f0e8637b7aea9af0d474a4 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -158,19 +158,25 @@ int mesh_path_add(u8 *dst, struct net_device *dev) if (atomic_add_unless(&sdata->u.sta.mpaths, 1, MESH_MAX_MPATHS) == 0) return -ENOSPC; - read_lock(&pathtbl_resize_lock); - new_mpath = kzalloc(sizeof(struct mesh_path), GFP_KERNEL); if (!new_mpath) { atomic_dec(&sdata->u.sta.mpaths); err = -ENOMEM; goto endadd2; } + new_node = kmalloc(sizeof(struct mpath_node), GFP_KERNEL); + if (!new_node) { + kfree(new_mpath); + atomic_dec(&sdata->u.sta.mpaths); + err = -ENOMEM; + goto endadd2; + } + + read_lock(&pathtbl_resize_lock); memcpy(new_mpath->dst, dst, ETH_ALEN); new_mpath->dev = dev; new_mpath->flags = 0; skb_queue_head_init(&new_mpath->frame_queue); - new_node = kmalloc(sizeof(struct mpath_node), GFP_KERNEL); new_node->mpath = new_mpath; new_mpath->timer.data = (unsigned long) new_mpath; new_mpath->timer.function = mesh_path_timer; @@ -202,7 +208,6 @@ int mesh_path_add(u8 *dst, struct net_device *dev) endadd: spin_unlock(&mesh_paths->hashwlock[hash_idx]); -endadd2: read_unlock(&pathtbl_resize_lock); if (!err && grow) { struct mesh_table *oldtbl, *newtbl; @@ -215,10 +220,12 @@ endadd2: return -ENOMEM; } rcu_assign_pointer(mesh_paths, newtbl); + write_unlock(&pathtbl_resize_lock); + synchronize_rcu(); mesh_table_free(oldtbl, false); - write_unlock(&pathtbl_resize_lock); } +endadd2: return err; } diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index a5e5c31c23abf3d23bca0d0ce9186e1776249215..4adba09e80ca8d23fe8c3b15112ca7e183a86d75 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -665,6 +665,26 @@ static void ieee80211_authenticate(struct net_device *dev, mod_timer(&ifsta->timer, jiffies + IEEE80211_AUTH_TIMEOUT); } +static int ieee80211_compatible_rates(struct ieee80211_sta_bss *bss, + struct ieee80211_supported_band *sband, + u64 *rates) +{ + int i, j, count; + *rates = 0; + count = 0; + for (i = 0; i < bss->supp_rates_len; i++) { + int rate = (bss->supp_rates[i] & 0x7F) * 5; + + for (j = 0; j < sband->n_bitrates; j++) + if (sband->bitrates[j].bitrate == rate) { + *rates |= BIT(j); + count++; + break; + } + } + + return count; +} static void ieee80211_send_assoc(struct net_device *dev, struct ieee80211_if_sta *ifsta) @@ -673,11 +693,12 @@ static void ieee80211_send_assoc(struct net_device *dev, struct sk_buff *skb; struct ieee80211_mgmt *mgmt; u8 *pos, *ies; - int i, len; + int i, len, count, rates_len, supp_rates_len; u16 capab; struct ieee80211_sta_bss *bss; int wmm = 0; struct ieee80211_supported_band *sband; + u64 rates = 0; skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) + 200 + ifsta->extra_ie_len + @@ -740,24 +761,39 @@ static void ieee80211_send_assoc(struct net_device *dev, *pos++ = ifsta->ssid_len; memcpy(pos, ifsta->ssid, ifsta->ssid_len); + /* all supported rates should be added here but some APs + * (e.g. D-Link DAP 1353 in b-only mode) don't like that + * Therefore only add rates the AP supports */ + rates_len = ieee80211_compatible_rates(bss, sband, &rates); + supp_rates_len = rates_len; + if (supp_rates_len > 8) + supp_rates_len = 8; + len = sband->n_bitrates; - if (len > 8) - len = 8; - pos = skb_put(skb, len + 2); + pos = skb_put(skb, supp_rates_len + 2); *pos++ = WLAN_EID_SUPP_RATES; - *pos++ = len; - for (i = 0; i < len; i++) { - int rate = sband->bitrates[i].bitrate; - *pos++ = (u8) (rate / 5); - } + *pos++ = supp_rates_len; - if (sband->n_bitrates > len) { - pos = skb_put(skb, sband->n_bitrates - len + 2); - *pos++ = WLAN_EID_EXT_SUPP_RATES; - *pos++ = sband->n_bitrates - len; - for (i = len; i < sband->n_bitrates; i++) { + count = 0; + for (i = 0; i < sband->n_bitrates; i++) { + if (BIT(i) & rates) { int rate = sband->bitrates[i].bitrate; *pos++ = (u8) (rate / 5); + if (++count == 8) + break; + } + } + + if (count == 8) { + pos = skb_put(skb, rates_len - count + 2); + *pos++ = WLAN_EID_EXT_SUPP_RATES; + *pos++ = rates_len - count; + + for (i++; i < sband->n_bitrates; i++) { + if (BIT(i) & rates) { + int rate = sband->bitrates[i].bitrate; + *pos++ = (u8) (rate / 5); + } } } diff --git a/net/mac80211/rc80211_pid_debugfs.c b/net/mac80211/rc80211_pid_debugfs.c index ae75d417873988c3b9edcaff38d83b8d97af2153..ff5c380f3c1343805108b1d561ed931161a8e20e 100644 --- a/net/mac80211/rc80211_pid_debugfs.c +++ b/net/mac80211/rc80211_pid_debugfs.c @@ -85,7 +85,7 @@ static int rate_control_pid_events_open(struct inode *inode, struct file *file) struct rc_pid_sta_info *sinfo = inode->i_private; struct rc_pid_event_buffer *events = &sinfo->events; struct rc_pid_events_file_info *file_info; - unsigned int status; + unsigned long status; /* Allocate a state struct */ file_info = kmalloc(sizeof(*file_info), GFP_KERNEL); @@ -135,7 +135,7 @@ static ssize_t rate_control_pid_events_read(struct file *file, char __user *buf, char pb[RC_PID_PRINT_BUF_SIZE]; int ret; int p; - unsigned int status; + unsigned long status; /* Check if there is something to read. */ if (events->next_entry == file_info->next_entry) { diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 02f436a86061a33c99c3c38dc4787b03d27c6c39..1958bfb361c676f34f734065ddf6e66d4be96ac0 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1305,11 +1305,11 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) if (is_multicast_ether_addr(skb->data)) { if (*mesh_ttl > 0) { xmit_skb = skb_copy(skb, GFP_ATOMIC); - if (!xmit_skb && net_ratelimit()) + if (xmit_skb) + xmit_skb->pkt_type = PACKET_OTHERHOST; + else if (net_ratelimit()) printk(KERN_DEBUG "%s: failed to clone " "multicast frame\n", dev->name); - else - xmit_skb->pkt_type = PACKET_OTHERHOST; } else IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.sta, dropped_frames_ttl); @@ -1395,7 +1395,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) padding = ((4 - subframe_len) & 0x3); /* the last MSDU has no padding */ if (subframe_len > remaining) { - printk(KERN_DEBUG "%s: wrong buffer size", dev->name); + printk(KERN_DEBUG "%s: wrong buffer size\n", dev->name); return RX_DROP_UNUSABLE; } @@ -1418,7 +1418,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) eth = (struct ethhdr *) skb_pull(skb, ntohs(len) + padding); if (!eth) { - printk(KERN_DEBUG "%s: wrong buffer size ", + printk(KERN_DEBUG "%s: wrong buffer size\n", dev->name); dev_kfree_skb(frame); return RX_DROP_UNUSABLE; @@ -1952,7 +1952,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, if (!skb_new) { if (net_ratelimit()) printk(KERN_DEBUG "%s: failed to copy " - "multicast frame for %s", + "multicast frame for %s\n", wiphy_name(local->hw.wiphy), prev->dev->name); continue; diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index f35eaea98e7316bcac44b45adb0d210ca3ad551e..1d7dd54aacef31120fa744bef928bd7075ad72c2 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1562,13 +1562,13 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, * be cloned. This could happen, e.g., with Linux bridge code passing * us broadcast frames. */ - if (head_need > 0 || skb_cloned(skb)) { + if (head_need > 0 || skb_header_cloned(skb)) { #if 0 printk(KERN_DEBUG "%s: need to reallocate buffer for %d bytes " "of headroom\n", dev->name, head_need); #endif - if (skb_cloned(skb)) + if (skb_header_cloned(skb)) I802_DEBUG_INC(local->tx_expand_skb_head_cloned); else I802_DEBUG_INC(local->tx_expand_skb_head); @@ -1898,6 +1898,7 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, control->flags |= IEEE80211_TXCTL_SHORT_PREAMBLE; control->antenna_sel_tx = local->hw.conf.antenna_sel_tx; control->flags |= IEEE80211_TXCTL_NO_ACK; + control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT; control->retry_limit = 1; control->flags |= IEEE80211_TXCTL_CLEAR_PS_FILT; } diff --git a/net/mac80211/util.c b/net/mac80211/util.c index cc9f715c7bfc5bce2a8caf90248bddd64b1f07f7..24a465c4df099aa81dee13ce5f24f53035e2e6f4 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -153,15 +153,15 @@ int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr) /* 7.1.3.5a.2 */ switch (ae) { case 0: - return 5; + return 6; case 1: - return 11; + return 12; case 2: - return 17; + return 18; case 3: - return 23; + return 24; default: - return 5; + return 6; } } diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index 64faa3dc488f70d2cfb09fae1bb1c3470424153e..dc1598b86004e9df03e4eefb188b17ca292171b9 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c @@ -394,7 +394,8 @@ static int wme_qdiscop_init(struct Qdisc *qd, struct nlattr *opt) qd->handle); if (!q->queues[i]) { q->queues[i] = &noop_qdisc; - printk(KERN_ERR "%s child qdisc %i creation failed", dev->name, i); + printk(KERN_ERR "%s child qdisc %i creation failed\n", + dev->name, i); } } diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index c1fc0f1a641c622abd6ad7c9c2640e6eec38f16e..aa8d80c35e28c41daba4f1187fd45b59d549cc4c 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig @@ -90,6 +90,7 @@ config NF_CT_PROTO_DCCP tristate 'DCCP protocol connection tracking support (EXPERIMENTAL)' depends on EXPERIMENTAL && NF_CONNTRACK depends on NETFILTER_ADVANCED + default IP_DCCP help With this option enabled, the layer 3 independent connection tracking code will be able to do state tracking on DCCP connections. @@ -104,6 +105,7 @@ config NF_CT_PROTO_SCTP tristate 'SCTP protocol connection tracking support (EXPERIMENTAL)' depends on EXPERIMENTAL && NF_CONNTRACK depends on NETFILTER_ADVANCED + default IP_SCTP help With this option enabled, the layer 3 independent connection tracking code will be able to do state tracking on SCTP connections. @@ -532,6 +534,7 @@ config NETFILTER_XT_MATCH_DCCP tristate '"dccp" protocol match support' depends on NETFILTER_XTABLES depends on NETFILTER_ADVANCED + default IP_DCCP help With this option enabled, you will be able to use the iptables `dccp' match in order to match on DCCP source/destination ports @@ -725,6 +728,7 @@ config NETFILTER_XT_MATCH_SCTP tristate '"sctp" protocol match support (EXPERIMENTAL)' depends on NETFILTER_XTABLES && EXPERIMENTAL depends on NETFILTER_ADVANCED + default IP_SCTP help With this option enabled, you will be able to use the `sctp' match in order to match on SCTP source/destination ports diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 16774ecd1c4efca903d8c03e9af700d73a053d21..0edefcfc5949ccf500db459bd57297819c06749b 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -472,6 +472,9 @@ static int ctnetlink_conntrack_event(struct notifier_block *this, goto nla_put_failure; nla_nest_end(skb, nest_parms); + if (ctnetlink_dump_id(skb, ct) < 0) + goto nla_put_failure; + if (events & IPCT_DESTROY) { if (ctnetlink_dump_counters(skb, ct, IP_CT_DIR_ORIGINAL) < 0 || ctnetlink_dump_counters(skb, ct, IP_CT_DIR_REPLY) < 0) diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c index 9f4900069561547772d04ca232f36f720605fcee..2f9bbc058b487bede799f9cf2e69e7554aa0a63d 100644 --- a/net/netfilter/nf_conntrack_sip.c +++ b/net/netfilter/nf_conntrack_sip.c @@ -870,6 +870,7 @@ static int process_sdp(struct sk_buff *skb, { enum ip_conntrack_info ctinfo; struct nf_conn *ct = nf_ct_get(skb, &ctinfo); + struct nf_conn_help *help = nfct_help(ct); unsigned int matchoff, matchlen; unsigned int mediaoff, medialen; unsigned int sdpoff; @@ -959,6 +960,9 @@ static int process_sdp(struct sk_buff *skb, if (nf_nat_sdp_session && ct->status & IPS_NAT_MASK) ret = nf_nat_sdp_session(skb, dptr, sdpoff, datalen, &rtp_addr); + if (ret == NF_ACCEPT && i > 0) + help->help.ct_sip_info.invite_cseq = cseq; + return ret; } static int process_invite_response(struct sk_buff *skb, @@ -967,14 +971,14 @@ static int process_invite_response(struct sk_buff *skb, { enum ip_conntrack_info ctinfo; struct nf_conn *ct = nf_ct_get(skb, &ctinfo); + struct nf_conn_help *help = nfct_help(ct); if ((code >= 100 && code <= 199) || (code >= 200 && code <= 299)) return process_sdp(skb, dptr, datalen, cseq); - else { + else if (help->help.ct_sip_info.invite_cseq == cseq) flush_expectations(ct, true); - return NF_ACCEPT; - } + return NF_ACCEPT; } static int process_update_response(struct sk_buff *skb, @@ -983,14 +987,14 @@ static int process_update_response(struct sk_buff *skb, { enum ip_conntrack_info ctinfo; struct nf_conn *ct = nf_ct_get(skb, &ctinfo); + struct nf_conn_help *help = nfct_help(ct); if ((code >= 100 && code <= 199) || (code >= 200 && code <= 299)) return process_sdp(skb, dptr, datalen, cseq); - else { + else if (help->help.ct_sip_info.invite_cseq == cseq) flush_expectations(ct, true); - return NF_ACCEPT; - } + return NF_ACCEPT; } static int process_prack_response(struct sk_buff *skb, @@ -999,14 +1003,14 @@ static int process_prack_response(struct sk_buff *skb, { enum ip_conntrack_info ctinfo; struct nf_conn *ct = nf_ct_get(skb, &ctinfo); + struct nf_conn_help *help = nfct_help(ct); if ((code >= 100 && code <= 199) || (code >= 200 && code <= 299)) return process_sdp(skb, dptr, datalen, cseq); - else { + else if (help->help.ct_sip_info.invite_cseq == cseq) flush_expectations(ct, true); - return NF_ACCEPT; - } + return NF_ACCEPT; } static int process_bye_request(struct sk_buff *skb, diff --git a/net/netfilter/xt_iprange.c b/net/netfilter/xt_iprange.c index 500528d60cd7a571cbdacc762e0b6f8f775d53ef..c63e9333c7550a04971084b3f688d8fe295919ea 100644 --- a/net/netfilter/xt_iprange.c +++ b/net/netfilter/xt_iprange.c @@ -179,3 +179,5 @@ module_exit(iprange_mt_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Jozsef Kadlecsik , Jan Engelhardt "); MODULE_DESCRIPTION("Xtables: arbitrary IPv4 range matching"); +MODULE_ALIAS("ipt_iprange"); +MODULE_ALIAS("ip6t_iprange"); diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 25070240d4ae79aa94e23bcde07ef81291849a4a..2cee87da44411f12f24683611c7027bc01c7774a 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -743,7 +743,7 @@ static int packet_sendmsg(struct kiocb *iocb, struct socket *sock, if (len > dev->mtu+reserve) goto out_unlock; - skb = sock_alloc_send_skb(sk, len + LL_RESERVED_SPACE(dev), + skb = sock_alloc_send_skb(sk, len + LL_ALLOCATED_SPACE(dev), msg->msg_flags & MSG_DONTWAIT, &err); if (skb==NULL) goto out_unlock; diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c index 64b2d136c78e9ac1cf370e3289bed361de9995ff..1d421d059caf48aa7f2327acf0c011355deaf534 100644 --- a/net/sched/act_simple.c +++ b/net/sched/act_simple.c @@ -6,7 +6,7 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * - * Authors: Jamal Hadi Salim (2005) + * Authors: Jamal Hadi Salim (2005-8) * */ @@ -34,6 +34,7 @@ static struct tcf_hashinfo simp_hash_info = { .lock = &simp_lock, }; +#define SIMP_MAX_DATA 32 static int tcf_simp(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res) { struct tcf_defact *d = a->priv; @@ -69,23 +70,28 @@ static int tcf_simp_release(struct tcf_defact *d, int bind) return ret; } -static int alloc_defdata(struct tcf_defact *d, u32 datalen, void *defdata) +static int alloc_defdata(struct tcf_defact *d, char *defdata) { - d->tcfd_defdata = kmemdup(defdata, datalen, GFP_KERNEL); + d->tcfd_defdata = kstrndup(defdata, SIMP_MAX_DATA, GFP_KERNEL); if (unlikely(!d->tcfd_defdata)) return -ENOMEM; - d->tcfd_datalen = datalen; + return 0; } -static int realloc_defdata(struct tcf_defact *d, u32 datalen, void *defdata) +static void reset_policy(struct tcf_defact *d, char *defdata, + struct tc_defact *p) { - kfree(d->tcfd_defdata); - return alloc_defdata(d, datalen, defdata); + spin_lock_bh(&d->tcf_lock); + d->tcf_action = p->action; + memset(d->tcfd_defdata, 0, SIMP_MAX_DATA); + strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA); + spin_unlock_bh(&d->tcf_lock); } static const struct nla_policy simple_policy[TCA_DEF_MAX + 1] = { [TCA_DEF_PARMS] = { .len = sizeof(struct tc_defact) }, + [TCA_DEF_DATA] = { .type = NLA_STRING, .len = SIMP_MAX_DATA }, }; static int tcf_simp_init(struct nlattr *nla, struct nlattr *est, @@ -95,28 +101,24 @@ static int tcf_simp_init(struct nlattr *nla, struct nlattr *est, struct tc_defact *parm; struct tcf_defact *d; struct tcf_common *pc; - void *defdata; - u32 datalen = 0; + char *defdata; int ret = 0, err; if (nla == NULL) return -EINVAL; - err = nla_parse_nested(tb, TCA_DEF_MAX, nla, NULL); + err = nla_parse_nested(tb, TCA_DEF_MAX, nla, simple_policy); if (err < 0) return err; if (tb[TCA_DEF_PARMS] == NULL) return -EINVAL; - parm = nla_data(tb[TCA_DEF_PARMS]); - defdata = nla_data(tb[TCA_DEF_DATA]); - if (defdata == NULL) + if (tb[TCA_DEF_DATA] == NULL) return -EINVAL; - datalen = nla_len(tb[TCA_DEF_DATA]); - if (datalen == 0) - return -EINVAL; + parm = nla_data(tb[TCA_DEF_PARMS]); + defdata = nla_data(tb[TCA_DEF_DATA]); pc = tcf_hash_check(parm->index, a, bind, &simp_hash_info); if (!pc) { @@ -126,11 +128,12 @@ static int tcf_simp_init(struct nlattr *nla, struct nlattr *est, return -ENOMEM; d = to_defact(pc); - ret = alloc_defdata(d, datalen, defdata); + ret = alloc_defdata(d, defdata); if (ret < 0) { kfree(pc); return ret; } + d->tcf_action = parm->action; ret = ACT_P_CREATED; } else { d = to_defact(pc); @@ -138,13 +141,9 @@ static int tcf_simp_init(struct nlattr *nla, struct nlattr *est, tcf_simp_release(d, bind); return -EEXIST; } - realloc_defdata(d, datalen, defdata); + reset_policy(d, defdata, parm); } - spin_lock_bh(&d->tcf_lock); - d->tcf_action = parm->action; - spin_unlock_bh(&d->tcf_lock); - if (ret == ACT_P_CREATED) tcf_hash_insert(pc, &simp_hash_info); return ret; @@ -172,7 +171,7 @@ static inline int tcf_simp_dump(struct sk_buff *skb, struct tc_action *a, opt.bindcnt = d->tcf_bindcnt - bind; opt.action = d->tcf_action; NLA_PUT(skb, TCA_DEF_PARMS, sizeof(opt), &opt); - NLA_PUT(skb, TCA_DEF_DATA, d->tcfd_datalen, d->tcfd_defdata); + NLA_PUT_STRING(skb, TCA_DEF_DATA, d->tcfd_defdata); t.install = jiffies_to_clock_t(jiffies - d->tcf_tm.install); t.lastuse = jiffies_to_clock_t(jiffies - d->tcf_tm.lastuse); t.expires = jiffies_to_clock_t(d->tcf_tm.expires); diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index 66148cc4759ee862a848a1d802d04e13dd89b290..5bc1ed4901800af63fc1255ba1f5eecbbe8368de 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c @@ -1197,12 +1197,16 @@ static inline int htb_parent_last_child(struct htb_class *cl) return 1; } -static void htb_parent_to_leaf(struct htb_class *cl, struct Qdisc *new_q) +static void htb_parent_to_leaf(struct htb_sched *q, struct htb_class *cl, + struct Qdisc *new_q) { struct htb_class *parent = cl->parent; BUG_TRAP(!cl->level && cl->un.leaf.q && !cl->prio_activity); + if (parent->cmode != HTB_CAN_SEND) + htb_safe_rb_erase(&parent->pq_node, q->wait_pq + parent->level); + parent->level = 0; memset(&parent->un.inner, 0, sizeof(parent->un.inner)); INIT_LIST_HEAD(&parent->un.leaf.drop_list); @@ -1300,7 +1304,7 @@ static int htb_delete(struct Qdisc *sch, unsigned long arg) htb_deactivate(q, cl); if (last_child) - htb_parent_to_leaf(cl, new_q); + htb_parent_to_leaf(q, cl, new_q); if (--cl->refcnt == 0) htb_destroy_class(sch, cl); diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 81b606424e122a2f033fba1d8ddb0839d3dd01f4..bbc7107c86cf90003d31ee70a11580b6fef48114 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c @@ -2418,7 +2418,8 @@ static int sctp_process_param(struct sctp_association *asoc, break; case SCTP_PARAM_IPV6_ADDRESS: - asoc->peer.ipv6_address = 1; + if (PF_INET6 == asoc->base.sk->sk_family) + asoc->peer.ipv6_address = 1; break; case SCTP_PARAM_HOST_NAME_ADDRESS: @@ -2829,6 +2830,19 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc, addr_param = (union sctp_addr_param *) ((void *)asconf_param + sizeof(sctp_addip_param_t)); + switch (addr_param->v4.param_hdr.type) { + case SCTP_PARAM_IPV6_ADDRESS: + if (!asoc->peer.ipv6_address) + return SCTP_ERROR_INV_PARAM; + break; + case SCTP_PARAM_IPV4_ADDRESS: + if (!asoc->peer.ipv4_address) + return SCTP_ERROR_INV_PARAM; + break; + default: + return SCTP_ERROR_INV_PARAM; + } + af = sctp_get_af_specific(param_type2af(addr_param->v4.param_hdr.type)); if (unlikely(!af)) return SCTP_ERROR_INV_PARAM; diff --git a/net/sunrpc/auth_generic.c b/net/sunrpc/auth_generic.c index d927d9f574121f94d9477cda3670e960f8f147c7..744b79fdcb19dac256b1dea5b26dc6e87f208f07 100644 --- a/net/sunrpc/auth_generic.c +++ b/net/sunrpc/auth_generic.c @@ -17,8 +17,8 @@ # define RPCDBG_FACILITY RPCDBG_AUTH #endif -#define RPC_ANONYMOUS_USERID ((uid_t)-2) -#define RPC_ANONYMOUS_GROUPID ((gid_t)-2) +#define RPC_MACHINE_CRED_USERID ((uid_t)0) +#define RPC_MACHINE_CRED_GROUPID ((gid_t)0) struct generic_cred { struct rpc_cred gc_base; @@ -44,8 +44,8 @@ EXPORT_SYMBOL_GPL(rpc_lookup_cred); struct rpc_cred *rpc_lookup_machine_cred(void) { struct auth_cred acred = { - .uid = RPC_ANONYMOUS_USERID, - .gid = RPC_ANONYMOUS_GROUPID, + .uid = RPC_MACHINE_CRED_USERID, + .gid = RPC_MACHINE_CRED_GROUPID, .machine_cred = 1, }; diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index d74c2d269539a03a4267dcc93d195ca20e68d522..01c7e311b904597e826b1da925a03c888aa090f7 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include diff --git a/net/tipc/core.h b/net/tipc/core.h index 325404fd4eb5efaebe86109333b9ebc715593762..5a0e4878d3b72b7c44cfd7b81cb88117b691029b 100644 --- a/net/tipc/core.h +++ b/net/tipc/core.h @@ -279,15 +279,14 @@ static inline void k_term_timer(struct timer_list *timer) /* * TIPC message buffer code * - * TIPC message buffer headroom reserves space for a link-level header - * (in case the message is sent off-node), - * while ensuring TIPC header is word aligned for quicker access + * TIPC message buffer headroom reserves space for the worst-case + * link-level device header (in case the message is sent off-node). * - * The largest header currently supported is 18 bytes, which is used when - * the standard 14 byte Ethernet header has 4 added bytes for VLAN info + * Note: Headroom should be a multiple of 4 to ensure the TIPC header fields + * are word aligned for quicker access */ -#define BUF_HEADROOM 20u +#define BUF_HEADROOM LL_MAX_HEADER struct tipc_skb_cb { void *handle; diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c index 09cd9c0c2d805bcac6f742d5a3ef8945502fe223..3f964db908a71466e77949568d6ea672c63f281c 100644 --- a/net/xfrm/xfrm_output.c +++ b/net/xfrm/xfrm_output.c @@ -25,11 +25,11 @@ static int xfrm_state_check_space(struct xfrm_state *x, struct sk_buff *skb) struct dst_entry *dst = skb->dst; int nhead = dst->header_len + LL_RESERVED_SPACE(dst->dev) - skb_headroom(skb); + int ntail = dst->dev->needed_tailroom - skb_tailroom(skb); - if (nhead > 0) - return pskb_expand_head(skb, nhead, 0, GFP_ATOMIC); + if (nhead > 0 || ntail > 0) + return pskb_expand_head(skb, nhead, ntail, GFP_ATOMIC); - /* Check tail too... */ return 0; } diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index 5d20a2e24cd1e18814483327645f25b6c2f73d0e..ad2434b26970c17b4b72efb82761afd0ac04042d 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -108,6 +108,9 @@ static int read_symbol(FILE *in, struct sym_entry *s) /* exclude also MIPS ELF local symbols ($L123 instead of .L123) */ else if (str[0] == '$') return -1; + /* exclude debugging symbols */ + else if (stype == 'N') + return -1; /* include the type field in the symbol name, so that it gets * compressed together */ diff --git a/scripts/kconfig/util.c b/scripts/kconfig/util.c index f8e73c039dc880984f96aa8cadd4e43edaa6baba..3cc9f93690362ec220bb97a9d68b35cf74207dce 100644 --- a/scripts/kconfig/util.c +++ b/scripts/kconfig/util.c @@ -77,7 +77,7 @@ struct gstr str_new(void) { struct gstr gs; gs.s = malloc(sizeof(char) * 64); - gs.len = 16; + gs.len = 64; strcpy(gs.s, "\0"); return gs; } diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 83cee18a02e922130fae1bf9d8dff87d4f6169d8..88e3934a8b8c86f6e5962ac64acb36ab7d0c08dd 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1556,7 +1556,9 @@ sub create_parameterlist($$$) { push_parameter($2, "$type $1", $file); } elsif ($param =~ m/(.*?):(\d+)/) { - push_parameter($1, "$type:$2", $file) + if ($type ne "") { # skip unnamed bit-fields + push_parameter($1, "$type:$2", $file) + } } else { push_parameter($param, $type, $file); diff --git a/scripts/mksysmap b/scripts/mksysmap index 4390fab9f5bdf40576abf6be54de67207969ae42..6e133a0bae7a8db162a5233fbf4af319f5ede35f 100644 --- a/scripts/mksysmap +++ b/scripts/mksysmap @@ -32,6 +32,7 @@ # For System.map filter away: # a - local absolute symbols # U - undefined global symbols +# N - debugging symbols # w - local weak symbols # readprofile starts reading symbols when _stext is found, and @@ -40,5 +41,5 @@ # so we just ignore them to let readprofile continue to work. # (At least sparc64 has __crc_ in the middle). -$NM -n $1 | grep -v '\( [aUw] \)\|\(__crc_\)\|\( \$[adt]\)' > $2 +$NM -n $1 | grep -v '\( [aNUw] \)\|\(__crc_\)\|\( \$[adt]\)' > $2 diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 757294b4f3222d28dfeef6415f9784a497b23c84..508c5895c6808880be73eda7c087e70c48348b80 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -721,7 +721,7 @@ static int check_section(const char *modname, const char *sec) /* consume all digits */ while (*e && e != sec && isdigit(*e)) e--; - if (*e == '.') { + if (*e == '.' && !strstr(sec, ".linkonce")) { warn("%s (%s): unexpected section name.\n" "The (.[number]+) following section name are " "ld generated and not expected.\n" diff --git a/sound/Kconfig b/sound/Kconfig index b2a2db47aff54820e02a635655f4c06ce8a92b1a..4247406160e7ef7c5684943a9c3065e1ec73eb9a 100644 --- a/sound/Kconfig +++ b/sound/Kconfig @@ -28,11 +28,6 @@ config SOUND and read ; the module will be called soundcore. - I'm told that even without a sound card, you can make your computer - say more than an occasional beep, by programming the PC speaker. - Kernel patches and supporting utilities to do that are in the pcsp - package, available at . - source "sound/oss/dmasound/Kconfig" if !M68K diff --git a/sound/drivers/Kconfig b/sound/drivers/Kconfig index a78a8d045175bb65b4dc576612e289b36957b898..602b58e3b55d198914f047c6d806871abfddd00e 100644 --- a/sound/drivers/Kconfig +++ b/sound/drivers/Kconfig @@ -5,9 +5,10 @@ menu "Generic devices" config SND_PCSP - tristate "Internal PC speaker support" - depends on X86_PC && HIGH_RES_TIMERS + tristate "PC-Speaker support (READ HELP!)" + depends on PCSPKR_PLATFORM && X86_PC && HIGH_RES_TIMERS depends on INPUT + depends on EXPERIMENTAL depends on SND select SND_PCM help @@ -18,11 +19,21 @@ config SND_PCSP You can compile this as a module which will be called snd-pcsp. + WARNING: if you already have a soundcard, enabling this + driver may lead to a problem. Namely, it may get loaded + before the other sound driver of yours, making the + pc-speaker a default sound device. Which is likely not + what you want. To make this driver play nicely with other + sound driver, you can add this into your /etc/modprobe.conf: + options snd-pcsp index=2 + You don't need this driver if you only want your pc-speaker to beep. You don't need this driver if you have a tablet piezo beeper in your PC instead of the real speaker. - It should not hurt to say Y or M here in all other cases. + Say N if you have a sound card. + Say M if you don't. + Say Y only if you really know what you do. config SND_MPU401_UART tristate diff --git a/sound/drivers/pcsp/pcsp_lib.c b/sound/drivers/pcsp/pcsp_lib.c index ac6238e93513b3080389f0e5a0e1f348c5c0c89d..7ad4a1534b2bf7e7099c6442950f7a20a58f99dd 100644 --- a/sound/drivers/pcsp/pcsp_lib.c +++ b/sound/drivers/pcsp/pcsp_lib.c @@ -18,6 +18,8 @@ module_param(nforce_wa, bool, 0444); MODULE_PARM_DESC(nforce_wa, "Apply NForce chipset workaround " "(expect bad sound)"); +#define DMIX_WANTS_S16 1 + static void pcsp_start_timer(unsigned long dummy) { hrtimer_start(&pcsp_chip.timer, ktime_set(0, 0), HRTIMER_MODE_REL); @@ -47,7 +49,7 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) { unsigned long flags; unsigned char timer_cnt, val; - int periods_elapsed; + int fmt_size, periods_elapsed; u64 ns; size_t period_bytes, buffer_bytes; struct snd_pcm_substream *substream; @@ -92,8 +94,11 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) goto exit_nr_unlock2; runtime = substream->runtime; - /* assume it is u8 mono */ - val = runtime->dma_area[chip->playback_ptr]; + fmt_size = snd_pcm_format_physical_width(runtime->format) >> 3; + /* assume it is mono! */ + val = runtime->dma_area[chip->playback_ptr + fmt_size - 1]; + if (snd_pcm_format_signed(runtime->format)) + val ^= 0x80; timer_cnt = val * CUR_DIV() / 256; if (timer_cnt && chip->enable) { @@ -111,12 +116,14 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) period_bytes = snd_pcm_lib_period_bytes(substream); buffer_bytes = snd_pcm_lib_buffer_bytes(substream); - chip->playback_ptr += PCSP_INDEX_INC(); + chip->playback_ptr += PCSP_INDEX_INC() * fmt_size; periods_elapsed = chip->playback_ptr - chip->period_ptr; if (periods_elapsed < 0) { - printk(KERN_WARNING "PCSP: playback_ptr inconsistent " +#if PCSP_DEBUG + printk(KERN_INFO "PCSP: buffer_bytes mod period_bytes != 0 ? " "(%zi %zi %zi)\n", chip->playback_ptr, period_bytes, buffer_bytes); +#endif periods_elapsed += buffer_bytes; } periods_elapsed /= period_bytes; @@ -270,7 +277,11 @@ static struct snd_pcm_hardware snd_pcsp_playback = { .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_HALF_DUPLEX | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID), - .formats = SNDRV_PCM_FMTBIT_U8, + .formats = (SNDRV_PCM_FMTBIT_U8 +#if DMIX_WANTS_S16 + | SNDRV_PCM_FMTBIT_S16_LE +#endif + ), .rates = SNDRV_PCM_RATE_KNOT, .rate_min = PCSP_DEFAULT_SRATE, .rate_max = PCSP_DEFAULT_SRATE, diff --git a/sound/oss/kahlua.c b/sound/oss/kahlua.c index dfe670f12e67d71117904db746c2a2b8e87af10d..eb9bc365530dde4107f1cf4f9de102bd66dac59b 100644 --- a/sound/oss/kahlua.c +++ b/sound/oss/kahlua.c @@ -67,7 +67,7 @@ static int __devinit probe_one(struct pci_dev *pdev, const struct pci_device_id return 1; mem = ioremap(base, 128); - if(mem == 0UL) + if (!mem) return 1; map = readw(mem + 0x18); /* Read the SMI enables */ iounmap(mem); diff --git a/sound/soc/at91/at91-pcm.c b/sound/soc/at91/at91-pcm.c index 67c88e322fb1259b5ab265cc385bb0e3a6e31f10..ccac6bd2889c0f56589f2234aa899aeb42b42ff0 100644 --- a/sound/soc/at91/at91-pcm.c +++ b/sound/soc/at91/at91-pcm.c @@ -103,7 +103,8 @@ static void at91_pcm_dma_irq(u32 ssc_sr, if (prtd->period_ptr >= prtd->dma_buffer_end) { prtd->period_ptr = prtd->dma_buffer; } - at91_ssc_write(params->ssc_base + params->pdc->xnpr, prtd->period_ptr); + at91_ssc_write(params->ssc_base + params->pdc->xnpr, + prtd->period_ptr); at91_ssc_write(params->ssc_base + params->pdc->xncr, prtd->period_size / params->pdc_xfer_size); } @@ -191,10 +192,12 @@ static int at91_pcm_trigger(struct snd_pcm_substream *substream, at91_ssc_write(params->ssc_base + AT91_SSC_IER, params->mask->ssc_endx | params->mask->ssc_endbuf); - at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR, params->mask->pdc_enable); + at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR, + params->mask->pdc_enable); - DBG("sr=%lx imr=%lx\n", at91_ssc_read(params->ssc_base + AT91_SSC_SR), - at91_ssc_read(params->ssc_base + AT91_SSC_IER)); + DBG("sr=%lx imr=%lx\n", + at91_ssc_read(params->ssc_base + AT91_SSC_SR), + at91_ssc_read(params->ssc_base + AT91_SSC_IMR)); break; case SNDRV_PCM_TRIGGER_STOP: diff --git a/sound/soc/at91/at91-ssc.c b/sound/soc/at91/at91-ssc.c index f642d2dd4ec310119deabca184dea7cad7a4c481..bc35d00a38f86b89778bd86953a165d4075dfef2 100644 --- a/sound/soc/at91/at91-ssc.c +++ b/sound/soc/at91/at91-ssc.c @@ -590,7 +590,7 @@ static int at91_ssc_hw_params(struct snd_pcm_substream *substream, printk(KERN_WARNING "at91-ssc: request_irq failure\n"); DBG("Stopping pid %d clock\n", ssc_p->ssc.pid); - at91_sys_write(AT91_PMC_PCER, 1<ssc.pid); + at91_sys_write(AT91_PMC_PCDR, 1<ssc.pid); return ret; } diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 630684f4a0bc5ec1c91741902d9b8d7d3bcc1fa9..09b1661b8a3a3930720947d91cf9a582b642cb0f 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -539,8 +539,8 @@ static const char *intercon[][3] = { {"HPRCOM", NULL, "Right HP Com"}, /* Mono Output */ - {"MONOLOUT", NULL, "Mono Out"}, - {"MONOLOUT", NULL, "Mono Out"}, + {"MONO_LOUT", NULL, "Mono Out"}, + {"MONO_LOUT", NULL, "Mono Out"}, /* Left Input */ {"Left Line1L Mux", "single-ended", "LINE1L"}, diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index b2a11b0d2e4c3b9cb6eb17c1dee1ec1743aec48a..f588545698f3687f75941977b8e597791c964e9e 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -416,7 +416,7 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd) * to put data into its FIFO. Without it, ALSA starts * to complain about overruns. */ - msleep(1); + mdelay(1); } break; diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c index 83b1eb4e40f3f6046e6987de1bc4086264c56034..6533563a6011d01ccb71084c136f79d7a1b808d6 100644 --- a/sound/soc/omap/n810.c +++ b/sound/soc/omap/n810.c @@ -188,8 +188,8 @@ static const char *audio_map[][3] = { static const char *spk_function[] = {"Off", "On"}; static const char *jack_function[] = {"Off", "Headphone"}; static const struct soc_enum n810_enum[] = { - SOC_ENUM_SINGLE_EXT(2, spk_function), - SOC_ENUM_SINGLE_EXT(3, jack_function), + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spk_function), spk_function), + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(jack_function), jack_function), }; static const struct snd_kcontrol_new aic33_n810_controls[] = { diff --git a/sound/synth/emux/emux_synth.c b/sound/synth/emux/emux_synth.c index 478369bb38c34118701f08966c0cf2b96f2beab4..b343818dbb964ae3137b7e90c08284ffa03e92c6 100644 --- a/sound/synth/emux/emux_synth.c +++ b/sound/synth/emux/emux_synth.c @@ -341,8 +341,12 @@ snd_emux_control(void *p, int type, struct snd_midi_channel *chan) case MIDI_CTL_SOFT_PEDAL: #ifdef SNDRV_EMUX_USE_RAW_EFFECT /* FIXME: this is an emulation */ - snd_emux_send_effect(port, chan, EMUX_FX_CUTOFF, -160, + if (chan->control[type] >= 64) + snd_emux_send_effect(port, chan, EMUX_FX_CUTOFF, -160, EMUX_FX_FLAG_ADD); + else + snd_emux_send_effect(port, chan, EMUX_FX_CUTOFF, 0, + EMUX_FX_FLAG_OFF); #endif break; diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index f7ba099049eaeab16caf69d6bed1afc280a4a712..2d29e260da3d1b56830794c8dfb1719119195086 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -758,25 +758,26 @@ void mark_page_dirty(struct kvm *kvm, gfn_t gfn) */ void kvm_vcpu_block(struct kvm_vcpu *vcpu) { - DECLARE_WAITQUEUE(wait, current); - - add_wait_queue(&vcpu->wq, &wait); - - /* - * We will block until either an interrupt or a signal wakes us up - */ - while (!kvm_cpu_has_interrupt(vcpu) - && !kvm_cpu_has_pending_timer(vcpu) - && !signal_pending(current) - && !kvm_arch_vcpu_runnable(vcpu)) { - set_current_state(TASK_INTERRUPTIBLE); + DEFINE_WAIT(wait); + + for (;;) { + prepare_to_wait(&vcpu->wq, &wait, TASK_INTERRUPTIBLE); + + if (kvm_cpu_has_interrupt(vcpu)) + break; + if (kvm_cpu_has_pending_timer(vcpu)) + break; + if (kvm_arch_vcpu_runnable(vcpu)) + break; + if (signal_pending(current)) + break; + vcpu_put(vcpu); schedule(); vcpu_load(vcpu); } - __set_current_state(TASK_RUNNING); - remove_wait_queue(&vcpu->wq, &wait); + finish_wait(&vcpu->wq, &wait); } void kvm_resched(struct kvm_vcpu *vcpu)