mirror of
https://github.com/adulau/aha.git
synced 2024-12-27 11:16:11 +00:00
Merge branches 'tracing/ftrace', 'tracing/mmiotrace' and 'linus' into tracing/core
This commit is contained in:
commit
fdfa66ab45
105 changed files with 1872 additions and 860 deletions
|
@ -1,3 +1,46 @@
|
|||
What: /sys/bus/pci/drivers/.../bind
|
||||
Date: December 2003
|
||||
Contact: linux-pci@vger.kernel.org
|
||||
Description:
|
||||
Writing a device location to this file will cause
|
||||
the driver to attempt to bind to the device found at
|
||||
this location. This is useful for overriding default
|
||||
bindings. The format for the location is: DDDD:BB:DD.F.
|
||||
That is Domain:Bus:Device.Function and is the same as
|
||||
found in /sys/bus/pci/devices/. For example:
|
||||
# echo 0000:00:19.0 > /sys/bus/pci/drivers/foo/bind
|
||||
(Note: kernels before 2.6.28 may require echo -n).
|
||||
|
||||
What: /sys/bus/pci/drivers/.../unbind
|
||||
Date: December 2003
|
||||
Contact: linux-pci@vger.kernel.org
|
||||
Description:
|
||||
Writing a device location to this file will cause the
|
||||
driver to attempt to unbind from the device found at
|
||||
this location. This may be useful when overriding default
|
||||
bindings. The format for the location is: DDDD:BB:DD.F.
|
||||
That is Domain:Bus:Device.Function and is the same as
|
||||
found in /sys/bus/pci/devices/. For example:
|
||||
# echo 0000:00:19.0 > /sys/bus/pci/drivers/foo/unbind
|
||||
(Note: kernels before 2.6.28 may require echo -n).
|
||||
|
||||
What: /sys/bus/pci/drivers/.../new_id
|
||||
Date: December 2003
|
||||
Contact: linux-pci@vger.kernel.org
|
||||
Description:
|
||||
Writing a device ID to this file will attempt to
|
||||
dynamically add a new device ID to a PCI device driver.
|
||||
This may allow the driver to support more hardware than
|
||||
was included in the driver's static device ID support
|
||||
table at compile time. The format for the device ID is:
|
||||
VVVV DDDD SVVV SDDD CCCC MMMM PPPP. That is Vendor ID,
|
||||
Device ID, Subsystem Vendor ID, Subsystem Device ID,
|
||||
Class, Class Mask, and Private Driver Data. The Vendor ID
|
||||
and Device ID fields are required, the rest are optional.
|
||||
Upon successfully adding an ID, the driver will probe
|
||||
for the device and attempt to bind to it. For example:
|
||||
# echo "8086 10f5" > /sys/bus/pci/drivers/foo/new_id
|
||||
|
||||
What: /sys/bus/pci/devices/.../vpd
|
||||
Date: February 2008
|
||||
Contact: Ben Hutchings <bhutchings@solarflare.com>
|
||||
|
|
|
@ -1,205 +0,0 @@
|
|||
This README escorted the skystar2-driver rewriting procedure. It describes the
|
||||
state of the new flexcop-driver set and some internals are written down here
|
||||
too.
|
||||
|
||||
This document hopefully describes things about the flexcop and its
|
||||
device-offsprings. Goal was to write an easy-to-write and easy-to-read set of
|
||||
drivers based on the skystar2.c and other information.
|
||||
|
||||
Remark: flexcop-pci.c was a copy of skystar2.c, but every line has been
|
||||
touched and rewritten.
|
||||
|
||||
History & News
|
||||
==============
|
||||
2005-04-01 - correct USB ISOC transfers (thanks to Vadim Catana)
|
||||
|
||||
|
||||
|
||||
|
||||
General coding processing
|
||||
=========================
|
||||
|
||||
We should proceed as follows (as long as no one complains):
|
||||
|
||||
0) Think before start writing code!
|
||||
|
||||
1) rewriting the skystar2.c with the help of the flexcop register descriptions
|
||||
and splitting up the files to a pci-bus-part and a flexcop-part.
|
||||
The new driver will be called b2c2-flexcop-pci.ko/b2c2-flexcop-usb.ko for the
|
||||
device-specific part and b2c2-flexcop.ko for the common flexcop-functions.
|
||||
|
||||
2) Search for errors in the leftover of flexcop-pci.c (compare with pluto2.c
|
||||
and other pci drivers)
|
||||
|
||||
3) make some beautification (see 'Improvements when rewriting (refactoring) is
|
||||
done')
|
||||
|
||||
4) Testing the new driver and maybe substitute the skystar2.c with it, to reach
|
||||
a wider tester audience.
|
||||
|
||||
5) creating an usb-bus-part using the already written flexcop code for the pci
|
||||
card.
|
||||
|
||||
Idea: create a kernel-object for the flexcop and export all important
|
||||
functions. This option saves kernel-memory, but maybe a lot of functions have
|
||||
to be exported to kernel namespace.
|
||||
|
||||
|
||||
Current situation
|
||||
=================
|
||||
|
||||
0) Done :)
|
||||
1) Done (some minor issues left)
|
||||
2) Done
|
||||
3) Not ready yet, more information is necessary
|
||||
4) next to be done (see the table below)
|
||||
5) USB driver is working (yes, there are some minor issues)
|
||||
|
||||
What seems to be ready?
|
||||
-----------------------
|
||||
|
||||
1) Rewriting
|
||||
1a) i2c is cut off from the flexcop-pci.c and seems to work
|
||||
1b) moved tuner and demod stuff from flexcop-pci.c to flexcop-tuner-fe.c
|
||||
1c) moved lnb and diseqc stuff from flexcop-pci.c to flexcop-tuner-fe.c
|
||||
1e) eeprom (reading MAC address)
|
||||
1d) sram (no dynamic sll size detection (commented out) (using default as JJ told me))
|
||||
1f) misc. register accesses for reading parameters (e.g. resetting, revision)
|
||||
1g) pid/mac filter (flexcop-hw-filter.c)
|
||||
1i) dvb-stuff initialization in flexcop.c (done)
|
||||
1h) dma stuff (now just using the size-irq, instead of all-together, to be done)
|
||||
1j) remove flexcop initialization from flexcop-pci.c completely (done)
|
||||
1l) use a well working dma IRQ method (done, see 'Known bugs and problems and TODO')
|
||||
1k) cleanup flexcop-files (remove unused EXPORT_SYMBOLs, make static from
|
||||
non-static where possible, moved code to proper places)
|
||||
|
||||
2) Search for errors in the leftover of flexcop-pci.c (partially done)
|
||||
5a) add MAC address reading
|
||||
5c) feeding of ISOC data to the software demux (format of the isochronous data
|
||||
and speed optimization, no real error) (thanks to Vadim Catana)
|
||||
|
||||
What to do in the near future?
|
||||
--------------------------------------
|
||||
(no special order here)
|
||||
|
||||
5) USB driver
|
||||
5b) optimize isoc-transfer (submitting/killing isoc URBs when transfer is starting)
|
||||
|
||||
Testing changes
|
||||
---------------
|
||||
|
||||
O = item is working
|
||||
P = item is partially working
|
||||
X = item is not working
|
||||
N = item does not apply here
|
||||
<empty field> = item need to be examined
|
||||
|
||||
| PCI | USB
|
||||
item | mt352 | nxt2002 | stv0299 | mt312 | mt352 | nxt2002 | stv0299 | mt312
|
||||
-------+-------+---------+---------+-------+-------+---------+---------+-------
|
||||
1a) | O | | | | N | N | N | N
|
||||
1b) | O | | | | | | O |
|
||||
1c) | N | N | | | N | N | O |
|
||||
1d) | O | O
|
||||
1e) | O | O
|
||||
1f) | P
|
||||
1g) | O
|
||||
1h) | P |
|
||||
1i) | O | N
|
||||
1j) | O | N
|
||||
1l) | O | N
|
||||
2) | O | N
|
||||
5a) | N | O
|
||||
5b)* | N |
|
||||
5c) | N | O
|
||||
|
||||
* - not done yet
|
||||
|
||||
Known bugs and problems and TODO
|
||||
--------------------------------
|
||||
|
||||
1g/h/l) when pid filtering is enabled on the pci card
|
||||
|
||||
DMA usage currently:
|
||||
The DMA is splitted in 2 equal-sized subbuffers. The Flexcop writes to first
|
||||
address and triggers an IRQ when it's full and starts writing to the second
|
||||
address. When the second address is full, the IRQ is triggered again, and
|
||||
the flexcop writes to first address again, and so on.
|
||||
The buffersize of each address is currently 640*188 bytes.
|
||||
|
||||
Problem is, when using hw-pid-filtering and doing some low-bandwidth
|
||||
operation (like scanning) the buffers won't be filled enough to trigger
|
||||
the IRQ. That's why:
|
||||
|
||||
When PID filtering is activated, the timer IRQ is used. Every 1.97 ms the IRQ
|
||||
is triggered. Is the current write address of DMA1 different to the one
|
||||
during the last IRQ, then the data is passed to the demuxer.
|
||||
|
||||
There is an additional DMA-IRQ-method: packet count IRQ. This isn't
|
||||
implemented correctly yet.
|
||||
|
||||
The solution is to disable HW PID filtering, but I don't know how the DVB
|
||||
API software demux behaves on slow systems with 45MBit/s TS.
|
||||
|
||||
Solved bugs :)
|
||||
--------------
|
||||
1g) pid-filtering (somehow pid index 4 and 5 (EMM_PID and ECM_PID) aren't
|
||||
working)
|
||||
SOLUTION: also index 0 was affected, because net_translation is done for
|
||||
these indexes by default
|
||||
|
||||
5b) isochronous transfer does only work in the first attempt (for the Sky2PC
|
||||
USB, Air2PC is working) SOLUTION: the flexcop was going asleep and never really
|
||||
woke up again (don't know if this need fixes, see
|
||||
flexcop-fe-tuner.c:flexcop_sleep)
|
||||
|
||||
NEWS: when the driver is loaded and unloaded and loaded again (w/o doing
|
||||
anything in the while the driver is loaded the first time), no transfers take
|
||||
place anymore.
|
||||
|
||||
Improvements when rewriting (refactoring) is done
|
||||
=================================================
|
||||
|
||||
- split sleeping of the flexcop (misc_204.ACPI3_sig = 1;) from lnb_control
|
||||
(enable sleeping for other demods than dvb-s)
|
||||
- add support for CableStar (stv0297 Microtune 203x/ALPS) (almost done, incompatibilities with the Nexus-CA)
|
||||
|
||||
Debugging
|
||||
---------
|
||||
- add verbose debugging to skystar2.c (dump the reg_dw_data) and compare it
|
||||
with this flexcop, this is important, because i2c is now using the
|
||||
flexcop_ibi_value union from flexcop-reg.h (do you have a better idea for
|
||||
that, please tell us so).
|
||||
|
||||
Everything which is identical in the following table, can be put into a common
|
||||
flexcop-module.
|
||||
|
||||
PCI USB
|
||||
-------------------------------------------------------------------------------
|
||||
Different:
|
||||
Register access: accessing IO memory USB control message
|
||||
I2C bus: I2C bus of the FC USB control message
|
||||
Data transfer: DMA isochronous transfer
|
||||
EEPROM transfer: through i2c bus not clear yet
|
||||
|
||||
Identical:
|
||||
Streaming: accessing registers
|
||||
PID Filtering: accessing registers
|
||||
Sram destinations: accessing registers
|
||||
Tuner/Demod: I2C bus
|
||||
DVB-stuff: can be written for common use
|
||||
|
||||
Acknowledgements (just for the rewriting part)
|
||||
================
|
||||
|
||||
Bjarne Steinsbo thought a lot in the first place of the pci part for this code
|
||||
sharing idea.
|
||||
|
||||
Andreas Oberritter for providing a recent PCI initialization template
|
||||
(pluto2.c).
|
||||
|
||||
Boleslaw Ciesielski for pointing out a problem with firmware loader.
|
||||
|
||||
Vadim Catana for correcting the USB transfer.
|
||||
|
||||
comments, critics and ideas to linux-dvb@linuxtv.org.
|
|
@ -1,5 +1,5 @@
|
|||
How to set up the Technisat devices
|
||||
===================================
|
||||
How to set up the Technisat/B2C2 Flexcop devices
|
||||
================================================
|
||||
|
||||
1) Find out what device you have
|
||||
================================
|
||||
|
@ -16,54 +16,60 @@ DVB: registering frontend 0 (Conexant CX24123/CX24109)...
|
|||
|
||||
If the Technisat is the only TV device in your box get rid of unnecessary modules and check this one:
|
||||
"Multimedia devices" => "Customise analog and hybrid tuner modules to build"
|
||||
In this directory uncheck every driver which is activated there.
|
||||
In this directory uncheck every driver which is activated there (except "Simple tuner support" for case 9 only).
|
||||
|
||||
Then please activate:
|
||||
2a) Main module part:
|
||||
|
||||
a.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters"
|
||||
b.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters" => "Technisat/B2C2 Air/Sky/Cable2PC PCI" in case of a PCI card OR
|
||||
b.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters" => "Technisat/B2C2 Air/Sky/Cable2PC PCI" in case of a PCI card
|
||||
OR
|
||||
c.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters" => "Technisat/B2C2 Air/Sky/Cable2PC USB" in case of an USB 1.1 adapter
|
||||
d.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters" => "Enable debug for the B2C2 FlexCop drivers"
|
||||
Notice: d.) is helpful for troubleshooting
|
||||
|
||||
2b) Frontend module part:
|
||||
|
||||
1.) Revision 2.3:
|
||||
1.) SkyStar DVB-S Revision 2.3:
|
||||
a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
|
||||
b.)"Multimedia devices" => "Customise DVB frontends" => "Zarlink VP310/MT312/ZL10313 based"
|
||||
|
||||
2.) Revision 2.6:
|
||||
2.) SkyStar DVB-S Revision 2.6:
|
||||
a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
|
||||
b.)"Multimedia devices" => "Customise DVB frontends" => "ST STV0299 based"
|
||||
|
||||
3.) Revision 2.7:
|
||||
3.) SkyStar DVB-S Revision 2.7:
|
||||
a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
|
||||
b.)"Multimedia devices" => "Customise DVB frontends" => "Samsung S5H1420 based"
|
||||
c.)"Multimedia devices" => "Customise DVB frontends" => "Integrant ITD1000 Zero IF tuner for DVB-S/DSS"
|
||||
d.)"Multimedia devices" => "Customise DVB frontends" => "ISL6421 SEC controller"
|
||||
|
||||
4.) Revision 2.8:
|
||||
4.) SkyStar DVB-S Revision 2.8:
|
||||
a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
|
||||
b.)"Multimedia devices" => "Customise DVB frontends" => "Conexant CX24113/CX24128 tuner for DVB-S/DSS"
|
||||
c.)"Multimedia devices" => "Customise DVB frontends" => "Conexant CX24123 based"
|
||||
d.)"Multimedia devices" => "Customise DVB frontends" => "ISL6421 SEC controller"
|
||||
|
||||
5.) DVB-T card:
|
||||
5.) AirStar DVB-T card:
|
||||
a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
|
||||
b.)"Multimedia devices" => "Customise DVB frontends" => "Zarlink MT352 based"
|
||||
|
||||
6.) DVB-C card:
|
||||
6.) CableStar DVB-C card:
|
||||
a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
|
||||
b.)"Multimedia devices" => "Customise DVB frontends" => "ST STV0297 based"
|
||||
|
||||
7.) ATSC card 1st generation:
|
||||
7.) AirStar ATSC card 1st generation:
|
||||
a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
|
||||
b.)"Multimedia devices" => "Customise DVB frontends" => "Broadcom BCM3510"
|
||||
|
||||
8.) ATSC card 2nd generation:
|
||||
8.) AirStar ATSC card 2nd generation:
|
||||
a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
|
||||
b.)"Multimedia devices" => "Customise DVB frontends" => "NxtWave Communications NXT2002/NXT2004 based"
|
||||
c.)"Multimedia devices" => "Customise DVB frontends" => "LG Electronics LGDT3302/LGDT3303 based"
|
||||
c.)"Multimedia devices" => "Customise DVB frontends" => "Generic I2C PLL based tuners"
|
||||
|
||||
Author: Uwe Bugla <uwe.bugla@gmx.de> December 2008
|
||||
9.) AirStar ATSC card 3rd generation:
|
||||
a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
|
||||
b.)"Multimedia devices" => "Customise DVB frontends" => "LG Electronics LGDT3302/LGDT3303 based"
|
||||
c.)"Multimedia devices" => "Customise analog and hybrid tuner modules to build" => "Simple tuner support"
|
||||
|
||||
Author: Uwe Bugla <uwe.bugla@gmx.de> February 2009
|
||||
|
|
|
@ -115,7 +115,7 @@ In addition, the following text indicates that the option:
|
|||
Parameters denoted with BOOT are actually interpreted by the boot
|
||||
loader, and have no meaning to the kernel directly.
|
||||
Do not modify the syntax of boot loader parameters without extreme
|
||||
need or coordination with <Documentation/x86/i386/boot.txt>.
|
||||
need or coordination with <Documentation/x86/boot.txt>.
|
||||
|
||||
There are also arch-specific kernel-parameters not documented here.
|
||||
See for example <Documentation/x86/x86_64/boot-options.txt>.
|
||||
|
@ -2461,7 +2461,7 @@ and is between 256 and 4096 characters. It is defined in the file
|
|||
See Documentation/fb/modedb.txt.
|
||||
|
||||
vga= [BOOT,X86-32] Select a particular video mode
|
||||
See Documentation/x86/i386/boot.txt and
|
||||
See Documentation/x86/boot.txt and
|
||||
Documentation/svga.txt.
|
||||
Use vga=ask for menu.
|
||||
This is actually a boot loader parameter; the value is
|
||||
|
|
|
@ -311,6 +311,9 @@ evm_u35_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
|
|||
gpio_request(gpio + 7, "nCF_SEL");
|
||||
gpio_direction_output(gpio + 7, 1);
|
||||
|
||||
/* irlml6401 sustains over 3A, switches 5V in under 8 msec */
|
||||
setup_usb(500, 8);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -417,9 +420,6 @@ static __init void davinci_evm_init(void)
|
|||
platform_add_devices(davinci_evm_devices,
|
||||
ARRAY_SIZE(davinci_evm_devices));
|
||||
evm_init_i2c();
|
||||
|
||||
/* irlml6401 sustains over 3A, switches 5V in under 8 msec */
|
||||
setup_usb(500, 8);
|
||||
}
|
||||
|
||||
static __init void davinci_evm_irq_init(void)
|
||||
|
|
|
@ -230,6 +230,11 @@ static struct clk davinci_clks[] = {
|
|||
.rate = &commonrate,
|
||||
.lpsc = DAVINCI_LPSC_GPIO,
|
||||
},
|
||||
{
|
||||
.name = "usb",
|
||||
.rate = &commonrate,
|
||||
.lpsc = DAVINCI_LPSC_USB,
|
||||
},
|
||||
{
|
||||
.name = "AEMIFCLK",
|
||||
.rate = &commonrate,
|
||||
|
|
|
@ -47,6 +47,7 @@ static struct musb_hdrc_platform_data usb_data = {
|
|||
#elif defined(CONFIG_USB_MUSB_HOST)
|
||||
.mode = MUSB_HOST,
|
||||
#endif
|
||||
.clock = "usb",
|
||||
.config = &musb_config,
|
||||
};
|
||||
|
||||
|
|
|
@ -603,7 +603,7 @@ config CAVIUM_OCTEON_SIMULATOR
|
|||
select SYS_SUPPORTS_64BIT_KERNEL
|
||||
select SYS_SUPPORTS_BIG_ENDIAN
|
||||
select SYS_SUPPORTS_HIGHMEM
|
||||
select CPU_CAVIUM_OCTEON
|
||||
select SYS_HAS_CPU_CAVIUM_OCTEON
|
||||
help
|
||||
The Octeon simulator is software performance model of the Cavium
|
||||
Octeon Processor. It supports simulating Octeon processors on x86
|
||||
|
@ -618,7 +618,7 @@ config CAVIUM_OCTEON_REFERENCE_BOARD
|
|||
select SYS_SUPPORTS_BIG_ENDIAN
|
||||
select SYS_SUPPORTS_HIGHMEM
|
||||
select SYS_HAS_EARLY_PRINTK
|
||||
select CPU_CAVIUM_OCTEON
|
||||
select SYS_HAS_CPU_CAVIUM_OCTEON
|
||||
select SWAP_IO_SPACE
|
||||
help
|
||||
This option supports all of the Octeon reference boards from Cavium
|
||||
|
@ -1234,6 +1234,7 @@ config CPU_SB1
|
|||
|
||||
config CPU_CAVIUM_OCTEON
|
||||
bool "Cavium Octeon processor"
|
||||
depends on SYS_HAS_CPU_CAVIUM_OCTEON
|
||||
select IRQ_CPU
|
||||
select IRQ_CPU_OCTEON
|
||||
select CPU_HAS_PREFETCH
|
||||
|
@ -1314,6 +1315,9 @@ config SYS_HAS_CPU_RM9000
|
|||
config SYS_HAS_CPU_SB1
|
||||
bool
|
||||
|
||||
config SYS_HAS_CPU_CAVIUM_OCTEON
|
||||
bool
|
||||
|
||||
#
|
||||
# CPU may reorder R->R, R->W, W->R, W->W
|
||||
# Reordering beyond LL and SC is handled in WEAK_REORDERING_BEYOND_LLSC
|
||||
|
@ -1387,6 +1391,7 @@ config 32BIT
|
|||
config 64BIT
|
||||
bool "64-bit kernel"
|
||||
depends on CPU_SUPPORTS_64BIT_KERNEL && SYS_SUPPORTS_64BIT_KERNEL
|
||||
select HAVE_SYSCALL_WRAPPERS
|
||||
help
|
||||
Select this option if you want to build a 64-bit kernel.
|
||||
|
||||
|
|
|
@ -118,7 +118,7 @@ void __init plat_time_init(void)
|
|||
* setup counter 1 (RTC) to tick at full speed
|
||||
*/
|
||||
t = 0xffffff;
|
||||
while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S) && t--)
|
||||
while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S) && --t)
|
||||
asm volatile ("nop");
|
||||
if (!t)
|
||||
goto cntr_err;
|
||||
|
@ -127,7 +127,7 @@ void __init plat_time_init(void)
|
|||
au_sync();
|
||||
|
||||
t = 0xffffff;
|
||||
while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S) && t--)
|
||||
while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S) && --t)
|
||||
asm volatile ("nop");
|
||||
if (!t)
|
||||
goto cntr_err;
|
||||
|
@ -135,7 +135,7 @@ void __init plat_time_init(void)
|
|||
au_sync();
|
||||
|
||||
t = 0xffffff;
|
||||
while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S) && t--)
|
||||
while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S) && --t)
|
||||
asm volatile ("nop");
|
||||
if (!t)
|
||||
goto cntr_err;
|
||||
|
|
|
@ -111,7 +111,6 @@ int show_interrupts(struct seq_file *p, void *v)
|
|||
seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
|
||||
#endif
|
||||
seq_printf(p, " %14s", irq_desc[i].chip->name);
|
||||
seq_printf(p, "-%-8s", irq_desc[i].name);
|
||||
seq_printf(p, " %s", action->name);
|
||||
|
||||
for (action=action->next; action; action = action->next)
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/binfmts.h>
|
||||
#include <linux/security.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/compat.h>
|
||||
#include <linux/vfs.h>
|
||||
#include <linux/ipc.h>
|
||||
|
@ -63,9 +64,9 @@
|
|||
#define merge_64(r1, r2) ((((r2) & 0xffffffffUL) << 32) + ((r1) & 0xffffffffUL))
|
||||
#endif
|
||||
|
||||
asmlinkage unsigned long
|
||||
sys32_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
|
||||
unsigned long flags, unsigned long fd, unsigned long pgoff)
|
||||
SYSCALL_DEFINE6(32_mmap2, unsigned long, addr, unsigned long, len,
|
||||
unsigned long, prot, unsigned long, flags, unsigned long, fd,
|
||||
unsigned long, pgoff)
|
||||
{
|
||||
struct file * file = NULL;
|
||||
unsigned long error;
|
||||
|
@ -121,21 +122,21 @@ struct rlimit32 {
|
|||
int rlim_max;
|
||||
};
|
||||
|
||||
asmlinkage long sys32_truncate64(const char __user * path,
|
||||
unsigned long __dummy, int a2, int a3)
|
||||
SYSCALL_DEFINE4(32_truncate64, const char __user *, path,
|
||||
unsigned long, __dummy, unsigned long, a2, unsigned long, a3)
|
||||
{
|
||||
return sys_truncate(path, merge_64(a2, a3));
|
||||
}
|
||||
|
||||
asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long __dummy,
|
||||
int a2, int a3)
|
||||
SYSCALL_DEFINE4(32_ftruncate64, unsigned long, fd, unsigned long, __dummy,
|
||||
unsigned long, a2, unsigned long, a3)
|
||||
{
|
||||
return sys_ftruncate(fd, merge_64(a2, a3));
|
||||
}
|
||||
|
||||
asmlinkage int sys32_llseek(unsigned int fd, unsigned int offset_high,
|
||||
unsigned int offset_low, loff_t __user * result,
|
||||
unsigned int origin)
|
||||
SYSCALL_DEFINE5(32_llseek, unsigned long, fd, unsigned long, offset_high,
|
||||
unsigned long, offset_low, loff_t __user *, result,
|
||||
unsigned long, origin)
|
||||
{
|
||||
return sys_llseek(fd, offset_high, offset_low, result, origin);
|
||||
}
|
||||
|
@ -144,20 +145,20 @@ asmlinkage int sys32_llseek(unsigned int fd, unsigned int offset_high,
|
|||
lseek back to original location. They fail just like lseek does on
|
||||
non-seekable files. */
|
||||
|
||||
asmlinkage ssize_t sys32_pread(unsigned int fd, char __user * buf,
|
||||
size_t count, u32 unused, u64 a4, u64 a5)
|
||||
SYSCALL_DEFINE6(32_pread, unsigned long, fd, char __user *, buf, size_t, count,
|
||||
unsigned long, unused, unsigned long, a4, unsigned long, a5)
|
||||
{
|
||||
return sys_pread64(fd, buf, count, merge_64(a4, a5));
|
||||
}
|
||||
|
||||
asmlinkage ssize_t sys32_pwrite(unsigned int fd, const char __user * buf,
|
||||
size_t count, u32 unused, u64 a4, u64 a5)
|
||||
SYSCALL_DEFINE6(32_pwrite, unsigned int, fd, const char __user *, buf,
|
||||
size_t, count, u32, unused, u64, a4, u64, a5)
|
||||
{
|
||||
return sys_pwrite64(fd, buf, count, merge_64(a4, a5));
|
||||
}
|
||||
|
||||
asmlinkage int sys32_sched_rr_get_interval(compat_pid_t pid,
|
||||
struct compat_timespec __user *interval)
|
||||
SYSCALL_DEFINE2(32_sched_rr_get_interval, compat_pid_t, pid,
|
||||
struct compat_timespec __user *, interval)
|
||||
{
|
||||
struct timespec t;
|
||||
int ret;
|
||||
|
@ -174,8 +175,8 @@ asmlinkage int sys32_sched_rr_get_interval(compat_pid_t pid,
|
|||
|
||||
#ifdef CONFIG_SYSVIPC
|
||||
|
||||
asmlinkage long
|
||||
sys32_ipc(u32 call, int first, int second, int third, u32 ptr, u32 fifth)
|
||||
SYSCALL_DEFINE6(32_ipc, u32, call, long, first, long, second, long, third,
|
||||
unsigned long, ptr, unsigned long, fifth)
|
||||
{
|
||||
int version, err;
|
||||
|
||||
|
@ -233,8 +234,8 @@ sys32_ipc(u32 call, int first, int second, int third, u32 ptr, u32 fifth)
|
|||
|
||||
#else
|
||||
|
||||
asmlinkage long
|
||||
sys32_ipc(u32 call, int first, int second, int third, u32 ptr, u32 fifth)
|
||||
SYSCALL_DEFINE6(32_ipc, u32, call, int, first, int, second, int, third,
|
||||
u32, ptr, u32 fifth)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
@ -242,7 +243,7 @@ sys32_ipc(u32 call, int first, int second, int third, u32 ptr, u32 fifth)
|
|||
#endif /* CONFIG_SYSVIPC */
|
||||
|
||||
#ifdef CONFIG_MIPS32_N32
|
||||
asmlinkage long sysn32_semctl(int semid, int semnum, int cmd, u32 arg)
|
||||
SYSCALL_DEFINE4(n32_semctl, int, semid, int, semnum, int, cmd, u32, arg)
|
||||
{
|
||||
/* compat_sys_semctl expects a pointer to union semun */
|
||||
u32 __user *uptr = compat_alloc_user_space(sizeof(u32));
|
||||
|
@ -251,13 +252,14 @@ asmlinkage long sysn32_semctl(int semid, int semnum, int cmd, u32 arg)
|
|||
return compat_sys_semctl(semid, semnum, cmd, uptr);
|
||||
}
|
||||
|
||||
asmlinkage long sysn32_msgsnd(int msqid, u32 msgp, unsigned msgsz, int msgflg)
|
||||
SYSCALL_DEFINE4(n32_msgsnd, int, msqid, u32, msgp, unsigned int, msgsz,
|
||||
int, msgflg)
|
||||
{
|
||||
return compat_sys_msgsnd(msqid, msgsz, msgflg, compat_ptr(msgp));
|
||||
}
|
||||
|
||||
asmlinkage long sysn32_msgrcv(int msqid, u32 msgp, size_t msgsz, int msgtyp,
|
||||
int msgflg)
|
||||
SYSCALL_DEFINE5(n32_msgrcv, int, msqid, u32, msgp, size_t, msgsz,
|
||||
int, msgtyp, int, msgflg)
|
||||
{
|
||||
return compat_sys_msgrcv(msqid, msgsz, msgtyp, msgflg, IPC_64,
|
||||
compat_ptr(msgp));
|
||||
|
@ -277,7 +279,7 @@ struct sysctl_args32
|
|||
|
||||
#ifdef CONFIG_SYSCTL_SYSCALL
|
||||
|
||||
asmlinkage long sys32_sysctl(struct sysctl_args32 __user *args)
|
||||
SYSCALL_DEFINE1(32_sysctl, struct sysctl_args32 __user *, args)
|
||||
{
|
||||
struct sysctl_args32 tmp;
|
||||
int error;
|
||||
|
@ -316,9 +318,16 @@ asmlinkage long sys32_sysctl(struct sysctl_args32 __user *args)
|
|||
return error;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
SYSCALL_DEFINE1(32_sysctl, struct sysctl_args32 __user *, args)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_SYSCTL_SYSCALL */
|
||||
|
||||
asmlinkage long sys32_newuname(struct new_utsname __user * name)
|
||||
SYSCALL_DEFINE1(32_newuname, struct new_utsname __user *, name)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
|
@ -334,7 +343,7 @@ asmlinkage long sys32_newuname(struct new_utsname __user * name)
|
|||
return ret;
|
||||
}
|
||||
|
||||
asmlinkage int sys32_personality(unsigned long personality)
|
||||
SYSCALL_DEFINE1(32_personality, unsigned long, personality)
|
||||
{
|
||||
int ret;
|
||||
personality &= 0xffffffff;
|
||||
|
@ -357,7 +366,7 @@ struct ustat32 {
|
|||
|
||||
extern asmlinkage long sys_ustat(dev_t dev, struct ustat __user * ubuf);
|
||||
|
||||
asmlinkage int sys32_ustat(dev_t dev, struct ustat32 __user * ubuf32)
|
||||
SYSCALL_DEFINE2(32_ustat, dev_t, dev, struct ustat32 __user *, ubuf32)
|
||||
{
|
||||
int err;
|
||||
struct ustat tmp;
|
||||
|
@ -381,8 +390,8 @@ out:
|
|||
return err;
|
||||
}
|
||||
|
||||
asmlinkage int sys32_sendfile(int out_fd, int in_fd, compat_off_t __user *offset,
|
||||
s32 count)
|
||||
SYSCALL_DEFINE4(32_sendfile, long, out_fd, long, in_fd,
|
||||
compat_off_t __user *, offset, s32, count)
|
||||
{
|
||||
mm_segment_t old_fs = get_fs();
|
||||
int ret;
|
||||
|
|
|
@ -399,7 +399,7 @@ einval: li v0, -ENOSYS
|
|||
sys sys_swapon 2
|
||||
sys sys_reboot 3
|
||||
sys sys_old_readdir 3
|
||||
sys old_mmap 6 /* 4090 */
|
||||
sys sys_mips_mmap 6 /* 4090 */
|
||||
sys sys_munmap 2
|
||||
sys sys_truncate 2
|
||||
sys sys_ftruncate 2
|
||||
|
@ -519,7 +519,7 @@ einval: li v0, -ENOSYS
|
|||
sys sys_sendfile 4
|
||||
sys sys_ni_syscall 0
|
||||
sys sys_ni_syscall 0
|
||||
sys sys_mmap2 6 /* 4210 */
|
||||
sys sys_mips_mmap2 6 /* 4210 */
|
||||
sys sys_truncate64 4
|
||||
sys sys_ftruncate64 4
|
||||
sys sys_stat64 2
|
||||
|
|
|
@ -207,7 +207,7 @@ sys_call_table:
|
|||
PTR sys_newlstat
|
||||
PTR sys_poll
|
||||
PTR sys_lseek
|
||||
PTR old_mmap
|
||||
PTR sys_mips_mmap
|
||||
PTR sys_mprotect /* 5010 */
|
||||
PTR sys_munmap
|
||||
PTR sys_brk
|
||||
|
|
|
@ -129,12 +129,12 @@ EXPORT(sysn32_call_table)
|
|||
PTR sys_newlstat
|
||||
PTR sys_poll
|
||||
PTR sys_lseek
|
||||
PTR old_mmap
|
||||
PTR sys_mips_mmap
|
||||
PTR sys_mprotect /* 6010 */
|
||||
PTR sys_munmap
|
||||
PTR sys_brk
|
||||
PTR sys32_rt_sigaction
|
||||
PTR sys32_rt_sigprocmask
|
||||
PTR sys_32_rt_sigaction
|
||||
PTR sys_32_rt_sigprocmask
|
||||
PTR compat_sys_ioctl /* 6015 */
|
||||
PTR sys_pread64
|
||||
PTR sys_pwrite64
|
||||
|
@ -159,7 +159,7 @@ EXPORT(sysn32_call_table)
|
|||
PTR compat_sys_setitimer
|
||||
PTR sys_alarm
|
||||
PTR sys_getpid
|
||||
PTR sys32_sendfile
|
||||
PTR sys_32_sendfile
|
||||
PTR sys_socket /* 6040 */
|
||||
PTR sys_connect
|
||||
PTR sys_accept
|
||||
|
@ -181,14 +181,14 @@ EXPORT(sysn32_call_table)
|
|||
PTR sys_exit
|
||||
PTR compat_sys_wait4
|
||||
PTR sys_kill /* 6060 */
|
||||
PTR sys32_newuname
|
||||
PTR sys_32_newuname
|
||||
PTR sys_semget
|
||||
PTR sys_semop
|
||||
PTR sysn32_semctl
|
||||
PTR sys_n32_semctl
|
||||
PTR sys_shmdt /* 6065 */
|
||||
PTR sys_msgget
|
||||
PTR sysn32_msgsnd
|
||||
PTR sysn32_msgrcv
|
||||
PTR sys_n32_msgsnd
|
||||
PTR sys_n32_msgrcv
|
||||
PTR compat_sys_msgctl
|
||||
PTR compat_sys_fcntl /* 6070 */
|
||||
PTR sys_flock
|
||||
|
@ -245,15 +245,15 @@ EXPORT(sysn32_call_table)
|
|||
PTR sys_getsid
|
||||
PTR sys_capget
|
||||
PTR sys_capset
|
||||
PTR sys32_rt_sigpending /* 6125 */
|
||||
PTR sys_32_rt_sigpending /* 6125 */
|
||||
PTR compat_sys_rt_sigtimedwait
|
||||
PTR sys32_rt_sigqueueinfo
|
||||
PTR sys_32_rt_sigqueueinfo
|
||||
PTR sysn32_rt_sigsuspend
|
||||
PTR sys32_sigaltstack
|
||||
PTR compat_sys_utime /* 6130 */
|
||||
PTR sys_mknod
|
||||
PTR sys32_personality
|
||||
PTR sys32_ustat
|
||||
PTR sys_32_personality
|
||||
PTR sys_32_ustat
|
||||
PTR compat_sys_statfs
|
||||
PTR compat_sys_fstatfs /* 6135 */
|
||||
PTR sys_sysfs
|
||||
|
@ -265,14 +265,14 @@ EXPORT(sysn32_call_table)
|
|||
PTR sys_sched_getscheduler
|
||||
PTR sys_sched_get_priority_max
|
||||
PTR sys_sched_get_priority_min
|
||||
PTR sys32_sched_rr_get_interval /* 6145 */
|
||||
PTR sys_32_sched_rr_get_interval /* 6145 */
|
||||
PTR sys_mlock
|
||||
PTR sys_munlock
|
||||
PTR sys_mlockall
|
||||
PTR sys_munlockall
|
||||
PTR sys_vhangup /* 6150 */
|
||||
PTR sys_pivot_root
|
||||
PTR sys32_sysctl
|
||||
PTR sys_32_sysctl
|
||||
PTR sys_prctl
|
||||
PTR compat_sys_adjtimex
|
||||
PTR compat_sys_setrlimit /* 6155 */
|
||||
|
|
|
@ -265,12 +265,12 @@ sys_call_table:
|
|||
PTR sys_olduname
|
||||
PTR sys_umask /* 4060 */
|
||||
PTR sys_chroot
|
||||
PTR sys32_ustat
|
||||
PTR sys_32_ustat
|
||||
PTR sys_dup2
|
||||
PTR sys_getppid
|
||||
PTR sys_getpgrp /* 4065 */
|
||||
PTR sys_setsid
|
||||
PTR sys32_sigaction
|
||||
PTR sys_32_sigaction
|
||||
PTR sys_sgetmask
|
||||
PTR sys_ssetmask
|
||||
PTR sys_setreuid /* 4070 */
|
||||
|
@ -293,7 +293,7 @@ sys_call_table:
|
|||
PTR sys_swapon
|
||||
PTR sys_reboot
|
||||
PTR compat_sys_old_readdir
|
||||
PTR old_mmap /* 4090 */
|
||||
PTR sys_mips_mmap /* 4090 */
|
||||
PTR sys_munmap
|
||||
PTR sys_truncate
|
||||
PTR sys_ftruncate
|
||||
|
@ -320,12 +320,12 @@ sys_call_table:
|
|||
PTR compat_sys_wait4
|
||||
PTR sys_swapoff /* 4115 */
|
||||
PTR compat_sys_sysinfo
|
||||
PTR sys32_ipc
|
||||
PTR sys_32_ipc
|
||||
PTR sys_fsync
|
||||
PTR sys32_sigreturn
|
||||
PTR sys32_clone /* 4120 */
|
||||
PTR sys_setdomainname
|
||||
PTR sys32_newuname
|
||||
PTR sys_32_newuname
|
||||
PTR sys_ni_syscall /* sys_modify_ldt */
|
||||
PTR compat_sys_adjtimex
|
||||
PTR sys_mprotect /* 4125 */
|
||||
|
@ -339,11 +339,11 @@ sys_call_table:
|
|||
PTR sys_fchdir
|
||||
PTR sys_bdflush
|
||||
PTR sys_sysfs /* 4135 */
|
||||
PTR sys32_personality
|
||||
PTR sys_32_personality
|
||||
PTR sys_ni_syscall /* for afs_syscall */
|
||||
PTR sys_setfsuid
|
||||
PTR sys_setfsgid
|
||||
PTR sys32_llseek /* 4140 */
|
||||
PTR sys_32_llseek /* 4140 */
|
||||
PTR compat_sys_getdents
|
||||
PTR compat_sys_select
|
||||
PTR sys_flock
|
||||
|
@ -356,7 +356,7 @@ sys_call_table:
|
|||
PTR sys_ni_syscall /* 4150 */
|
||||
PTR sys_getsid
|
||||
PTR sys_fdatasync
|
||||
PTR sys32_sysctl
|
||||
PTR sys_32_sysctl
|
||||
PTR sys_mlock
|
||||
PTR sys_munlock /* 4155 */
|
||||
PTR sys_mlockall
|
||||
|
@ -368,7 +368,7 @@ sys_call_table:
|
|||
PTR sys_sched_yield
|
||||
PTR sys_sched_get_priority_max
|
||||
PTR sys_sched_get_priority_min
|
||||
PTR sys32_sched_rr_get_interval /* 4165 */
|
||||
PTR sys_32_sched_rr_get_interval /* 4165 */
|
||||
PTR compat_sys_nanosleep
|
||||
PTR sys_mremap
|
||||
PTR sys_accept
|
||||
|
@ -397,25 +397,25 @@ sys_call_table:
|
|||
PTR sys_getresgid
|
||||
PTR sys_prctl
|
||||
PTR sys32_rt_sigreturn
|
||||
PTR sys32_rt_sigaction
|
||||
PTR sys32_rt_sigprocmask /* 4195 */
|
||||
PTR sys32_rt_sigpending
|
||||
PTR sys_32_rt_sigaction
|
||||
PTR sys_32_rt_sigprocmask /* 4195 */
|
||||
PTR sys_32_rt_sigpending
|
||||
PTR compat_sys_rt_sigtimedwait
|
||||
PTR sys32_rt_sigqueueinfo
|
||||
PTR sys_32_rt_sigqueueinfo
|
||||
PTR sys32_rt_sigsuspend
|
||||
PTR sys32_pread /* 4200 */
|
||||
PTR sys32_pwrite
|
||||
PTR sys_32_pread /* 4200 */
|
||||
PTR sys_32_pwrite
|
||||
PTR sys_chown
|
||||
PTR sys_getcwd
|
||||
PTR sys_capget
|
||||
PTR sys_capset /* 4205 */
|
||||
PTR sys32_sigaltstack
|
||||
PTR sys32_sendfile
|
||||
PTR sys_32_sendfile
|
||||
PTR sys_ni_syscall
|
||||
PTR sys_ni_syscall
|
||||
PTR sys32_mmap2 /* 4210 */
|
||||
PTR sys32_truncate64
|
||||
PTR sys32_ftruncate64
|
||||
PTR sys_mips_mmap2 /* 4210 */
|
||||
PTR sys_32_truncate64
|
||||
PTR sys_32_ftruncate64
|
||||
PTR sys_newstat
|
||||
PTR sys_newlstat
|
||||
PTR sys_newfstat /* 4215 */
|
||||
|
@ -481,7 +481,7 @@ sys_call_table:
|
|||
PTR compat_sys_mq_notify /* 4275 */
|
||||
PTR compat_sys_mq_getsetattr
|
||||
PTR sys_ni_syscall /* sys_vserver */
|
||||
PTR sys32_waitid
|
||||
PTR sys_32_waitid
|
||||
PTR sys_ni_syscall /* available, was setaltroot */
|
||||
PTR sys_add_key /* 4280 */
|
||||
PTR sys_request_key
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <linux/ptrace.h>
|
||||
#include <linux/unistd.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#include <asm/abi.h>
|
||||
|
@ -338,8 +339,8 @@ asmlinkage int sys_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_TRAD_SIGNALS
|
||||
asmlinkage int sys_sigaction(int sig, const struct sigaction __user *act,
|
||||
struct sigaction __user *oact)
|
||||
SYSCALL_DEFINE3(sigaction, int, sig, const struct sigaction __user *, act,
|
||||
struct sigaction __user *, oact)
|
||||
{
|
||||
struct k_sigaction new_ka, old_ka;
|
||||
int ret;
|
||||
|
|
|
@ -349,8 +349,8 @@ asmlinkage int sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
|
|||
return -ERESTARTNOHAND;
|
||||
}
|
||||
|
||||
asmlinkage int sys32_sigaction(int sig, const struct sigaction32 __user *act,
|
||||
struct sigaction32 __user *oact)
|
||||
SYSCALL_DEFINE3(32_sigaction, long, sig, const struct sigaction32 __user *, act,
|
||||
struct sigaction32 __user *, oact)
|
||||
{
|
||||
struct k_sigaction new_ka, old_ka;
|
||||
int ret;
|
||||
|
@ -704,9 +704,9 @@ struct mips_abi mips_abi_32 = {
|
|||
.restart = __NR_O32_restart_syscall
|
||||
};
|
||||
|
||||
asmlinkage int sys32_rt_sigaction(int sig, const struct sigaction32 __user *act,
|
||||
struct sigaction32 __user *oact,
|
||||
unsigned int sigsetsize)
|
||||
SYSCALL_DEFINE4(32_rt_sigaction, int, sig,
|
||||
const struct sigaction32 __user *, act,
|
||||
struct sigaction32 __user *, oact, unsigned int, sigsetsize)
|
||||
{
|
||||
struct k_sigaction new_sa, old_sa;
|
||||
int ret = -EINVAL;
|
||||
|
@ -748,8 +748,8 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
asmlinkage int sys32_rt_sigprocmask(int how, compat_sigset_t __user *set,
|
||||
compat_sigset_t __user *oset, unsigned int sigsetsize)
|
||||
SYSCALL_DEFINE4(32_rt_sigprocmask, int, how, compat_sigset_t __user *, set,
|
||||
compat_sigset_t __user *, oset, unsigned int, sigsetsize)
|
||||
{
|
||||
sigset_t old_set, new_set;
|
||||
int ret;
|
||||
|
@ -770,8 +770,8 @@ asmlinkage int sys32_rt_sigprocmask(int how, compat_sigset_t __user *set,
|
|||
return ret;
|
||||
}
|
||||
|
||||
asmlinkage int sys32_rt_sigpending(compat_sigset_t __user *uset,
|
||||
unsigned int sigsetsize)
|
||||
SYSCALL_DEFINE2(32_rt_sigpending, compat_sigset_t __user *, uset,
|
||||
unsigned int, sigsetsize)
|
||||
{
|
||||
int ret;
|
||||
sigset_t set;
|
||||
|
@ -787,7 +787,8 @@ asmlinkage int sys32_rt_sigpending(compat_sigset_t __user *uset,
|
|||
return ret;
|
||||
}
|
||||
|
||||
asmlinkage int sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo)
|
||||
SYSCALL_DEFINE3(32_rt_sigqueueinfo, int, pid, int, sig,
|
||||
compat_siginfo_t __user *, uinfo)
|
||||
{
|
||||
siginfo_t info;
|
||||
int ret;
|
||||
|
@ -802,10 +803,9 @@ asmlinkage int sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *
|
|||
return ret;
|
||||
}
|
||||
|
||||
asmlinkage long
|
||||
sys32_waitid(int which, compat_pid_t pid,
|
||||
compat_siginfo_t __user *uinfo, int options,
|
||||
struct compat_rusage __user *uru)
|
||||
SYSCALL_DEFINE5(32_waitid, int, which, compat_pid_t, pid,
|
||||
compat_siginfo_t __user *, uinfo, int, options,
|
||||
struct compat_rusage __user *, uru)
|
||||
{
|
||||
siginfo_t info;
|
||||
struct rusage ru;
|
||||
|
|
|
@ -152,9 +152,9 @@ out:
|
|||
return error;
|
||||
}
|
||||
|
||||
asmlinkage unsigned long
|
||||
old_mmap(unsigned long addr, unsigned long len, int prot,
|
||||
int flags, int fd, off_t offset)
|
||||
SYSCALL_DEFINE6(mips_mmap, unsigned long, addr, unsigned long, len,
|
||||
unsigned long, prot, unsigned long, flags, unsigned long,
|
||||
fd, off_t, offset)
|
||||
{
|
||||
unsigned long result;
|
||||
|
||||
|
@ -168,9 +168,9 @@ out:
|
|||
return result;
|
||||
}
|
||||
|
||||
asmlinkage unsigned long
|
||||
sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
|
||||
unsigned long flags, unsigned long fd, unsigned long pgoff)
|
||||
SYSCALL_DEFINE6(mips_mmap2, unsigned long, addr, unsigned long, len,
|
||||
unsigned long, prot, unsigned long, flags, unsigned long, fd,
|
||||
unsigned long, pgoff)
|
||||
{
|
||||
if (pgoff & (~PAGE_MASK >> 12))
|
||||
return -EINVAL;
|
||||
|
@ -240,7 +240,7 @@ out:
|
|||
/*
|
||||
* Compacrapability ...
|
||||
*/
|
||||
asmlinkage int sys_uname(struct old_utsname __user * name)
|
||||
SYSCALL_DEFINE1(uname, struct old_utsname __user *, name)
|
||||
{
|
||||
if (name && !copy_to_user(name, utsname(), sizeof (*name)))
|
||||
return 0;
|
||||
|
@ -250,7 +250,7 @@ asmlinkage int sys_uname(struct old_utsname __user * name)
|
|||
/*
|
||||
* Compacrapability ...
|
||||
*/
|
||||
asmlinkage int sys_olduname(struct oldold_utsname __user * name)
|
||||
SYSCALL_DEFINE1(olduname, struct oldold_utsname __user *, name)
|
||||
{
|
||||
int error;
|
||||
|
||||
|
@ -279,7 +279,7 @@ asmlinkage int sys_olduname(struct oldold_utsname __user * name)
|
|||
return error;
|
||||
}
|
||||
|
||||
asmlinkage int sys_set_thread_area(unsigned long addr)
|
||||
SYSCALL_DEFINE1(set_thread_area, unsigned long, addr)
|
||||
{
|
||||
struct thread_info *ti = task_thread_info(current);
|
||||
|
||||
|
@ -290,7 +290,7 @@ asmlinkage int sys_set_thread_area(unsigned long addr)
|
|||
return 0;
|
||||
}
|
||||
|
||||
asmlinkage int _sys_sysmips(int cmd, long arg1, int arg2, int arg3)
|
||||
asmlinkage int _sys_sysmips(long cmd, long arg1, long arg2, long arg3)
|
||||
{
|
||||
switch (cmd) {
|
||||
case MIPS_ATOMIC_SET:
|
||||
|
@ -325,8 +325,8 @@ asmlinkage int _sys_sysmips(int cmd, long arg1, int arg2, int arg3)
|
|||
*
|
||||
* This is really horribly ugly.
|
||||
*/
|
||||
asmlinkage int sys_ipc(unsigned int call, int first, int second,
|
||||
unsigned long third, void __user *ptr, long fifth)
|
||||
SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, int, second,
|
||||
unsigned long, third, void __user *, ptr, long, fifth)
|
||||
{
|
||||
int version, ret;
|
||||
|
||||
|
@ -411,7 +411,7 @@ asmlinkage int sys_ipc(unsigned int call, int first, int second,
|
|||
/*
|
||||
* No implemented yet ...
|
||||
*/
|
||||
asmlinkage int sys_cachectl(char *addr, int nbytes, int op)
|
||||
SYSCALL_DEFINE3(cachectl, char *, addr, int, nbytes, int, op)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <linux/linkage.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
|
@ -58,8 +59,8 @@ EXPORT_SYMBOL(_dma_cache_wback_inv);
|
|||
* We could optimize the case where the cache argument is not BCACHE but
|
||||
* that seems very atypical use ...
|
||||
*/
|
||||
asmlinkage int sys_cacheflush(unsigned long addr,
|
||||
unsigned long bytes, unsigned int cache)
|
||||
SYSCALL_DEFINE3(cacheflush, unsigned long, addr, unsigned long, bytes,
|
||||
unsigned int, cache)
|
||||
{
|
||||
if (bytes == 0)
|
||||
return 0;
|
||||
|
|
|
@ -204,6 +204,23 @@ static int __init ppc4xx_setup_one_pci_PMM(struct pci_controller *hose,
|
|||
{
|
||||
u32 ma, pcila, pciha;
|
||||
|
||||
/* Hack warning ! The "old" PCI 2.x cell only let us configure the low
|
||||
* 32-bit of incoming PLB addresses. The top 4 bits of the 36-bit
|
||||
* address are actually hard wired to a value that appears to depend
|
||||
* on the specific SoC. For example, it's 0 on 440EP and 1 on 440EPx.
|
||||
*
|
||||
* The trick here is we just crop those top bits and ignore them when
|
||||
* programming the chip. That means the device-tree has to be right
|
||||
* for the specific part used (we don't print a warning if it's wrong
|
||||
* but on the other hand, you'll crash quickly enough), but at least
|
||||
* this code should work whatever the hard coded value is
|
||||
*/
|
||||
plb_addr &= 0xffffffffull;
|
||||
|
||||
/* Note: Due to the above hack, the test below doesn't actually test
|
||||
* if you address is above 4G, but it tests that address and
|
||||
* (address + size) are both contained in the same 4G
|
||||
*/
|
||||
if ((plb_addr + size) > 0xffffffffull || !is_power_of_2(size) ||
|
||||
size < 0x1000 || (plb_addr & (size - 1)) != 0) {
|
||||
printk(KERN_WARNING "%s: Resource out of range\n",
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#include <linux/gpio.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/spi/spi_gpio.h>
|
||||
#include <media/ov772x.h>
|
||||
#include <media/soc_camera_platform.h>
|
||||
#include <media/sh_mobile_ceu.h>
|
||||
#include <video/sh_mobile_lcdc.h>
|
||||
|
@ -224,7 +223,6 @@ static void camera_power(int val)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_I2C
|
||||
/* support for the old ncm03j camera */
|
||||
static unsigned char camera_ncm03j_magic[] =
|
||||
{
|
||||
0x87, 0x00, 0x88, 0x08, 0x89, 0x01, 0x8A, 0xE8,
|
||||
|
@ -245,23 +243,6 @@ static unsigned char camera_ncm03j_magic[] =
|
|||
0x63, 0xD4, 0x64, 0xEA, 0xD6, 0x0F,
|
||||
};
|
||||
|
||||
static int camera_probe(void)
|
||||
{
|
||||
struct i2c_adapter *a = i2c_get_adapter(0);
|
||||
struct i2c_msg msg;
|
||||
int ret;
|
||||
|
||||
camera_power(1);
|
||||
msg.addr = 0x6e;
|
||||
msg.buf = camera_ncm03j_magic;
|
||||
msg.len = 2;
|
||||
msg.flags = 0;
|
||||
ret = i2c_transfer(a, &msg, 1);
|
||||
camera_power(0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int camera_set_capture(struct soc_camera_platform_info *info,
|
||||
int enable)
|
||||
{
|
||||
|
@ -313,35 +294,8 @@ static struct platform_device camera_device = {
|
|||
.platform_data = &camera_info,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init camera_setup(void)
|
||||
{
|
||||
if (camera_probe() > 0)
|
||||
platform_device_register(&camera_device);
|
||||
|
||||
return 0;
|
||||
}
|
||||
late_initcall(camera_setup);
|
||||
|
||||
#endif /* CONFIG_I2C */
|
||||
|
||||
static int ov7725_power(struct device *dev, int mode)
|
||||
{
|
||||
camera_power(0);
|
||||
if (mode)
|
||||
camera_power(1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ov772x_camera_info ov7725_info = {
|
||||
.buswidth = SOCAM_DATAWIDTH_8,
|
||||
.flags = OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP,
|
||||
.link = {
|
||||
.power = ov7725_power,
|
||||
},
|
||||
};
|
||||
|
||||
static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
|
||||
.flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH |
|
||||
SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8,
|
||||
|
@ -392,6 +346,9 @@ static struct platform_device *ap325rxa_devices[] __initdata = {
|
|||
&ap325rxa_nor_flash_device,
|
||||
&lcdc_device,
|
||||
&ceu_device,
|
||||
#ifdef CONFIG_I2C
|
||||
&camera_device,
|
||||
#endif
|
||||
&nand_flash_device,
|
||||
&sdcard_cn3_device,
|
||||
};
|
||||
|
@ -400,10 +357,6 @@ static struct i2c_board_info __initdata ap325rxa_i2c_devices[] = {
|
|||
{
|
||||
I2C_BOARD_INFO("pcf8563", 0x51),
|
||||
},
|
||||
{
|
||||
I2C_BOARD_INFO("ov772x", 0x21),
|
||||
.platform_data = &ov7725_info,
|
||||
},
|
||||
};
|
||||
|
||||
static struct spi_board_info ap325rxa_spi_devices[] = {
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
#include <asm/freq.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
const static int pll1rate[]={1,2,3,4,6,8};
|
||||
const static int pfc_divisors[]={1,2,3,4,6,8,12};
|
||||
static const int pll1rate[]={1,2,3,4,6,8};
|
||||
static const int pfc_divisors[]={1,2,3,4,6,8,12};
|
||||
#define ifc_divisors pfc_divisors
|
||||
|
||||
#if (CONFIG_SH_CLK_MD == 0)
|
||||
|
|
|
@ -1804,7 +1804,7 @@ config DMAR
|
|||
remapping devices.
|
||||
|
||||
config DMAR_DEFAULT_ON
|
||||
def_bool n
|
||||
def_bool y
|
||||
prompt "Enable DMA Remapping Devices by default"
|
||||
depends on DMAR
|
||||
help
|
||||
|
|
|
@ -23,6 +23,9 @@
|
|||
#include <asm/pgtable.h>
|
||||
#include <asm/tlbflush.h>
|
||||
|
||||
int
|
||||
is_io_mapping_possible(resource_size_t base, unsigned long size);
|
||||
|
||||
void *
|
||||
iomap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot);
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ static volatile unsigned long smp_invalidate_needed;
|
|||
|
||||
/* Bitmask of CPUs present in the system - exported by i386_syms.c, used
|
||||
* by scheduler but indexed physically */
|
||||
cpumask_t phys_cpu_present_map = CPU_MASK_NONE;
|
||||
static cpumask_t voyager_phys_cpu_present_map = CPU_MASK_NONE;
|
||||
|
||||
/* The internal functions */
|
||||
static void send_CPI(__u32 cpuset, __u8 cpi);
|
||||
|
@ -366,19 +366,19 @@ void __init find_smp_config(void)
|
|||
/* set up everything for just this CPU, we can alter
|
||||
* this as we start the other CPUs later */
|
||||
/* now get the CPU disposition from the extended CMOS */
|
||||
cpus_addr(phys_cpu_present_map)[0] =
|
||||
cpus_addr(voyager_phys_cpu_present_map)[0] =
|
||||
voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK);
|
||||
cpus_addr(phys_cpu_present_map)[0] |=
|
||||
cpus_addr(voyager_phys_cpu_present_map)[0] |=
|
||||
voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 1) << 8;
|
||||
cpus_addr(phys_cpu_present_map)[0] |=
|
||||
cpus_addr(voyager_phys_cpu_present_map)[0] |=
|
||||
voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK +
|
||||
2) << 16;
|
||||
cpus_addr(phys_cpu_present_map)[0] |=
|
||||
cpus_addr(voyager_phys_cpu_present_map)[0] |=
|
||||
voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK +
|
||||
3) << 24;
|
||||
init_cpu_possible(&phys_cpu_present_map);
|
||||
printk("VOYAGER SMP: phys_cpu_present_map = 0x%lx\n",
|
||||
cpus_addr(phys_cpu_present_map)[0]);
|
||||
init_cpu_possible(&voyager_phys_cpu_present_map);
|
||||
printk("VOYAGER SMP: voyager_phys_cpu_present_map = 0x%lx\n",
|
||||
cpus_addr(voyager_phys_cpu_present_map)[0]);
|
||||
/* Here we set up the VIC to enable SMP */
|
||||
/* enable the CPIs by writing the base vector to their register */
|
||||
outb(VIC_DEFAULT_CPI_BASE, VIC_CPI_BASE_REGISTER);
|
||||
|
@ -628,15 +628,15 @@ void __init smp_boot_cpus(void)
|
|||
/* now that the cat has probed the Voyager System Bus, sanity
|
||||
* check the cpu map */
|
||||
if (((voyager_quad_processors | voyager_extended_vic_processors)
|
||||
& cpus_addr(phys_cpu_present_map)[0]) !=
|
||||
cpus_addr(phys_cpu_present_map)[0]) {
|
||||
& cpus_addr(voyager_phys_cpu_present_map)[0]) !=
|
||||
cpus_addr(voyager_phys_cpu_present_map)[0]) {
|
||||
/* should panic */
|
||||
printk("\n\n***WARNING*** "
|
||||
"Sanity check of CPU present map FAILED\n");
|
||||
}
|
||||
} else if (voyager_level == 4)
|
||||
voyager_extended_vic_processors =
|
||||
cpus_addr(phys_cpu_present_map)[0];
|
||||
cpus_addr(voyager_phys_cpu_present_map)[0];
|
||||
|
||||
/* this sets up the idle task to run on the current cpu */
|
||||
voyager_extended_cpus = 1;
|
||||
|
@ -670,7 +670,7 @@ void __init smp_boot_cpus(void)
|
|||
/* loop over all the extended VIC CPUs and boot them. The
|
||||
* Quad CPUs must be bootstrapped by their extended VIC cpu */
|
||||
for (i = 0; i < nr_cpu_ids; i++) {
|
||||
if (i == boot_cpu_id || !cpu_isset(i, phys_cpu_present_map))
|
||||
if (i == boot_cpu_id || !cpu_isset(i, voyager_phys_cpu_present_map))
|
||||
continue;
|
||||
do_boot_cpu(i);
|
||||
/* This udelay seems to be needed for the Quad boots
|
||||
|
|
|
@ -20,6 +20,24 @@
|
|||
#include <asm/pat.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#ifdef CONFIG_X86_PAE
|
||||
int
|
||||
is_io_mapping_possible(resource_size_t base, unsigned long size)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
int
|
||||
is_io_mapping_possible(resource_size_t base, unsigned long size)
|
||||
{
|
||||
/* There is no way to map greater than 1 << 32 address without PAE */
|
||||
if (base + size > 0x100000000ULL)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Map 'pfn' using fixed map 'type' and protections 'prot'
|
||||
*/
|
||||
void *
|
||||
|
|
|
@ -32,11 +32,14 @@ struct kmmio_fault_page {
|
|||
struct list_head list;
|
||||
struct kmmio_fault_page *release_next;
|
||||
unsigned long page; /* location of the fault page */
|
||||
bool old_presence; /* page presence prior to arming */
|
||||
bool armed;
|
||||
|
||||
/*
|
||||
* Number of times this page has been registered as a part
|
||||
* of a probe. If zero, page is disarmed and this may be freed.
|
||||
* Used only by writers (RCU).
|
||||
* Used only by writers (RCU) and post_kmmio_handler().
|
||||
* Protected by kmmio_lock, when linked into kmmio_page_table.
|
||||
*/
|
||||
int count;
|
||||
};
|
||||
|
@ -105,57 +108,85 @@ static struct kmmio_fault_page *get_kmmio_fault_page(unsigned long page)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void set_page_present(unsigned long addr, bool present,
|
||||
unsigned int *pglevel)
|
||||
static void set_pmd_presence(pmd_t *pmd, bool present, bool *old)
|
||||
{
|
||||
pmdval_t v = pmd_val(*pmd);
|
||||
*old = !!(v & _PAGE_PRESENT);
|
||||
v &= ~_PAGE_PRESENT;
|
||||
if (present)
|
||||
v |= _PAGE_PRESENT;
|
||||
set_pmd(pmd, __pmd(v));
|
||||
}
|
||||
|
||||
static void set_pte_presence(pte_t *pte, bool present, bool *old)
|
||||
{
|
||||
pteval_t v = pte_val(*pte);
|
||||
*old = !!(v & _PAGE_PRESENT);
|
||||
v &= ~_PAGE_PRESENT;
|
||||
if (present)
|
||||
v |= _PAGE_PRESENT;
|
||||
set_pte_atomic(pte, __pte(v));
|
||||
}
|
||||
|
||||
static int set_page_presence(unsigned long addr, bool present, bool *old)
|
||||
{
|
||||
pteval_t pteval;
|
||||
pmdval_t pmdval;
|
||||
unsigned int level;
|
||||
pmd_t *pmd;
|
||||
pte_t *pte = lookup_address(addr, &level);
|
||||
|
||||
if (!pte) {
|
||||
pr_err("kmmio: no pte for page 0x%08lx\n", addr);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pglevel)
|
||||
*pglevel = level;
|
||||
|
||||
switch (level) {
|
||||
case PG_LEVEL_2M:
|
||||
pmd = (pmd_t *)pte;
|
||||
pmdval = pmd_val(*pmd) & ~_PAGE_PRESENT;
|
||||
if (present)
|
||||
pmdval |= _PAGE_PRESENT;
|
||||
set_pmd(pmd, __pmd(pmdval));
|
||||
set_pmd_presence((pmd_t *)pte, present, old);
|
||||
break;
|
||||
|
||||
case PG_LEVEL_4K:
|
||||
pteval = pte_val(*pte) & ~_PAGE_PRESENT;
|
||||
if (present)
|
||||
pteval |= _PAGE_PRESENT;
|
||||
set_pte_atomic(pte, __pte(pteval));
|
||||
set_pte_presence(pte, present, old);
|
||||
break;
|
||||
|
||||
default:
|
||||
pr_err("kmmio: unexpected page level 0x%x.\n", level);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
__flush_tlb_one(addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Mark the given page as not present. Access to it will trigger a fault. */
|
||||
static void arm_kmmio_fault_page(unsigned long page, unsigned int *pglevel)
|
||||
/*
|
||||
* Mark the given page as not present. Access to it will trigger a fault.
|
||||
*
|
||||
* Struct kmmio_fault_page is protected by RCU and kmmio_lock, but the
|
||||
* protection is ignored here. RCU read lock is assumed held, so the struct
|
||||
* will not disappear unexpectedly. Furthermore, the caller must guarantee,
|
||||
* that double arming the same virtual address (page) cannot occur.
|
||||
*
|
||||
* Double disarming on the other hand is allowed, and may occur when a fault
|
||||
* and mmiotrace shutdown happen simultaneously.
|
||||
*/
|
||||
static int arm_kmmio_fault_page(struct kmmio_fault_page *f)
|
||||
{
|
||||
set_page_present(page & PAGE_MASK, false, pglevel);
|
||||
int ret;
|
||||
WARN_ONCE(f->armed, KERN_ERR "kmmio page already armed.\n");
|
||||
if (f->armed) {
|
||||
pr_warning("kmmio double-arm: page 0x%08lx, ref %d, old %d\n",
|
||||
f->page, f->count, f->old_presence);
|
||||
}
|
||||
ret = set_page_presence(f->page, false, &f->old_presence);
|
||||
WARN_ONCE(ret < 0, KERN_ERR "kmmio arming 0x%08lx failed.\n", f->page);
|
||||
f->armed = true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Mark the given page as present. */
|
||||
static void disarm_kmmio_fault_page(unsigned long page, unsigned int *pglevel)
|
||||
/** Restore the given page to saved presence state. */
|
||||
static void disarm_kmmio_fault_page(struct kmmio_fault_page *f)
|
||||
{
|
||||
set_page_present(page & PAGE_MASK, true, pglevel);
|
||||
bool tmp;
|
||||
int ret = set_page_presence(f->page, f->old_presence, &tmp);
|
||||
WARN_ONCE(ret < 0,
|
||||
KERN_ERR "kmmio disarming 0x%08lx failed.\n", f->page);
|
||||
f->armed = false;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -202,28 +233,32 @@ int kmmio_handler(struct pt_regs *regs, unsigned long addr)
|
|||
|
||||
ctx = &get_cpu_var(kmmio_ctx);
|
||||
if (ctx->active) {
|
||||
disarm_kmmio_fault_page(faultpage->page, NULL);
|
||||
if (addr == ctx->addr) {
|
||||
/*
|
||||
* On SMP we sometimes get recursive probe hits on the
|
||||
* same address. Context is already saved, fall out.
|
||||
* A second fault on the same page means some other
|
||||
* condition needs handling by do_page_fault(), the
|
||||
* page really not being present is the most common.
|
||||
*/
|
||||
pr_debug("kmmio: duplicate probe hit on CPU %d, for "
|
||||
"address 0x%08lx.\n",
|
||||
smp_processor_id(), addr);
|
||||
ret = 1;
|
||||
goto no_kmmio_ctx;
|
||||
}
|
||||
/*
|
||||
* Prevent overwriting already in-flight context.
|
||||
* This should not happen, let's hope disarming at least
|
||||
* prevents a panic.
|
||||
*/
|
||||
pr_emerg("kmmio: recursive probe hit on CPU %d, "
|
||||
pr_debug("kmmio: secondary hit for 0x%08lx CPU %d.\n",
|
||||
addr, smp_processor_id());
|
||||
|
||||
if (!faultpage->old_presence)
|
||||
pr_info("kmmio: unexpected secondary hit for "
|
||||
"address 0x%08lx on CPU %d.\n", addr,
|
||||
smp_processor_id());
|
||||
} else {
|
||||
/*
|
||||
* Prevent overwriting already in-flight context.
|
||||
* This should not happen, let's hope disarming at
|
||||
* least prevents a panic.
|
||||
*/
|
||||
pr_emerg("kmmio: recursive probe hit on CPU %d, "
|
||||
"for address 0x%08lx. Ignoring.\n",
|
||||
smp_processor_id(), addr);
|
||||
pr_emerg("kmmio: previous hit was at 0x%08lx.\n",
|
||||
ctx->addr);
|
||||
pr_emerg("kmmio: previous hit was at 0x%08lx.\n",
|
||||
ctx->addr);
|
||||
disarm_kmmio_fault_page(faultpage);
|
||||
}
|
||||
goto no_kmmio_ctx;
|
||||
}
|
||||
ctx->active++;
|
||||
|
@ -244,7 +279,7 @@ int kmmio_handler(struct pt_regs *regs, unsigned long addr)
|
|||
regs->flags &= ~X86_EFLAGS_IF;
|
||||
|
||||
/* Now we set present bit in PTE and single step. */
|
||||
disarm_kmmio_fault_page(ctx->fpage->page, NULL);
|
||||
disarm_kmmio_fault_page(ctx->fpage);
|
||||
|
||||
/*
|
||||
* If another cpu accesses the same page while we are stepping,
|
||||
|
@ -275,7 +310,7 @@ static int post_kmmio_handler(unsigned long condition, struct pt_regs *regs)
|
|||
struct kmmio_context *ctx = &get_cpu_var(kmmio_ctx);
|
||||
|
||||
if (!ctx->active) {
|
||||
pr_debug("kmmio: spurious debug trap on CPU %d.\n",
|
||||
pr_warning("kmmio: spurious debug trap on CPU %d.\n",
|
||||
smp_processor_id());
|
||||
goto out;
|
||||
}
|
||||
|
@ -283,7 +318,11 @@ static int post_kmmio_handler(unsigned long condition, struct pt_regs *regs)
|
|||
if (ctx->probe && ctx->probe->post_handler)
|
||||
ctx->probe->post_handler(ctx->probe, condition, regs);
|
||||
|
||||
arm_kmmio_fault_page(ctx->fpage->page, NULL);
|
||||
/* Prevent racing against release_kmmio_fault_page(). */
|
||||
spin_lock(&kmmio_lock);
|
||||
if (ctx->fpage->count)
|
||||
arm_kmmio_fault_page(ctx->fpage);
|
||||
spin_unlock(&kmmio_lock);
|
||||
|
||||
regs->flags &= ~X86_EFLAGS_TF;
|
||||
regs->flags |= ctx->saved_flags;
|
||||
|
@ -315,20 +354,24 @@ static int add_kmmio_fault_page(unsigned long page)
|
|||
f = get_kmmio_fault_page(page);
|
||||
if (f) {
|
||||
if (!f->count)
|
||||
arm_kmmio_fault_page(f->page, NULL);
|
||||
arm_kmmio_fault_page(f);
|
||||
f->count++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
f = kmalloc(sizeof(*f), GFP_ATOMIC);
|
||||
f = kzalloc(sizeof(*f), GFP_ATOMIC);
|
||||
if (!f)
|
||||
return -1;
|
||||
|
||||
f->count = 1;
|
||||
f->page = page;
|
||||
list_add_rcu(&f->list, kmmio_page_list(f->page));
|
||||
|
||||
arm_kmmio_fault_page(f->page, NULL);
|
||||
if (arm_kmmio_fault_page(f)) {
|
||||
kfree(f);
|
||||
return -1;
|
||||
}
|
||||
|
||||
list_add_rcu(&f->list, kmmio_page_list(f->page));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -347,7 +390,7 @@ static void release_kmmio_fault_page(unsigned long page,
|
|||
f->count--;
|
||||
BUG_ON(f->count < 0);
|
||||
if (!f->count) {
|
||||
disarm_kmmio_fault_page(f->page, NULL);
|
||||
disarm_kmmio_fault_page(f);
|
||||
f->release_next = *release_list;
|
||||
*release_list = f;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Written by Pekka Paalanen, 2008 <pq@iki.fi>
|
||||
* Written by Pekka Paalanen, 2008-2009 <pq@iki.fi>
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/io.h>
|
||||
|
@ -9,35 +9,74 @@
|
|||
|
||||
static unsigned long mmio_address;
|
||||
module_param(mmio_address, ulong, 0);
|
||||
MODULE_PARM_DESC(mmio_address, "Start address of the mapping of 16 kB.");
|
||||
MODULE_PARM_DESC(mmio_address, " Start address of the mapping of 16 kB "
|
||||
"(or 8 MB if read_far is non-zero).");
|
||||
|
||||
static unsigned long read_far = 0x400100;
|
||||
module_param(read_far, ulong, 0);
|
||||
MODULE_PARM_DESC(read_far, " Offset of a 32-bit read within 8 MB "
|
||||
"(default: 0x400100).");
|
||||
|
||||
static unsigned v16(unsigned i)
|
||||
{
|
||||
return i * 12 + 7;
|
||||
}
|
||||
|
||||
static unsigned v32(unsigned i)
|
||||
{
|
||||
return i * 212371 + 13;
|
||||
}
|
||||
|
||||
static void do_write_test(void __iomem *p)
|
||||
{
|
||||
unsigned int i;
|
||||
pr_info(MODULE_NAME ": write test.\n");
|
||||
mmiotrace_printk("Write test.\n");
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
iowrite8(i, p + i);
|
||||
|
||||
for (i = 1024; i < (5 * 1024); i += 2)
|
||||
iowrite16(i * 12 + 7, p + i);
|
||||
iowrite16(v16(i), p + i);
|
||||
|
||||
for (i = (5 * 1024); i < (16 * 1024); i += 4)
|
||||
iowrite32(i * 212371 + 13, p + i);
|
||||
iowrite32(v32(i), p + i);
|
||||
}
|
||||
|
||||
static void do_read_test(void __iomem *p)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned errs[3] = { 0 };
|
||||
pr_info(MODULE_NAME ": read test.\n");
|
||||
mmiotrace_printk("Read test.\n");
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
ioread8(p + i);
|
||||
if (ioread8(p + i) != i)
|
||||
++errs[0];
|
||||
|
||||
for (i = 1024; i < (5 * 1024); i += 2)
|
||||
ioread16(p + i);
|
||||
if (ioread16(p + i) != v16(i))
|
||||
++errs[1];
|
||||
|
||||
for (i = (5 * 1024); i < (16 * 1024); i += 4)
|
||||
ioread32(p + i);
|
||||
if (ioread32(p + i) != v32(i))
|
||||
++errs[2];
|
||||
|
||||
mmiotrace_printk("Read errors: 8-bit %d, 16-bit %d, 32-bit %d.\n",
|
||||
errs[0], errs[1], errs[2]);
|
||||
}
|
||||
|
||||
static void do_test(void)
|
||||
static void do_read_far_test(void __iomem *p)
|
||||
{
|
||||
void __iomem *p = ioremap_nocache(mmio_address, 0x4000);
|
||||
pr_info(MODULE_NAME ": read far test.\n");
|
||||
mmiotrace_printk("Read far test.\n");
|
||||
|
||||
ioread32(p + read_far);
|
||||
}
|
||||
|
||||
static void do_test(unsigned long size)
|
||||
{
|
||||
void __iomem *p = ioremap_nocache(mmio_address, size);
|
||||
if (!p) {
|
||||
pr_err(MODULE_NAME ": could not ioremap, aborting.\n");
|
||||
return;
|
||||
|
@ -45,11 +84,15 @@ static void do_test(void)
|
|||
mmiotrace_printk("ioremap returned %p.\n", p);
|
||||
do_write_test(p);
|
||||
do_read_test(p);
|
||||
if (read_far && read_far < size - 4)
|
||||
do_read_far_test(p);
|
||||
iounmap(p);
|
||||
}
|
||||
|
||||
static int __init init(void)
|
||||
{
|
||||
unsigned long size = (read_far) ? (8 << 20) : (16 << 10);
|
||||
|
||||
if (mmio_address == 0) {
|
||||
pr_err(MODULE_NAME ": you have to use the module argument "
|
||||
"mmio_address.\n");
|
||||
|
@ -58,10 +101,11 @@ static int __init init(void)
|
|||
return -ENXIO;
|
||||
}
|
||||
|
||||
pr_warning(MODULE_NAME ": WARNING: mapping 16 kB @ 0x%08lx "
|
||||
"in PCI address space, and writing "
|
||||
"rubbish in there.\n", mmio_address);
|
||||
do_test();
|
||||
pr_warning(MODULE_NAME ": WARNING: mapping %lu kB @ 0x%08lx in PCI "
|
||||
"address space, and writing 16 kB of rubbish in there.\n",
|
||||
size >> 10, mmio_address);
|
||||
do_test(size);
|
||||
pr_info(MODULE_NAME ": All done.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1672,6 +1672,9 @@ asmlinkage void __init xen_start_kernel(void)
|
|||
possible map and a non-dummy shared_info. */
|
||||
per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0];
|
||||
|
||||
local_irq_disable();
|
||||
early_boot_irqs_off();
|
||||
|
||||
xen_raw_console_write("mapping kernel into physical memory\n");
|
||||
pgd = xen_setup_kernel_pagetable(pgd, xen_start_info->nr_pages);
|
||||
|
||||
|
|
|
@ -1090,6 +1090,11 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
|
|||
dev_priv->mm.gtt_mapping =
|
||||
io_mapping_create_wc(dev->agp->base,
|
||||
dev->agp->agp_info.aper_size * 1024*1024);
|
||||
if (dev_priv->mm.gtt_mapping == NULL) {
|
||||
ret = -EIO;
|
||||
goto out_rmmap;
|
||||
}
|
||||
|
||||
/* Set up a WC MTRR for non-PAT systems. This is more common than
|
||||
* one would think, because the kernel disables PAT on first
|
||||
* generation Core chips because WC PAT gets overridden by a UC
|
||||
|
@ -1122,7 +1127,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
|
|||
if (!I915_NEED_GFX_HWS(dev)) {
|
||||
ret = i915_init_phys_hws(dev);
|
||||
if (ret != 0)
|
||||
goto out_rmmap;
|
||||
goto out_iomapfree;
|
||||
}
|
||||
|
||||
/* On the 945G/GM, the chipset reports the MSI capability on the
|
||||
|
@ -1161,6 +1166,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
|
|||
|
||||
return 0;
|
||||
|
||||
out_iomapfree:
|
||||
io_mapping_free(dev_priv->mm.gtt_mapping);
|
||||
out_rmmap:
|
||||
iounmap(dev_priv->regs);
|
||||
free_priv:
|
||||
|
|
|
@ -192,6 +192,7 @@ int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *d
|
|||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(flexcop_pid_feed_control);
|
||||
|
||||
void flexcop_hw_filter_init(struct flexcop_device *fc)
|
||||
{
|
||||
|
|
|
@ -13,9 +13,9 @@ static int enable_pid_filtering = 1;
|
|||
module_param(enable_pid_filtering, int, 0444);
|
||||
MODULE_PARM_DESC(enable_pid_filtering, "enable hardware pid filtering: supported values: 0 (fullts), 1");
|
||||
|
||||
static int irq_chk_intv;
|
||||
static int irq_chk_intv = 100;
|
||||
module_param(irq_chk_intv, int, 0644);
|
||||
MODULE_PARM_DESC(irq_chk_intv, "set the interval for IRQ watchdog (currently just debugging).");
|
||||
MODULE_PARM_DESC(irq_chk_intv, "set the interval for IRQ streaming watchdog.");
|
||||
|
||||
#ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG
|
||||
#define dprintk(level,args...) \
|
||||
|
@ -34,7 +34,9 @@ MODULE_PARM_DESC(irq_chk_intv, "set the interval for IRQ watchdog (currently jus
|
|||
|
||||
static int debug;
|
||||
module_param(debug, int, 0644);
|
||||
MODULE_PARM_DESC(debug, "set debug level (1=info,2=regs,4=TS,8=irqdma (|-able))." DEBSTATUS);
|
||||
MODULE_PARM_DESC(debug,
|
||||
"set debug level (1=info,2=regs,4=TS,8=irqdma,16=check (|-able))."
|
||||
DEBSTATUS);
|
||||
|
||||
#define DRIVER_VERSION "0.1"
|
||||
#define DRIVER_NAME "Technisat/B2C2 FlexCop II/IIb/III Digital TV PCI Driver"
|
||||
|
@ -58,6 +60,8 @@ struct flexcop_pci {
|
|||
int active_dma1_addr; /* 0 = addr0 of dma1; 1 = addr1 of dma1 */
|
||||
u32 last_dma1_cur_pos; /* position of the pointer last time the timer/packet irq occured */
|
||||
int count;
|
||||
int count_prev;
|
||||
int stream_problem;
|
||||
|
||||
spinlock_t irq_lock;
|
||||
|
||||
|
@ -103,18 +107,32 @@ static void flexcop_pci_irq_check_work(struct work_struct *work)
|
|||
container_of(work, struct flexcop_pci, irq_check_work.work);
|
||||
struct flexcop_device *fc = fc_pci->fc_dev;
|
||||
|
||||
flexcop_ibi_value v = fc->read_ibi_reg(fc,sram_dest_reg_714);
|
||||
if (fc->feedcount) {
|
||||
|
||||
flexcop_dump_reg(fc_pci->fc_dev,dma1_000,4);
|
||||
if (fc_pci->count == fc_pci->count_prev) {
|
||||
deb_chk("no IRQ since the last check\n");
|
||||
if (fc_pci->stream_problem++ == 3) {
|
||||
struct dvb_demux_feed *feed;
|
||||
|
||||
if (v.sram_dest_reg_714.net_ovflow_error)
|
||||
deb_chk("sram net_ovflow_error\n");
|
||||
if (v.sram_dest_reg_714.media_ovflow_error)
|
||||
deb_chk("sram media_ovflow_error\n");
|
||||
if (v.sram_dest_reg_714.cai_ovflow_error)
|
||||
deb_chk("sram cai_ovflow_error\n");
|
||||
if (v.sram_dest_reg_714.cai_ovflow_error)
|
||||
deb_chk("sram cai_ovflow_error\n");
|
||||
spin_lock_irq(&fc->demux.lock);
|
||||
list_for_each_entry(feed, &fc->demux.feed_list,
|
||||
list_head) {
|
||||
flexcop_pid_feed_control(fc, feed, 0);
|
||||
}
|
||||
|
||||
list_for_each_entry(feed, &fc->demux.feed_list,
|
||||
list_head) {
|
||||
flexcop_pid_feed_control(fc, feed, 1);
|
||||
}
|
||||
spin_unlock_irq(&fc->demux.lock);
|
||||
|
||||
fc_pci->stream_problem = 0;
|
||||
}
|
||||
} else {
|
||||
fc_pci->stream_problem = 0;
|
||||
fc_pci->count_prev = fc_pci->count;
|
||||
}
|
||||
}
|
||||
|
||||
schedule_delayed_work(&fc_pci->irq_check_work,
|
||||
msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv));
|
||||
|
@ -216,16 +234,12 @@ static int flexcop_pci_stream_control(struct flexcop_device *fc, int onoff)
|
|||
flexcop_dma_control_timer_irq(fc,FC_DMA_1,1);
|
||||
deb_irq("IRQ enabled\n");
|
||||
|
||||
fc_pci->count_prev = fc_pci->count;
|
||||
|
||||
// fc_pci->active_dma1_addr = 0;
|
||||
// flexcop_dma_control_size_irq(fc,FC_DMA_1,1);
|
||||
|
||||
if (irq_chk_intv > 0)
|
||||
schedule_delayed_work(&fc_pci->irq_check_work,
|
||||
msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv));
|
||||
} else {
|
||||
if (irq_chk_intv > 0)
|
||||
cancel_delayed_work(&fc_pci->irq_check_work);
|
||||
|
||||
flexcop_dma_control_timer_irq(fc,FC_DMA_1,0);
|
||||
deb_irq("IRQ disabled\n");
|
||||
|
||||
|
@ -299,8 +313,6 @@ static int flexcop_pci_init(struct flexcop_pci *fc_pci)
|
|||
IRQF_SHARED, DRIVER_NAME, fc_pci)) != 0)
|
||||
goto err_pci_iounmap;
|
||||
|
||||
|
||||
|
||||
fc_pci->init_state |= FC_PCI_INIT;
|
||||
return ret;
|
||||
|
||||
|
@ -375,6 +387,10 @@ static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
|
|||
|
||||
INIT_DELAYED_WORK(&fc_pci->irq_check_work, flexcop_pci_irq_check_work);
|
||||
|
||||
if (irq_chk_intv > 0)
|
||||
schedule_delayed_work(&fc_pci->irq_check_work,
|
||||
msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv));
|
||||
|
||||
return ret;
|
||||
|
||||
err_fc_exit:
|
||||
|
@ -393,6 +409,9 @@ static void flexcop_pci_remove(struct pci_dev *pdev)
|
|||
{
|
||||
struct flexcop_pci *fc_pci = pci_get_drvdata(pdev);
|
||||
|
||||
if (irq_chk_intv > 0)
|
||||
cancel_delayed_work(&fc_pci->irq_check_work);
|
||||
|
||||
flexcop_pci_dma_exit(fc_pci);
|
||||
flexcop_device_exit(fc_pci->fc_dev);
|
||||
flexcop_pci_exit(fc_pci);
|
||||
|
|
|
@ -212,8 +212,7 @@ void flexcop_reset_block_300(struct flexcop_device *fc)
|
|||
v210.sw_reset_210.Block_reset_enable = 0xb2;
|
||||
|
||||
fc->write_ibi_reg(fc,sw_reset_210,v210);
|
||||
msleep(1);
|
||||
|
||||
udelay(1000);
|
||||
fc->write_ibi_reg(fc,ctrl_208,v208_save);
|
||||
}
|
||||
|
||||
|
|
|
@ -463,6 +463,8 @@ static int em28xx_audio_init(struct em28xx *dev)
|
|||
pcm->info_flags = 0;
|
||||
pcm->private_data = dev;
|
||||
strcpy(pcm->name, "Empia 28xx Capture");
|
||||
|
||||
snd_card_set_dev(card, &dev->udev->dev);
|
||||
strcpy(card->driver, "Empia Em28xx Audio");
|
||||
strcpy(card->shortname, "Em28xx Audio");
|
||||
strcpy(card->longname, "Empia Em28xx Audio");
|
||||
|
|
|
@ -1155,24 +1155,24 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd,
|
|||
{
|
||||
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
|
||||
struct pxa_camera_dev *pcdev = ici->priv;
|
||||
const struct soc_camera_data_format *host_fmt, *cam_fmt = NULL;
|
||||
const struct soc_camera_format_xlate *xlate;
|
||||
const struct soc_camera_data_format *cam_fmt = NULL;
|
||||
const struct soc_camera_format_xlate *xlate = NULL;
|
||||
struct soc_camera_sense sense = {
|
||||
.master_clock = pcdev->mclk,
|
||||
.pixel_clock_max = pcdev->ciclk / 4,
|
||||
};
|
||||
int ret, buswidth;
|
||||
int ret;
|
||||
|
||||
xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
|
||||
if (!xlate) {
|
||||
dev_warn(&ici->dev, "Format %x not found\n", pixfmt);
|
||||
return -EINVAL;
|
||||
if (pixfmt) {
|
||||
xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
|
||||
if (!xlate) {
|
||||
dev_warn(&ici->dev, "Format %x not found\n", pixfmt);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
cam_fmt = xlate->cam_fmt;
|
||||
}
|
||||
|
||||
buswidth = xlate->buswidth;
|
||||
host_fmt = xlate->host_fmt;
|
||||
cam_fmt = xlate->cam_fmt;
|
||||
|
||||
/* If PCLK is used to latch data from the sensor, check sense */
|
||||
if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN)
|
||||
icd->sense = &sense;
|
||||
|
@ -1201,8 +1201,8 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd,
|
|||
}
|
||||
|
||||
if (pixfmt && !ret) {
|
||||
icd->buswidth = buswidth;
|
||||
icd->current_fmt = host_fmt;
|
||||
icd->buswidth = xlate->buswidth;
|
||||
icd->current_fmt = xlate->host_fmt;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -603,21 +603,18 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
|
|||
const struct soc_camera_format_xlate *xlate;
|
||||
int ret;
|
||||
|
||||
if (!pixfmt)
|
||||
return icd->ops->set_fmt(icd, pixfmt, rect);
|
||||
|
||||
xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
|
||||
if (!xlate) {
|
||||
dev_warn(&ici->dev, "Format %x not found\n", pixfmt);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (pixfmt) {
|
||||
case 0: /* Only geometry change */
|
||||
ret = icd->ops->set_fmt(icd, pixfmt, rect);
|
||||
break;
|
||||
default:
|
||||
ret = icd->ops->set_fmt(icd, xlate->cam_fmt->fourcc, rect);
|
||||
}
|
||||
ret = icd->ops->set_fmt(icd, xlate->cam_fmt->fourcc, rect);
|
||||
|
||||
if (pixfmt && !ret) {
|
||||
if (!ret) {
|
||||
icd->buswidth = xlate->buswidth;
|
||||
icd->current_fmt = xlate->host_fmt;
|
||||
pcdev->camera_fmt = xlate->cam_fmt;
|
||||
|
|
|
@ -710,6 +710,7 @@ out:
|
|||
|
||||
static struct pci_device_id ilo_devices[] = {
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_COMPAQ, 0xB204) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_HP, 0x3307) },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, ilo_devices);
|
||||
|
@ -758,7 +759,7 @@ static void __exit ilo_exit(void)
|
|||
class_destroy(ilo_class);
|
||||
}
|
||||
|
||||
MODULE_VERSION("0.06");
|
||||
MODULE_VERSION("1.0");
|
||||
MODULE_ALIAS(ILO_NAME);
|
||||
MODULE_DESCRIPTION(ILO_NAME);
|
||||
MODULE_AUTHOR("David Altobelli <david.altobelli@hp.com>");
|
||||
|
|
|
@ -19,6 +19,7 @@ static int maprom_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
|
|||
static int maprom_write (struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
|
||||
static void maprom_nop (struct mtd_info *);
|
||||
static struct mtd_info *map_rom_probe(struct map_info *map);
|
||||
static int maprom_erase (struct mtd_info *mtd, struct erase_info *info);
|
||||
|
||||
static struct mtd_chip_driver maprom_chipdrv = {
|
||||
.probe = map_rom_probe,
|
||||
|
@ -42,6 +43,7 @@ static struct mtd_info *map_rom_probe(struct map_info *map)
|
|||
mtd->read = maprom_read;
|
||||
mtd->write = maprom_write;
|
||||
mtd->sync = maprom_nop;
|
||||
mtd->erase = maprom_erase;
|
||||
mtd->flags = MTD_CAP_ROM;
|
||||
mtd->erasesize = map->size;
|
||||
mtd->writesize = 1;
|
||||
|
@ -71,6 +73,12 @@ static int maprom_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *re
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
static int maprom_erase (struct mtd_info *mtd, struct erase_info *info)
|
||||
{
|
||||
/* We do our best 8) */
|
||||
return -EROFS;
|
||||
}
|
||||
|
||||
static int __init map_rom_init(void)
|
||||
{
|
||||
register_mtd_chip_driver(&maprom_chipdrv);
|
||||
|
|
|
@ -267,22 +267,28 @@ static int parse_cmdline(char *devname, char *szstart, char *szlength)
|
|||
if (*(szlength) != '+') {
|
||||
devlength = simple_strtoul(szlength, &buffer, 0);
|
||||
devlength = handle_unit(devlength, buffer) - devstart;
|
||||
if (devlength < devstart)
|
||||
goto err_out;
|
||||
|
||||
devlength -= devstart;
|
||||
} else {
|
||||
devlength = simple_strtoul(szlength + 1, &buffer, 0);
|
||||
devlength = handle_unit(devlength, buffer);
|
||||
}
|
||||
T("slram: devname=%s, devstart=0x%lx, devlength=0x%lx\n",
|
||||
devname, devstart, devlength);
|
||||
if ((devstart < 0) || (devlength < 0) || (devlength % SLRAM_BLK_SZ != 0)) {
|
||||
E("slram: Illegal start / length parameter.\n");
|
||||
return(-EINVAL);
|
||||
}
|
||||
if (devlength % SLRAM_BLK_SZ != 0)
|
||||
goto err_out;
|
||||
|
||||
if ((devstart = register_device(devname, devstart, devlength))){
|
||||
unregister_devices();
|
||||
return((int)devstart);
|
||||
}
|
||||
return(0);
|
||||
|
||||
err_out:
|
||||
E("slram: Illegal length parameter.\n");
|
||||
return(-EINVAL);
|
||||
}
|
||||
|
||||
#ifndef MODULE
|
||||
|
|
|
@ -12,6 +12,7 @@ config MTD_LPDDR
|
|||
DDR memories, intended for battery-operated systems.
|
||||
|
||||
config MTD_QINFO_PROBE
|
||||
depends on MTD_LPDDR
|
||||
tristate "Detect flash chips by QINFO probe"
|
||||
help
|
||||
Device Information for LPDDR chips is offered through the Overlay
|
||||
|
|
|
@ -491,7 +491,7 @@ config MTD_PCMCIA_ANONYMOUS
|
|||
|
||||
config MTD_BFIN_ASYNC
|
||||
tristate "Blackfin BF533-STAMP Flash Chip Support"
|
||||
depends on BFIN533_STAMP && MTD_CFI
|
||||
depends on BFIN533_STAMP && MTD_CFI && MTD_COMPLEX_MAPPINGS
|
||||
select MTD_PARTITIONS
|
||||
default y
|
||||
help
|
||||
|
|
|
@ -152,14 +152,18 @@ static int __devinit bfin_flash_probe(struct platform_device *pdev)
|
|||
|
||||
if (gpio_request(state->enet_flash_pin, DRIVER_NAME)) {
|
||||
pr_devinit(KERN_ERR DRIVER_NAME ": Failed to request gpio %d\n", state->enet_flash_pin);
|
||||
kfree(state);
|
||||
return -EBUSY;
|
||||
}
|
||||
gpio_direction_output(state->enet_flash_pin, 1);
|
||||
|
||||
pr_devinit(KERN_NOTICE DRIVER_NAME ": probing %d-bit flash bus\n", state->map.bankwidth * 8);
|
||||
state->mtd = do_map_probe(memory->name, &state->map);
|
||||
if (!state->mtd)
|
||||
if (!state->mtd) {
|
||||
gpio_free(state->enet_flash_pin);
|
||||
kfree(state);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MTD_PARTITIONS
|
||||
ret = parse_mtd_partitions(state->mtd, part_probe_types, &pdata->parts, 0);
|
||||
|
|
|
@ -342,9 +342,9 @@ static struct pci_device_id ck804xrom_pci_tbl[] = {
|
|||
{ 0, }
|
||||
};
|
||||
|
||||
#if 0
|
||||
MODULE_DEVICE_TABLE(pci, ck804xrom_pci_tbl);
|
||||
|
||||
#if 0
|
||||
static struct pci_driver ck804xrom_driver = {
|
||||
.name = MOD_NAME,
|
||||
.id_table = ck804xrom_pci_tbl,
|
||||
|
|
|
@ -29,6 +29,7 @@ struct physmap_flash_info {
|
|||
struct map_info map[MAX_RESOURCES];
|
||||
#ifdef CONFIG_MTD_PARTITIONS
|
||||
int nr_parts;
|
||||
struct mtd_partition *parts;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -45,25 +46,26 @@ static int physmap_flash_remove(struct platform_device *dev)
|
|||
|
||||
physmap_data = dev->dev.platform_data;
|
||||
|
||||
#ifdef CONFIG_MTD_CONCAT
|
||||
if (info->cmtd != info->mtd[0]) {
|
||||
#ifdef CONFIG_MTD_PARTITIONS
|
||||
if (info->nr_parts) {
|
||||
del_mtd_partitions(info->cmtd);
|
||||
kfree(info->parts);
|
||||
} else if (physmap_data->nr_parts)
|
||||
del_mtd_partitions(info->cmtd);
|
||||
else
|
||||
del_mtd_device(info->cmtd);
|
||||
#else
|
||||
del_mtd_device(info->cmtd);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MTD_CONCAT
|
||||
if (info->cmtd != info->mtd[0])
|
||||
mtd_concat_destroy(info->cmtd);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i < MAX_RESOURCES; i++) {
|
||||
if (info->mtd[i] != NULL) {
|
||||
#ifdef CONFIG_MTD_PARTITIONS
|
||||
if (info->nr_parts || physmap_data->nr_parts)
|
||||
del_mtd_partitions(info->mtd[i]);
|
||||
else
|
||||
del_mtd_device(info->mtd[i]);
|
||||
#else
|
||||
del_mtd_device(info->mtd[i]);
|
||||
#endif
|
||||
if (info->mtd[i] != NULL)
|
||||
map_destroy(info->mtd[i]);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -86,9 +88,6 @@ static int physmap_flash_probe(struct platform_device *dev)
|
|||
int err = 0;
|
||||
int i;
|
||||
int devices_found = 0;
|
||||
#ifdef CONFIG_MTD_PARTITIONS
|
||||
struct mtd_partition *parts;
|
||||
#endif
|
||||
|
||||
physmap_data = dev->dev.platform_data;
|
||||
if (physmap_data == NULL)
|
||||
|
@ -167,10 +166,11 @@ static int physmap_flash_probe(struct platform_device *dev)
|
|||
goto err_out;
|
||||
|
||||
#ifdef CONFIG_MTD_PARTITIONS
|
||||
err = parse_mtd_partitions(info->cmtd, part_probe_types, &parts, 0);
|
||||
err = parse_mtd_partitions(info->cmtd, part_probe_types,
|
||||
&info->parts, 0);
|
||||
if (err > 0) {
|
||||
add_mtd_partitions(info->cmtd, parts, err);
|
||||
kfree(parts);
|
||||
add_mtd_partitions(info->cmtd, info->parts, err);
|
||||
info->nr_parts = err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -111,6 +111,7 @@ struct controller {
|
|||
int cmd_busy;
|
||||
unsigned int no_cmd_complete:1;
|
||||
unsigned int link_active_reporting:1;
|
||||
unsigned int notification_enabled:1;
|
||||
};
|
||||
|
||||
#define INT_BUTTON_IGNORE 0
|
||||
|
@ -170,6 +171,7 @@ extern int pciehp_configure_device(struct slot *p_slot);
|
|||
extern int pciehp_unconfigure_device(struct slot *p_slot);
|
||||
extern void pciehp_queue_pushbutton_work(struct work_struct *work);
|
||||
struct controller *pcie_init(struct pcie_device *dev);
|
||||
int pcie_init_notification(struct controller *ctrl);
|
||||
int pciehp_enable_slot(struct slot *p_slot);
|
||||
int pciehp_disable_slot(struct slot *p_slot);
|
||||
int pcie_enable_notification(struct controller *ctrl);
|
||||
|
|
|
@ -434,6 +434,13 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
|
|||
goto err_out_release_ctlr;
|
||||
}
|
||||
|
||||
/* Enable events after we have setup the data structures */
|
||||
rc = pcie_init_notification(ctrl);
|
||||
if (rc) {
|
||||
ctrl_err(ctrl, "Notification initialization failed\n");
|
||||
goto err_out_release_ctlr;
|
||||
}
|
||||
|
||||
/* Check if slot is occupied */
|
||||
t_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset);
|
||||
t_slot->hpc_ops->get_adapter_status(t_slot, &value);
|
||||
|
|
|
@ -934,7 +934,7 @@ static void pcie_disable_notification(struct controller *ctrl)
|
|||
ctrl_warn(ctrl, "Cannot disable software notification\n");
|
||||
}
|
||||
|
||||
static int pcie_init_notification(struct controller *ctrl)
|
||||
int pcie_init_notification(struct controller *ctrl)
|
||||
{
|
||||
if (pciehp_request_irq(ctrl))
|
||||
return -1;
|
||||
|
@ -942,13 +942,17 @@ static int pcie_init_notification(struct controller *ctrl)
|
|||
pciehp_free_irq(ctrl);
|
||||
return -1;
|
||||
}
|
||||
ctrl->notification_enabled = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pcie_shutdown_notification(struct controller *ctrl)
|
||||
{
|
||||
pcie_disable_notification(ctrl);
|
||||
pciehp_free_irq(ctrl);
|
||||
if (ctrl->notification_enabled) {
|
||||
pcie_disable_notification(ctrl);
|
||||
pciehp_free_irq(ctrl);
|
||||
ctrl->notification_enabled = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int pcie_init_slot(struct controller *ctrl)
|
||||
|
@ -1110,13 +1114,8 @@ struct controller *pcie_init(struct pcie_device *dev)
|
|||
if (pcie_init_slot(ctrl))
|
||||
goto abort_ctrl;
|
||||
|
||||
if (pcie_init_notification(ctrl))
|
||||
goto abort_slot;
|
||||
|
||||
return ctrl;
|
||||
|
||||
abort_slot:
|
||||
pcie_cleanup_slot(ctrl);
|
||||
abort_ctrl:
|
||||
kfree(ctrl);
|
||||
abort:
|
||||
|
|
|
@ -108,6 +108,34 @@ int pci_cleanup_aer_correct_error_status(struct pci_dev *dev)
|
|||
}
|
||||
#endif /* 0 */
|
||||
|
||||
|
||||
static void set_device_error_reporting(struct pci_dev *dev, void *data)
|
||||
{
|
||||
bool enable = *((bool *)data);
|
||||
|
||||
if (dev->pcie_type != PCIE_RC_PORT &&
|
||||
dev->pcie_type != PCIE_SW_UPSTREAM_PORT &&
|
||||
dev->pcie_type != PCIE_SW_DOWNSTREAM_PORT)
|
||||
return;
|
||||
|
||||
if (enable)
|
||||
pci_enable_pcie_error_reporting(dev);
|
||||
else
|
||||
pci_disable_pcie_error_reporting(dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* set_downstream_devices_error_reporting - enable/disable the error reporting bits on the root port and its downstream ports.
|
||||
* @dev: pointer to root port's pci_dev data structure
|
||||
* @enable: true = enable error reporting, false = disable error reporting.
|
||||
*/
|
||||
static void set_downstream_devices_error_reporting(struct pci_dev *dev,
|
||||
bool enable)
|
||||
{
|
||||
set_device_error_reporting(dev, &enable);
|
||||
pci_walk_bus(dev->subordinate, set_device_error_reporting, &enable);
|
||||
}
|
||||
|
||||
static int find_device_iter(struct device *device, void *data)
|
||||
{
|
||||
struct pci_dev *dev;
|
||||
|
@ -525,15 +553,11 @@ void aer_enable_rootport(struct aer_rpc *rpc)
|
|||
pci_read_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, ®32);
|
||||
pci_write_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, reg32);
|
||||
|
||||
/* Enable Root Port device reporting error itself */
|
||||
pci_read_config_word(pdev, pos+PCI_EXP_DEVCTL, ®16);
|
||||
reg16 = reg16 |
|
||||
PCI_EXP_DEVCTL_CERE |
|
||||
PCI_EXP_DEVCTL_NFERE |
|
||||
PCI_EXP_DEVCTL_FERE |
|
||||
PCI_EXP_DEVCTL_URRE;
|
||||
pci_write_config_word(pdev, pos+PCI_EXP_DEVCTL,
|
||||
reg16);
|
||||
/*
|
||||
* Enable error reporting for the root port device and downstream port
|
||||
* devices.
|
||||
*/
|
||||
set_downstream_devices_error_reporting(pdev, true);
|
||||
|
||||
/* Enable Root Port's interrupt in response to error messages */
|
||||
pci_write_config_dword(pdev,
|
||||
|
@ -553,6 +577,12 @@ static void disable_root_aer(struct aer_rpc *rpc)
|
|||
u32 reg32;
|
||||
int pos;
|
||||
|
||||
/*
|
||||
* Disable error reporting for the root port device and downstream port
|
||||
* devices.
|
||||
*/
|
||||
set_downstream_devices_error_reporting(pdev, false);
|
||||
|
||||
pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR);
|
||||
/* Disable Root's interrupt in response to error messages */
|
||||
pci_write_config_dword(pdev, pos + PCI_ERR_ROOT_COMMAND, 0);
|
||||
|
|
|
@ -97,8 +97,6 @@ static int __devinit pcie_portdrv_probe (struct pci_dev *dev,
|
|||
|
||||
pcie_portdrv_save_config(dev);
|
||||
|
||||
pci_enable_pcie_error_reporting(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1584,6 +1584,7 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_
|
|||
*/
|
||||
#define AMD_813X_MISC 0x40
|
||||
#define AMD_813X_NOIOAMODE (1<<0)
|
||||
#define AMD_813X_REV_B2 0x13
|
||||
|
||||
static void quirk_disable_amd_813x_boot_interrupt(struct pci_dev *dev)
|
||||
{
|
||||
|
@ -1591,6 +1592,8 @@ static void quirk_disable_amd_813x_boot_interrupt(struct pci_dev *dev)
|
|||
|
||||
if (noioapicquirk)
|
||||
return;
|
||||
if (dev->revision == AMD_813X_REV_B2)
|
||||
return;
|
||||
|
||||
pci_read_config_dword(dev, AMD_813X_MISC, &pci_config_dword);
|
||||
pci_config_dword &= ~AMD_813X_NOIOAMODE;
|
||||
|
@ -1981,7 +1984,6 @@ static void __devinit quirk_msi_ht_cap(struct pci_dev *dev)
|
|||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE,
|
||||
quirk_msi_ht_cap);
|
||||
|
||||
|
||||
/* The nVidia CK804 chipset may have 2 HT MSI mappings.
|
||||
* MSI are supported if the MSI capability set in any of these mappings.
|
||||
*/
|
||||
|
@ -2032,6 +2034,9 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS,
|
|||
PCI_DEVICE_ID_SERVERWORKS_HT1000_PXB,
|
||||
ht_enable_msi_mapping);
|
||||
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8132_BRIDGE,
|
||||
ht_enable_msi_mapping);
|
||||
|
||||
/* The P5N32-SLI Premium motherboard from Asus has a problem with msi
|
||||
* for the MCP55 NIC. It is not yet determined whether the msi problem
|
||||
* also affects other devices. As for now, turn off msi for this device.
|
||||
|
@ -2048,10 +2053,100 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA,
|
|||
PCI_DEVICE_ID_NVIDIA_NVENET_15,
|
||||
nvenet_msi_disable);
|
||||
|
||||
static void __devinit nv_ht_enable_msi_mapping(struct pci_dev *dev)
|
||||
{
|
||||
struct pci_dev *host_bridge;
|
||||
int pos;
|
||||
int i, dev_no;
|
||||
int found = 0;
|
||||
|
||||
dev_no = dev->devfn >> 3;
|
||||
for (i = dev_no; i >= 0; i--) {
|
||||
host_bridge = pci_get_slot(dev->bus, PCI_DEVFN(i, 0));
|
||||
if (!host_bridge)
|
||||
continue;
|
||||
|
||||
pos = pci_find_ht_capability(host_bridge, HT_CAPTYPE_SLAVE);
|
||||
if (pos != 0) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
pci_dev_put(host_bridge);
|
||||
}
|
||||
|
||||
if (!found)
|
||||
return;
|
||||
|
||||
/* root did that ! */
|
||||
if (msi_ht_cap_enabled(host_bridge))
|
||||
goto out;
|
||||
|
||||
ht_enable_msi_mapping(dev);
|
||||
|
||||
out:
|
||||
pci_dev_put(host_bridge);
|
||||
}
|
||||
|
||||
static void __devinit ht_disable_msi_mapping(struct pci_dev *dev)
|
||||
{
|
||||
int pos, ttl = 48;
|
||||
|
||||
pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING);
|
||||
while (pos && ttl--) {
|
||||
u8 flags;
|
||||
|
||||
if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS,
|
||||
&flags) == 0) {
|
||||
dev_info(&dev->dev, "Enabling HT MSI Mapping\n");
|
||||
|
||||
pci_write_config_byte(dev, pos + HT_MSI_FLAGS,
|
||||
flags & ~HT_MSI_FLAGS_ENABLE);
|
||||
}
|
||||
pos = pci_find_next_ht_capability(dev, pos,
|
||||
HT_CAPTYPE_MSI_MAPPING);
|
||||
}
|
||||
}
|
||||
|
||||
static int __devinit ht_check_msi_mapping(struct pci_dev *dev)
|
||||
{
|
||||
int pos, ttl = 48;
|
||||
int found = 0;
|
||||
|
||||
/* check if there is HT MSI cap or enabled on this device */
|
||||
pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING);
|
||||
while (pos && ttl--) {
|
||||
u8 flags;
|
||||
|
||||
if (found < 1)
|
||||
found = 1;
|
||||
if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS,
|
||||
&flags) == 0) {
|
||||
if (flags & HT_MSI_FLAGS_ENABLE) {
|
||||
if (found < 2) {
|
||||
found = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
pos = pci_find_next_ht_capability(dev, pos,
|
||||
HT_CAPTYPE_MSI_MAPPING);
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev)
|
||||
{
|
||||
struct pci_dev *host_bridge;
|
||||
int pos, ttl = 48;
|
||||
int pos;
|
||||
int found;
|
||||
|
||||
/* check if there is HT MSI cap or enabled on this device */
|
||||
found = ht_check_msi_mapping(dev);
|
||||
|
||||
/* no HT MSI CAP */
|
||||
if (found == 0)
|
||||
return;
|
||||
|
||||
/*
|
||||
* HT MSI mapping should be disabled on devices that are below
|
||||
|
@ -2067,24 +2162,19 @@ static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev)
|
|||
pos = pci_find_ht_capability(host_bridge, HT_CAPTYPE_SLAVE);
|
||||
if (pos != 0) {
|
||||
/* Host bridge is to HT */
|
||||
ht_enable_msi_mapping(dev);
|
||||
if (found == 1) {
|
||||
/* it is not enabled, try to enable it */
|
||||
nv_ht_enable_msi_mapping(dev);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Host bridge is not to HT, disable HT MSI mapping on this device */
|
||||
pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING);
|
||||
while (pos && ttl--) {
|
||||
u8 flags;
|
||||
/* HT MSI is not enabled */
|
||||
if (found == 1)
|
||||
return;
|
||||
|
||||
if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS,
|
||||
&flags) == 0) {
|
||||
dev_info(&dev->dev, "Disabling HT MSI mapping");
|
||||
pci_write_config_byte(dev, pos + HT_MSI_FLAGS,
|
||||
flags & ~HT_MSI_FLAGS_ENABLE);
|
||||
}
|
||||
pos = pci_find_next_ht_capability(dev, pos,
|
||||
HT_CAPTYPE_MSI_MAPPING);
|
||||
}
|
||||
/* Host bridge is not to HT, disable HT MSI mapping on this device */
|
||||
ht_disable_msi_mapping(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);
|
||||
|
|
|
@ -133,7 +133,7 @@
|
|||
# define SCSPTR3 0xffed0024 /* 16 bit SCIF */
|
||||
# define SCSPTR4 0xffee0024 /* 16 bit SCIF */
|
||||
# define SCSPTR5 0xffef0024 /* 16 bit SCIF */
|
||||
# define SCIF_OPER 0x0001 /* Overrun error bit */
|
||||
# define SCIF_ORER 0x0001 /* Overrun error bit */
|
||||
# define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
|
||||
#elif defined(CONFIG_CPU_SUBTYPE_SH7201) || \
|
||||
defined(CONFIG_CPU_SUBTYPE_SH7203) || \
|
||||
|
|
|
@ -2164,19 +2164,20 @@ static void __exit panel_cleanup_module(void)
|
|||
if (scan_timer.function != NULL)
|
||||
del_timer(&scan_timer);
|
||||
|
||||
if (keypad_enabled)
|
||||
misc_deregister(&keypad_dev);
|
||||
if (pprt != NULL) {
|
||||
if (keypad_enabled)
|
||||
misc_deregister(&keypad_dev);
|
||||
|
||||
if (lcd_enabled) {
|
||||
panel_lcd_print("\x0cLCD driver " PANEL_VERSION
|
||||
"\nunloaded.\x1b[Lc\x1b[Lb\x1b[L-");
|
||||
misc_deregister(&lcd_dev);
|
||||
if (lcd_enabled) {
|
||||
panel_lcd_print("\x0cLCD driver " PANEL_VERSION
|
||||
"\nunloaded.\x1b[Lc\x1b[Lb\x1b[L-");
|
||||
misc_deregister(&lcd_dev);
|
||||
}
|
||||
|
||||
/* TODO: free all input signals */
|
||||
parport_release(pprt);
|
||||
parport_unregister_device(pprt);
|
||||
}
|
||||
|
||||
/* TODO: free all input signals */
|
||||
|
||||
parport_release(pprt);
|
||||
parport_unregister_device(pprt);
|
||||
parport_unregister_driver(&panel_driver);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
config RTL8187SE
|
||||
tristate "RealTek RTL8187SE Wireless LAN NIC driver"
|
||||
depends on PCI
|
||||
depends on WIRELESS_EXT && COMPAT_NET_DEV_OPS
|
||||
default N
|
||||
---help---
|
||||
|
|
|
@ -234,20 +234,21 @@ out:
|
|||
void ieee80211_crypto_deinit(void)
|
||||
{
|
||||
struct list_head *ptr, *n;
|
||||
struct ieee80211_crypto_alg *alg = NULL;
|
||||
|
||||
if (hcrypt == NULL)
|
||||
return;
|
||||
|
||||
for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs;
|
||||
ptr = n, n = ptr->next) {
|
||||
struct ieee80211_crypto_alg *alg =
|
||||
(struct ieee80211_crypto_alg *) ptr;
|
||||
list_del(ptr);
|
||||
printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
|
||||
"'%s' (deinit)\n", alg->ops->name);
|
||||
kfree(alg);
|
||||
list_for_each_safe(ptr, n, &hcrypt->algs) {
|
||||
alg = list_entry(ptr, struct ieee80211_crypto_alg, list);
|
||||
if (alg) {
|
||||
list_del(ptr);
|
||||
printk(KERN_DEBUG
|
||||
"ieee80211_crypt: unregistered algorithm '%s' (deinit)\n",
|
||||
alg->ops->name);
|
||||
kfree(alg);
|
||||
}
|
||||
}
|
||||
|
||||
kfree(hcrypt);
|
||||
}
|
||||
|
||||
|
|
|
@ -6161,10 +6161,10 @@ static void __exit rtl8180_pci_module_exit(void)
|
|||
{
|
||||
pci_unregister_driver (&rtl8180_pci_driver);
|
||||
rtl8180_proc_module_remove();
|
||||
ieee80211_crypto_deinit();
|
||||
ieee80211_crypto_tkip_exit();
|
||||
ieee80211_crypto_ccmp_exit();
|
||||
ieee80211_crypto_wep_exit();
|
||||
ieee80211_crypto_deinit();
|
||||
DMESG("Exiting");
|
||||
}
|
||||
|
||||
|
|
|
@ -319,16 +319,18 @@ static int wb35_probe(struct usb_interface *intf, const struct usb_device_id *id
|
|||
struct usb_device *udev = interface_to_usbdev(intf);
|
||||
struct wbsoft_priv *priv;
|
||||
struct ieee80211_hw *dev;
|
||||
int err;
|
||||
int nr, err;
|
||||
|
||||
usb_get_dev(udev);
|
||||
|
||||
// 20060630.2 Check the device if it already be opened
|
||||
err = usb_control_msg(udev, usb_rcvctrlpipe( udev, 0 ),
|
||||
0x01, USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_DIR_IN,
|
||||
0x0, 0x400, <mp, 4, HZ*100 );
|
||||
if (err)
|
||||
nr = usb_control_msg(udev, usb_rcvctrlpipe( udev, 0 ),
|
||||
0x01, USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_DIR_IN,
|
||||
0x0, 0x400, <mp, 4, HZ*100 );
|
||||
if (nr < 0) {
|
||||
err = nr;
|
||||
goto error;
|
||||
}
|
||||
|
||||
ltmp = cpu_to_le32(ltmp);
|
||||
if (ltmp) { // Is already initialized?
|
||||
|
@ -337,8 +339,10 @@ static int wb35_probe(struct usb_interface *intf, const struct usb_device_id *id
|
|||
}
|
||||
|
||||
dev = ieee80211_alloc_hw(sizeof(*priv), &wbsoft_ops);
|
||||
if (!dev)
|
||||
if (!dev) {
|
||||
err = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
priv = dev->priv;
|
||||
|
||||
|
@ -369,9 +373,11 @@ static int wb35_probe(struct usb_interface *intf, const struct usb_device_id *id
|
|||
}
|
||||
|
||||
dev->extra_tx_headroom = 12; /* FIXME */
|
||||
dev->flags = 0;
|
||||
dev->flags = IEEE80211_HW_SIGNAL_UNSPEC;
|
||||
dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
|
||||
|
||||
dev->channel_change_time = 1000;
|
||||
dev->max_signal = 100;
|
||||
dev->queues = 1;
|
||||
|
||||
dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &wbsoft_band_2GHz;
|
||||
|
|
|
@ -1376,6 +1376,15 @@ static struct usb_device_id acm_ids[] = {
|
|||
{ USB_DEVICE(0x0572, 0x1324), /* Conexant USB MODEM RD02-D400 */
|
||||
.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
|
||||
},
|
||||
{ USB_DEVICE(0x22b8, 0x6425), /* Motorola MOTOMAGX phones */
|
||||
},
|
||||
{ USB_DEVICE(0x0572, 0x1329), /* Hummingbird huc56s (Conexant) */
|
||||
.driver_info = NO_UNION_NORMAL, /* union descriptor misplaced on
|
||||
data interface instead of
|
||||
communications interface.
|
||||
Maybe we should define a new
|
||||
quirk for this. */
|
||||
},
|
||||
|
||||
/* control interfaces with various AT-command sets */
|
||||
{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
|
||||
|
|
|
@ -653,7 +653,7 @@ int usb_get_descriptor(struct usb_device *dev, unsigned char type,
|
|||
if (result <= 0 && result != -ETIMEDOUT)
|
||||
continue;
|
||||
if (result > 1 && ((u8 *)buf)[1] != type) {
|
||||
result = -EPROTO;
|
||||
result = -ENODATA;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
@ -696,8 +696,13 @@ static int usb_get_string(struct usb_device *dev, unsigned short langid,
|
|||
USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
|
||||
(USB_DT_STRING << 8) + index, langid, buf, size,
|
||||
USB_CTRL_GET_TIMEOUT);
|
||||
if (!(result == 0 || result == -EPIPE))
|
||||
break;
|
||||
if (result == 0 || result == -EPIPE)
|
||||
continue;
|
||||
if (result > 1 && ((u8 *) buf)[1] != USB_DT_STRING) {
|
||||
result = -ENODATA;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -191,6 +191,7 @@ config USB_GADGET_OMAP
|
|||
boolean "OMAP USB Device Controller"
|
||||
depends on ARCH_OMAP
|
||||
select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_H4_OTG
|
||||
select USB_OTG_UTILS if ARCH_OMAP
|
||||
help
|
||||
Many Texas Instruments OMAP processors have flexible full
|
||||
speed USB device controllers, with support for up to 30
|
||||
|
|
|
@ -366,9 +366,9 @@ obex_bind(struct usb_configuration *c, struct usb_function *f)
|
|||
f->hs_descriptors = usb_copy_descriptors(hs_function);
|
||||
|
||||
obex->hs.obex_in = usb_find_endpoint(hs_function,
|
||||
f->descriptors, &obex_hs_ep_in_desc);
|
||||
f->hs_descriptors, &obex_hs_ep_in_desc);
|
||||
obex->hs.obex_out = usb_find_endpoint(hs_function,
|
||||
f->descriptors, &obex_hs_ep_out_desc);
|
||||
f->hs_descriptors, &obex_hs_ep_out_desc);
|
||||
}
|
||||
|
||||
/* Avoid letting this gadget enumerate until the userspace
|
||||
|
|
|
@ -3879,7 +3879,11 @@ static int __init check_parameters(struct fsg_dev *fsg)
|
|||
mod_data.protocol_type = USB_SC_SCSI;
|
||||
mod_data.protocol_name = "Transparent SCSI";
|
||||
|
||||
if (gadget_is_sh(fsg->gadget))
|
||||
/* Some peripheral controllers are known not to be able to
|
||||
* halt bulk endpoints correctly. If one of them is present,
|
||||
* disable stalls.
|
||||
*/
|
||||
if (gadget_is_sh(fsg->gadget) || gadget_is_at91(fsg->gadget))
|
||||
mod_data.can_stall = 0;
|
||||
|
||||
if (mod_data.release == 0xffff) { // Parameter wasn't set
|
||||
|
|
|
@ -404,7 +404,10 @@ static void struct_ep_qh_setup(struct fsl_udc *udc, unsigned char ep_num,
|
|||
}
|
||||
if (zlt)
|
||||
tmp |= EP_QUEUE_HEAD_ZLT_SEL;
|
||||
|
||||
p_QH->max_pkt_length = cpu_to_le32(tmp);
|
||||
p_QH->next_dtd_ptr = 1;
|
||||
p_QH->size_ioc_int_sts = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -485,6 +485,7 @@ static int ehci_init(struct usb_hcd *hcd)
|
|||
* periodic_size can shrink by USBCMD update if hcc_params allows.
|
||||
*/
|
||||
ehci->periodic_size = DEFAULT_I_TDPS;
|
||||
INIT_LIST_HEAD(&ehci->cached_itd_list);
|
||||
if ((retval = ehci_mem_init(ehci, GFP_KERNEL)) < 0)
|
||||
return retval;
|
||||
|
||||
|
@ -497,6 +498,7 @@ static int ehci_init(struct usb_hcd *hcd)
|
|||
|
||||
ehci->reclaim = NULL;
|
||||
ehci->next_uframe = -1;
|
||||
ehci->clock_frame = -1;
|
||||
|
||||
/*
|
||||
* dedicate a qh for the async ring head, since we couldn't unlink
|
||||
|
|
|
@ -128,6 +128,7 @@ static inline void qh_put (struct ehci_qh *qh)
|
|||
|
||||
static void ehci_mem_cleanup (struct ehci_hcd *ehci)
|
||||
{
|
||||
free_cached_itd_list(ehci);
|
||||
if (ehci->async)
|
||||
qh_put (ehci->async);
|
||||
ehci->async = NULL;
|
||||
|
|
|
@ -1004,7 +1004,8 @@ iso_stream_put(struct ehci_hcd *ehci, struct ehci_iso_stream *stream)
|
|||
|
||||
is_in = (stream->bEndpointAddress & USB_DIR_IN) ? 0x10 : 0;
|
||||
stream->bEndpointAddress &= 0x0f;
|
||||
stream->ep->hcpriv = NULL;
|
||||
if (stream->ep)
|
||||
stream->ep->hcpriv = NULL;
|
||||
|
||||
if (stream->rescheduled) {
|
||||
ehci_info (ehci, "ep%d%s-iso rescheduled "
|
||||
|
@ -1653,14 +1654,28 @@ itd_complete (
|
|||
(stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out");
|
||||
}
|
||||
iso_stream_put (ehci, stream);
|
||||
/* OK to recycle this ITD now that its completion callback ran. */
|
||||
|
||||
done:
|
||||
usb_put_urb(urb);
|
||||
itd->urb = NULL;
|
||||
itd->stream = NULL;
|
||||
list_move(&itd->itd_list, &stream->free_list);
|
||||
iso_stream_put(ehci, stream);
|
||||
|
||||
if (ehci->clock_frame != itd->frame || itd->index[7] != -1) {
|
||||
/* OK to recycle this ITD now. */
|
||||
itd->stream = NULL;
|
||||
list_move(&itd->itd_list, &stream->free_list);
|
||||
iso_stream_put(ehci, stream);
|
||||
} else {
|
||||
/* HW might remember this ITD, so we can't recycle it yet.
|
||||
* Move it to a safe place until a new frame starts.
|
||||
*/
|
||||
list_move(&itd->itd_list, &ehci->cached_itd_list);
|
||||
if (stream->refcount == 2) {
|
||||
/* If iso_stream_put() were called here, stream
|
||||
* would be freed. Instead, just prevent reuse.
|
||||
*/
|
||||
stream->ep->hcpriv = NULL;
|
||||
stream->ep = NULL;
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -2101,6 +2116,20 @@ done:
|
|||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static void free_cached_itd_list(struct ehci_hcd *ehci)
|
||||
{
|
||||
struct ehci_itd *itd, *n;
|
||||
|
||||
list_for_each_entry_safe(itd, n, &ehci->cached_itd_list, itd_list) {
|
||||
struct ehci_iso_stream *stream = itd->stream;
|
||||
itd->stream = NULL;
|
||||
list_move(&itd->itd_list, &stream->free_list);
|
||||
iso_stream_put(ehci, stream);
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static void
|
||||
scan_periodic (struct ehci_hcd *ehci)
|
||||
{
|
||||
|
@ -2115,10 +2144,17 @@ scan_periodic (struct ehci_hcd *ehci)
|
|||
* Touches as few pages as possible: cache-friendly.
|
||||
*/
|
||||
now_uframe = ehci->next_uframe;
|
||||
if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state))
|
||||
if (HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) {
|
||||
clock = ehci_readl(ehci, &ehci->regs->frame_index);
|
||||
else
|
||||
clock_frame = (clock >> 3) % ehci->periodic_size;
|
||||
} else {
|
||||
clock = now_uframe + mod - 1;
|
||||
clock_frame = -1;
|
||||
}
|
||||
if (ehci->clock_frame != clock_frame) {
|
||||
free_cached_itd_list(ehci);
|
||||
ehci->clock_frame = clock_frame;
|
||||
}
|
||||
clock %= mod;
|
||||
clock_frame = clock >> 3;
|
||||
|
||||
|
@ -2277,6 +2313,10 @@ restart:
|
|||
/* rescan the rest of this frame, then ... */
|
||||
clock = now;
|
||||
clock_frame = clock >> 3;
|
||||
if (ehci->clock_frame != clock_frame) {
|
||||
free_cached_itd_list(ehci);
|
||||
ehci->clock_frame = clock_frame;
|
||||
}
|
||||
} else {
|
||||
now_uframe++;
|
||||
now_uframe %= mod;
|
||||
|
|
|
@ -87,6 +87,10 @@ struct ehci_hcd { /* one per controller */
|
|||
int next_uframe; /* scan periodic, start here */
|
||||
unsigned periodic_sched; /* periodic activity count */
|
||||
|
||||
/* list of itds completed while clock_frame was still active */
|
||||
struct list_head cached_itd_list;
|
||||
unsigned clock_frame;
|
||||
|
||||
/* per root hub port */
|
||||
unsigned long reset_done [EHCI_MAX_ROOT_PORTS];
|
||||
|
||||
|
@ -220,6 +224,8 @@ timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action)
|
|||
}
|
||||
}
|
||||
|
||||
static void free_cached_itd_list(struct ehci_hcd *ehci);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
#include <linux/usb/ehci_def.h>
|
||||
|
|
|
@ -377,18 +377,8 @@ int __init musb_platform_init(struct musb *musb)
|
|||
u32 revision;
|
||||
|
||||
musb->mregs += DAVINCI_BASE_OFFSET;
|
||||
#if 0
|
||||
/* REVISIT there's something odd about clocking, this
|
||||
* didn't appear do the job ...
|
||||
*/
|
||||
musb->clock = clk_get(pDevice, "usb");
|
||||
if (IS_ERR(musb->clock))
|
||||
return PTR_ERR(musb->clock);
|
||||
|
||||
status = clk_enable(musb->clock);
|
||||
if (status < 0)
|
||||
return -ENODEV;
|
||||
#endif
|
||||
clk_enable(musb->clock);
|
||||
|
||||
/* returns zero if e.g. not clocked */
|
||||
revision = musb_readl(tibase, DAVINCI_USB_VERSION_REG);
|
||||
|
@ -453,5 +443,8 @@ int musb_platform_exit(struct musb *musb)
|
|||
}
|
||||
|
||||
phy_off();
|
||||
|
||||
clk_disable(musb->clock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -115,7 +115,7 @@
|
|||
|
||||
|
||||
unsigned musb_debug;
|
||||
module_param(musb_debug, uint, S_IRUGO | S_IWUSR);
|
||||
module_param_named(debug, musb_debug, uint, S_IRUGO | S_IWUSR);
|
||||
MODULE_PARM_DESC(debug, "Debug message level. Default = 0");
|
||||
|
||||
#define DRIVER_AUTHOR "Mentor Graphics, Texas Instruments, Nokia"
|
||||
|
@ -767,6 +767,7 @@ static irqreturn_t musb_stage2_irq(struct musb *musb, u8 int_usb,
|
|||
#ifdef CONFIG_USB_MUSB_HDRC_HCD
|
||||
case OTG_STATE_A_HOST:
|
||||
case OTG_STATE_A_SUSPEND:
|
||||
usb_hcd_resume_root_hub(musb_to_hcd(musb));
|
||||
musb_root_disconnect(musb);
|
||||
if (musb->a_wait_bcon != 0)
|
||||
musb_platform_try_idle(musb, jiffies
|
||||
|
@ -1815,7 +1816,7 @@ static void musb_free(struct musb *musb)
|
|||
#ifdef CONFIG_SYSFS
|
||||
device_remove_file(musb->controller, &dev_attr_mode);
|
||||
device_remove_file(musb->controller, &dev_attr_vbus);
|
||||
#ifdef CONFIG_USB_MUSB_OTG
|
||||
#ifdef CONFIG_USB_GADGET_MUSB_HDRC
|
||||
device_remove_file(musb->controller, &dev_attr_srp);
|
||||
#endif
|
||||
#endif
|
||||
|
@ -2063,7 +2064,7 @@ fail2:
|
|||
#ifdef CONFIG_SYSFS
|
||||
device_remove_file(musb->controller, &dev_attr_mode);
|
||||
device_remove_file(musb->controller, &dev_attr_vbus);
|
||||
#ifdef CONFIG_USB_MUSB_OTG
|
||||
#ifdef CONFIG_USB_GADGET_MUSB_HDRC
|
||||
device_remove_file(musb->controller, &dev_attr_srp);
|
||||
#endif
|
||||
#endif
|
||||
|
@ -2243,10 +2244,10 @@ static int __init musb_init(void)
|
|||
return platform_driver_probe(&musb_driver, musb_probe);
|
||||
}
|
||||
|
||||
/* make us init after usbcore and before usb
|
||||
* gadget and host-side drivers start to register
|
||||
/* make us init after usbcore and i2c (transceivers, regulators, etc)
|
||||
* and before usb gadget and host-side drivers start to register
|
||||
*/
|
||||
subsys_initcall(musb_init);
|
||||
fs_initcall(musb_init);
|
||||
|
||||
static void __exit musb_cleanup(void)
|
||||
{
|
||||
|
|
|
@ -575,7 +575,7 @@ static void rxstate(struct musb *musb, struct musb_request *req)
|
|||
struct usb_request *request = &req->request;
|
||||
struct musb_ep *musb_ep = &musb->endpoints[epnum].ep_out;
|
||||
void __iomem *epio = musb->endpoints[epnum].regs;
|
||||
u16 fifo_count = 0;
|
||||
unsigned fifo_count = 0;
|
||||
u16 len = musb_ep->packet_sz;
|
||||
|
||||
csr = musb_readw(epio, MUSB_RXCSR);
|
||||
|
@ -687,7 +687,7 @@ static void rxstate(struct musb *musb, struct musb_request *req)
|
|||
len, fifo_count,
|
||||
musb_ep->packet_sz);
|
||||
|
||||
fifo_count = min(len, fifo_count);
|
||||
fifo_count = min_t(unsigned, len, fifo_count);
|
||||
|
||||
#ifdef CONFIG_USB_TUSB_OMAP_DMA
|
||||
if (tusb_dma_omap() && musb_ep->dma) {
|
||||
|
|
|
@ -335,16 +335,11 @@ musb_save_toggle(struct musb_hw_ep *ep, int is_in, struct urb *urb)
|
|||
static struct musb_qh *
|
||||
musb_giveback(struct musb_qh *qh, struct urb *urb, int status)
|
||||
{
|
||||
int is_in;
|
||||
struct musb_hw_ep *ep = qh->hw_ep;
|
||||
struct musb *musb = ep->musb;
|
||||
int is_in = usb_pipein(urb->pipe);
|
||||
int ready = qh->is_ready;
|
||||
|
||||
if (ep->is_shared_fifo)
|
||||
is_in = 1;
|
||||
else
|
||||
is_in = usb_pipein(urb->pipe);
|
||||
|
||||
/* save toggle eagerly, for paranoia */
|
||||
switch (qh->type) {
|
||||
case USB_ENDPOINT_XFER_BULK:
|
||||
|
@ -432,7 +427,7 @@ musb_advance_schedule(struct musb *musb, struct urb *urb,
|
|||
else
|
||||
qh = musb_giveback(qh, urb, urb->status);
|
||||
|
||||
if (qh && qh->is_ready && !list_empty(&qh->hep->urb_list)) {
|
||||
if (qh != NULL && qh->is_ready) {
|
||||
DBG(4, "... next ep%d %cX urb %p\n",
|
||||
hw_ep->epnum, is_in ? 'R' : 'T',
|
||||
next_urb(qh));
|
||||
|
@ -942,8 +937,8 @@ static bool musb_h_ep0_continue(struct musb *musb, u16 len, struct urb *urb)
|
|||
switch (musb->ep0_stage) {
|
||||
case MUSB_EP0_IN:
|
||||
fifo_dest = urb->transfer_buffer + urb->actual_length;
|
||||
fifo_count = min(len, ((u16) (urb->transfer_buffer_length
|
||||
- urb->actual_length)));
|
||||
fifo_count = min_t(size_t, len, urb->transfer_buffer_length -
|
||||
urb->actual_length);
|
||||
if (fifo_count < len)
|
||||
urb->status = -EOVERFLOW;
|
||||
|
||||
|
@ -976,10 +971,9 @@ static bool musb_h_ep0_continue(struct musb *musb, u16 len, struct urb *urb)
|
|||
}
|
||||
/* FALLTHROUGH */
|
||||
case MUSB_EP0_OUT:
|
||||
fifo_count = min(qh->maxpacket, ((u16)
|
||||
(urb->transfer_buffer_length
|
||||
- urb->actual_length)));
|
||||
|
||||
fifo_count = min_t(size_t, qh->maxpacket,
|
||||
urb->transfer_buffer_length -
|
||||
urb->actual_length);
|
||||
if (fifo_count) {
|
||||
fifo_dest = (u8 *) (urb->transfer_buffer
|
||||
+ urb->actual_length);
|
||||
|
@ -1161,7 +1155,8 @@ void musb_host_tx(struct musb *musb, u8 epnum)
|
|||
struct urb *urb;
|
||||
struct musb_hw_ep *hw_ep = musb->endpoints + epnum;
|
||||
void __iomem *epio = hw_ep->regs;
|
||||
struct musb_qh *qh = hw_ep->out_qh;
|
||||
struct musb_qh *qh = hw_ep->is_shared_fifo ? hw_ep->in_qh
|
||||
: hw_ep->out_qh;
|
||||
u32 status = 0;
|
||||
void __iomem *mbase = musb->mregs;
|
||||
struct dma_channel *dma;
|
||||
|
@ -1308,7 +1303,8 @@ void musb_host_tx(struct musb *musb, u8 epnum)
|
|||
* packets before updating TXCSR ... other docs disagree ...
|
||||
*/
|
||||
/* PIO: start next packet in this URB */
|
||||
wLength = min(qh->maxpacket, (u16) wLength);
|
||||
if (wLength > qh->maxpacket)
|
||||
wLength = qh->maxpacket;
|
||||
musb_write_fifo(hw_ep, wLength, buf);
|
||||
qh->segsize = wLength;
|
||||
|
||||
|
@ -1867,19 +1863,21 @@ static int musb_urb_enqueue(
|
|||
}
|
||||
qh->type_reg = type_reg;
|
||||
|
||||
/* precompute rxinterval/txinterval register */
|
||||
interval = min((u8)16, epd->bInterval); /* log encoding */
|
||||
/* Precompute RXINTERVAL/TXINTERVAL register */
|
||||
switch (qh->type) {
|
||||
case USB_ENDPOINT_XFER_INT:
|
||||
/* fullspeed uses linear encoding */
|
||||
if (USB_SPEED_FULL == urb->dev->speed) {
|
||||
interval = epd->bInterval;
|
||||
if (!interval)
|
||||
interval = 1;
|
||||
/*
|
||||
* Full/low speeds use the linear encoding,
|
||||
* high speed uses the logarithmic encoding.
|
||||
*/
|
||||
if (urb->dev->speed <= USB_SPEED_FULL) {
|
||||
interval = max_t(u8, epd->bInterval, 1);
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case USB_ENDPOINT_XFER_ISOC:
|
||||
/* iso always uses log encoding */
|
||||
/* ISO always uses logarithmic encoding */
|
||||
interval = min_t(u8, epd->bInterval, 16);
|
||||
break;
|
||||
default:
|
||||
/* REVISIT we actually want to use NAK limits, hinting to the
|
||||
|
@ -2037,9 +2035,9 @@ static int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
|
|||
goto done;
|
||||
|
||||
/* Any URB not actively programmed into endpoint hardware can be
|
||||
* immediately given back. Such an URB must be at the head of its
|
||||
* immediately given back; that's any URB not at the head of an
|
||||
* endpoint queue, unless someday we get real DMA queues. And even
|
||||
* then, it might not be known to the hardware...
|
||||
* if it's at the head, it might not be known to the hardware...
|
||||
*
|
||||
* Otherwise abort current transfer, pending dma, etc.; urb->status
|
||||
* has already been updated. This is a synchronous abort; it'd be
|
||||
|
@ -2078,6 +2076,15 @@ static int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
|
|||
qh->is_ready = 0;
|
||||
__musb_giveback(musb, urb, 0);
|
||||
qh->is_ready = ready;
|
||||
|
||||
/* If nothing else (usually musb_giveback) is using it
|
||||
* and its URB list has emptied, recycle this qh.
|
||||
*/
|
||||
if (ready && list_empty(&qh->hep->urb_list)) {
|
||||
qh->hep->hcpriv = NULL;
|
||||
list_del(&qh->ring);
|
||||
kfree(qh);
|
||||
}
|
||||
} else
|
||||
ret = musb_cleanup_urb(urb, qh, urb->pipe & USB_DIR_IN);
|
||||
done:
|
||||
|
@ -2093,15 +2100,16 @@ musb_h_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep)
|
|||
unsigned long flags;
|
||||
struct musb *musb = hcd_to_musb(hcd);
|
||||
u8 is_in = epnum & USB_DIR_IN;
|
||||
struct musb_qh *qh = hep->hcpriv;
|
||||
struct urb *urb, *tmp;
|
||||
struct musb_qh *qh;
|
||||
struct urb *urb;
|
||||
struct list_head *sched;
|
||||
|
||||
if (!qh)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&musb->lock, flags);
|
||||
|
||||
qh = hep->hcpriv;
|
||||
if (qh == NULL)
|
||||
goto exit;
|
||||
|
||||
switch (qh->type) {
|
||||
case USB_ENDPOINT_XFER_CONTROL:
|
||||
sched = &musb->control;
|
||||
|
@ -2135,13 +2143,28 @@ musb_h_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep)
|
|||
|
||||
/* cleanup */
|
||||
musb_cleanup_urb(urb, qh, urb->pipe & USB_DIR_IN);
|
||||
} else
|
||||
urb = NULL;
|
||||
|
||||
/* then just nuke all the others */
|
||||
list_for_each_entry_safe_from(urb, tmp, &hep->urb_list, urb_list)
|
||||
musb_giveback(qh, urb, -ESHUTDOWN);
|
||||
/* Then nuke all the others ... and advance the
|
||||
* queue on hw_ep (e.g. bulk ring) when we're done.
|
||||
*/
|
||||
while (!list_empty(&hep->urb_list)) {
|
||||
urb = next_urb(qh);
|
||||
urb->status = -ESHUTDOWN;
|
||||
musb_advance_schedule(musb, urb, qh->hw_ep, is_in);
|
||||
}
|
||||
} else {
|
||||
/* Just empty the queue; the hardware is busy with
|
||||
* other transfers, and since !qh->is_ready nothing
|
||||
* will activate any of these as it advances.
|
||||
*/
|
||||
while (!list_empty(&hep->urb_list))
|
||||
__musb_giveback(musb, next_urb(qh), -ESHUTDOWN);
|
||||
|
||||
hep->hcpriv = NULL;
|
||||
list_del(&qh->ring);
|
||||
kfree(qh);
|
||||
}
|
||||
exit:
|
||||
spin_unlock_irqrestore(&musb->lock, flags);
|
||||
}
|
||||
|
||||
|
|
|
@ -294,7 +294,11 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po
|
|||
|
||||
/* Ericsson products */
|
||||
#define ERICSSON_VENDOR_ID 0x0bdb
|
||||
#define ERICSSON_PRODUCT_F3507G 0x1900
|
||||
#define ERICSSON_PRODUCT_F3507G_1 0x1900
|
||||
#define ERICSSON_PRODUCT_F3507G_2 0x1902
|
||||
|
||||
#define BENQ_VENDOR_ID 0x04a5
|
||||
#define BENQ_PRODUCT_H10 0x4068
|
||||
|
||||
static struct usb_device_id option_ids[] = {
|
||||
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
|
||||
|
@ -509,7 +513,10 @@ static struct usb_device_id option_ids[] = {
|
|||
{ USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF626) },
|
||||
{ USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628) },
|
||||
{ USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) },
|
||||
{ USB_DEVICE(ERICSSON_VENDOR_ID, ERICSSON_PRODUCT_F3507G) },
|
||||
{ USB_DEVICE(ERICSSON_VENDOR_ID, ERICSSON_PRODUCT_F3507G_1) },
|
||||
{ USB_DEVICE(ERICSSON_VENDOR_ID, ERICSSON_PRODUCT_F3507G_2) },
|
||||
{ USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) },
|
||||
{ USB_DEVICE(0x1da5, 0x4515) }, /* BenQ H20 */
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, option_ids);
|
||||
|
|
|
@ -907,13 +907,13 @@ UNUSUAL_DEV( 0x05e3, 0x0701, 0x0000, 0xffff,
|
|||
"Genesys Logic",
|
||||
"USB to IDE Optical",
|
||||
US_SC_DEVICE, US_PR_DEVICE, NULL,
|
||||
US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 ),
|
||||
US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 | US_FL_IGNORE_RESIDUE ),
|
||||
|
||||
UNUSUAL_DEV( 0x05e3, 0x0702, 0x0000, 0xffff,
|
||||
"Genesys Logic",
|
||||
"USB to IDE Disk",
|
||||
US_SC_DEVICE, US_PR_DEVICE, NULL,
|
||||
US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 ),
|
||||
US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 | US_FL_IGNORE_RESIDUE ),
|
||||
|
||||
/* Reported by Ben Efros <ben@pc-doctor.com> */
|
||||
UNUSUAL_DEV( 0x05e3, 0x0723, 0x9451, 0x9451,
|
||||
|
|
|
@ -16,6 +16,12 @@ config W1_SLAVE_SMEM
|
|||
Say Y here if you want to connect 1-wire
|
||||
simple 64bit memory rom(ds2401/ds2411/ds1990*) to your wire.
|
||||
|
||||
config W1_SLAVE_DS2431
|
||||
tristate "1kb EEPROM family support (DS2431)"
|
||||
help
|
||||
Say Y here if you want to use a 1-wire
|
||||
1kb EEPROM family device (DS2431)
|
||||
|
||||
config W1_SLAVE_DS2433
|
||||
tristate "4kb EEPROM family support (DS2433)"
|
||||
help
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
obj-$(CONFIG_W1_SLAVE_THERM) += w1_therm.o
|
||||
obj-$(CONFIG_W1_SLAVE_SMEM) += w1_smem.o
|
||||
obj-$(CONFIG_W1_SLAVE_DS2431) += w1_ds2431.o
|
||||
obj-$(CONFIG_W1_SLAVE_DS2433) += w1_ds2433.o
|
||||
obj-$(CONFIG_W1_SLAVE_DS2760) += w1_ds2760.o
|
||||
obj-$(CONFIG_W1_SLAVE_BQ27000) += w1_bq27000.o
|
||||
|
|
|
@ -156,6 +156,9 @@ out_up:
|
|||
*/
|
||||
static int w1_f23_write(struct w1_slave *sl, int addr, int len, const u8 *data)
|
||||
{
|
||||
#ifdef CONFIG_W1_SLAVE_DS2433_CRC
|
||||
struct w1_f23_data *f23 = sl->family_data;
|
||||
#endif
|
||||
u8 wrbuf[4];
|
||||
u8 rdbuf[W1_PAGE_SIZE + 3];
|
||||
u8 es = (addr + len - 1) & 0x1f;
|
||||
|
@ -196,7 +199,9 @@ static int w1_f23_write(struct w1_slave *sl, int addr, int len, const u8 *data)
|
|||
|
||||
/* Reset the bus to wake up the EEPROM (this may not be needed) */
|
||||
w1_reset_bus(sl->master);
|
||||
|
||||
#ifdef CONFIG_W1_SLAVE_DS2433_CRC
|
||||
f23->validcrc &= ~(1 << (addr >> W1_PAGE_BITS));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1913,6 +1913,9 @@ COMPATIBLE_IOCTL(FIONREAD) /* This is also TIOCINQ */
|
|||
/* 0x00 */
|
||||
COMPATIBLE_IOCTL(FIBMAP)
|
||||
COMPATIBLE_IOCTL(FIGETBSZ)
|
||||
/* 'X' - originally XFS but some now in the VFS */
|
||||
COMPATIBLE_IOCTL(FIFREEZE)
|
||||
COMPATIBLE_IOCTL(FITHAW)
|
||||
/* RAID */
|
||||
COMPATIBLE_IOCTL(RAID_VERSION)
|
||||
COMPATIBLE_IOCTL(GET_ARRAY_INFO)
|
||||
|
|
|
@ -1180,7 +1180,7 @@ struct dentry *d_obtain_alias(struct inode *inode)
|
|||
iput(inode);
|
||||
return res;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(d_obtain_alias);
|
||||
EXPORT_SYMBOL(d_obtain_alias);
|
||||
|
||||
/**
|
||||
* d_splice_alias - splice a disconnected dentry into the tree if one exists
|
||||
|
|
|
@ -95,13 +95,17 @@ static int jffs2_garbage_collect_thread(void *_c)
|
|||
spin_unlock(&c->erase_completion_lock);
|
||||
|
||||
|
||||
/* This thread is purely an optimisation. But if it runs when
|
||||
other things could be running, it actually makes things a
|
||||
lot worse. Use yield() and put it at the back of the runqueue
|
||||
every time. Especially during boot, pulling an inode in
|
||||
with read_inode() is much preferable to having the GC thread
|
||||
get there first. */
|
||||
yield();
|
||||
/* Problem - immediately after bootup, the GCD spends a lot
|
||||
* of time in places like jffs2_kill_fragtree(); so much so
|
||||
* that userspace processes (like gdm and X) are starved
|
||||
* despite plenty of cond_resched()s and renicing. Yield()
|
||||
* doesn't help, either (presumably because userspace and GCD
|
||||
* are generally competing for a higher latency resource -
|
||||
* disk).
|
||||
* This forces the GCD to slow the hell down. Pulling an
|
||||
* inode in with read_inode() is much preferable to having
|
||||
* the GC thread get there first. */
|
||||
schedule_timeout_interruptible(msecs_to_jiffies(50));
|
||||
|
||||
/* Put_super will send a SIGKILL and then wait on the sem.
|
||||
*/
|
||||
|
|
|
@ -220,7 +220,7 @@ static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c,
|
|||
struct jffs2_tmp_dnode_info *tn)
|
||||
{
|
||||
uint32_t fn_end = tn->fn->ofs + tn->fn->size;
|
||||
struct jffs2_tmp_dnode_info *this;
|
||||
struct jffs2_tmp_dnode_info *this, *ptn;
|
||||
|
||||
dbg_readinode("insert fragment %#04x-%#04x, ver %u at %08x\n", tn->fn->ofs, fn_end, tn->version, ref_offset(tn->fn->raw));
|
||||
|
||||
|
@ -251,11 +251,18 @@ static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c,
|
|||
if (this) {
|
||||
/* If the node is coincident with another at a lower address,
|
||||
back up until the other node is found. It may be relevant */
|
||||
while (this->overlapped)
|
||||
this = tn_prev(this);
|
||||
|
||||
/* First node should never be marked overlapped */
|
||||
BUG_ON(!this);
|
||||
while (this->overlapped) {
|
||||
ptn = tn_prev(this);
|
||||
if (!ptn) {
|
||||
/*
|
||||
* We killed a node which set the overlapped
|
||||
* flags during the scan. Fix it up.
|
||||
*/
|
||||
this->overlapped = 0;
|
||||
break;
|
||||
}
|
||||
this = ptn;
|
||||
}
|
||||
dbg_readinode("'this' found %#04x-%#04x (%s)\n", this->fn->ofs, this->fn->ofs + this->fn->size, this->fn ? "data" : "hole");
|
||||
}
|
||||
|
||||
|
@ -360,7 +367,17 @@ static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c,
|
|||
}
|
||||
if (!this->overlapped)
|
||||
break;
|
||||
this = tn_prev(this);
|
||||
|
||||
ptn = tn_prev(this);
|
||||
if (!ptn) {
|
||||
/*
|
||||
* We killed a node which set the overlapped
|
||||
* flags during the scan. Fix it up.
|
||||
*/
|
||||
this->overlapped = 0;
|
||||
break;
|
||||
}
|
||||
this = ptn;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -456,8 +473,15 @@ static int jffs2_build_inode_fragtree(struct jffs2_sb_info *c,
|
|||
eat_last(&rii->tn_root, &last->rb);
|
||||
ver_insert(&ver_root, last);
|
||||
|
||||
if (unlikely(last->overlapped))
|
||||
continue;
|
||||
if (unlikely(last->overlapped)) {
|
||||
if (pen)
|
||||
continue;
|
||||
/*
|
||||
* We killed a node which set the overlapped
|
||||
* flags during the scan. Fix it up.
|
||||
*/
|
||||
last->overlapped = 0;
|
||||
}
|
||||
|
||||
/* Now we have a bunch of nodes in reverse version
|
||||
order, in the tree at ver_root. Most of the time,
|
||||
|
|
|
@ -4796,6 +4796,29 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int ocfs2_replace_extent_rec(struct inode *inode,
|
||||
handle_t *handle,
|
||||
struct ocfs2_path *path,
|
||||
struct ocfs2_extent_list *el,
|
||||
int split_index,
|
||||
struct ocfs2_extent_rec *split_rec)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = ocfs2_path_bh_journal_access(handle, inode, path,
|
||||
path_num_items(path) - 1);
|
||||
if (ret) {
|
||||
mlog_errno(ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
el->l_recs[split_index] = *split_rec;
|
||||
|
||||
ocfs2_journal_dirty(handle, path_leaf_bh(path));
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Mark part or all of the extent record at split_index in the leaf
|
||||
* pointed to by path as written. This removes the unwritten
|
||||
|
@ -4885,7 +4908,9 @@ static int __ocfs2_mark_extent_written(struct inode *inode,
|
|||
|
||||
if (ctxt.c_contig_type == CONTIG_NONE) {
|
||||
if (ctxt.c_split_covers_rec)
|
||||
el->l_recs[split_index] = *split_rec;
|
||||
ret = ocfs2_replace_extent_rec(inode, handle,
|
||||
path, el,
|
||||
split_index, split_rec);
|
||||
else
|
||||
ret = ocfs2_split_and_insert(inode, handle, path, et,
|
||||
&last_eb_bh, split_index,
|
||||
|
|
|
@ -1849,12 +1849,12 @@ int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data,
|
|||
if (!mle) {
|
||||
if (res->owner != DLM_LOCK_RES_OWNER_UNKNOWN &&
|
||||
res->owner != assert->node_idx) {
|
||||
mlog(ML_ERROR, "assert_master from "
|
||||
"%u, but current owner is "
|
||||
"%u! (%.*s)\n",
|
||||
assert->node_idx, res->owner,
|
||||
namelen, name);
|
||||
goto kill;
|
||||
mlog(ML_ERROR, "DIE! Mastery assert from %u, "
|
||||
"but current owner is %u! (%.*s)\n",
|
||||
assert->node_idx, res->owner, namelen,
|
||||
name);
|
||||
__dlm_print_one_lock_resource(res);
|
||||
BUG();
|
||||
}
|
||||
} else if (mle->type != DLM_MLE_MIGRATION) {
|
||||
if (res->owner != DLM_LOCK_RES_OWNER_UNKNOWN) {
|
||||
|
|
|
@ -181,8 +181,7 @@ static int dlm_purge_lockres(struct dlm_ctxt *dlm,
|
|||
|
||||
spin_lock(&res->spinlock);
|
||||
/* This ensures that clear refmap is sent after the set */
|
||||
__dlm_wait_on_lockres_flags(res, (DLM_LOCK_RES_SETREF_INPROG |
|
||||
DLM_LOCK_RES_MIGRATING));
|
||||
__dlm_wait_on_lockres_flags(res, DLM_LOCK_RES_SETREF_INPROG);
|
||||
spin_unlock(&res->spinlock);
|
||||
|
||||
/* clear our bit from the master's refmap, ignore errors */
|
||||
|
|
|
@ -117,11 +117,11 @@ static enum dlm_status dlmunlock_common(struct dlm_ctxt *dlm,
|
|||
else
|
||||
BUG_ON(res->owner == dlm->node_num);
|
||||
|
||||
spin_lock(&dlm->spinlock);
|
||||
spin_lock(&dlm->ast_lock);
|
||||
/* We want to be sure that we're not freeing a lock
|
||||
* that still has AST's pending... */
|
||||
in_use = !list_empty(&lock->ast_list);
|
||||
spin_unlock(&dlm->spinlock);
|
||||
spin_unlock(&dlm->ast_lock);
|
||||
if (in_use) {
|
||||
mlog(ML_ERROR, "lockres %.*s: Someone is calling dlmunlock "
|
||||
"while waiting for an ast!", res->lockname.len,
|
||||
|
|
|
@ -320,9 +320,14 @@ static void ocfs2_schedule_blocked_lock(struct ocfs2_super *osb,
|
|||
struct ocfs2_lock_res *lockres);
|
||||
static inline void ocfs2_recover_from_dlm_error(struct ocfs2_lock_res *lockres,
|
||||
int convert);
|
||||
#define ocfs2_log_dlm_error(_func, _err, _lockres) do { \
|
||||
mlog(ML_ERROR, "DLM error %d while calling %s on resource %s\n", \
|
||||
_err, _func, _lockres->l_name); \
|
||||
#define ocfs2_log_dlm_error(_func, _err, _lockres) do { \
|
||||
if ((_lockres)->l_type != OCFS2_LOCK_TYPE_DENTRY) \
|
||||
mlog(ML_ERROR, "DLM error %d while calling %s on resource %s\n", \
|
||||
_err, _func, _lockres->l_name); \
|
||||
else \
|
||||
mlog(ML_ERROR, "DLM error %d while calling %s on resource %.*s%08x\n", \
|
||||
_err, _func, OCFS2_DENTRY_LOCK_INO_START - 1, (_lockres)->l_name, \
|
||||
(unsigned int)ocfs2_get_dentry_lock_ino(_lockres)); \
|
||||
} while (0)
|
||||
static int ocfs2_downconvert_thread(void *arg);
|
||||
static void ocfs2_downconvert_on_unlock(struct ocfs2_super *osb,
|
||||
|
|
|
@ -341,6 +341,9 @@ struct ocfs2_super
|
|||
struct ocfs2_node_map osb_recovering_orphan_dirs;
|
||||
unsigned int *osb_orphan_wipes;
|
||||
wait_queue_head_t osb_wipe_event;
|
||||
|
||||
/* used to protect metaecc calculation check of xattr. */
|
||||
spinlock_t osb_xattr_lock;
|
||||
};
|
||||
|
||||
#define OCFS2_SB(sb) ((struct ocfs2_super *)(sb)->s_fs_info)
|
||||
|
|
|
@ -1537,6 +1537,13 @@ static int ocfs2_get_sector(struct super_block *sb,
|
|||
unlock_buffer(*bh);
|
||||
ll_rw_block(READ, 1, bh);
|
||||
wait_on_buffer(*bh);
|
||||
if (!buffer_uptodate(*bh)) {
|
||||
mlog_errno(-EIO);
|
||||
brelse(*bh);
|
||||
*bh = NULL;
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1747,6 +1754,7 @@ static int ocfs2_initialize_super(struct super_block *sb,
|
|||
INIT_LIST_HEAD(&osb->blocked_lock_list);
|
||||
osb->blocked_lock_count = 0;
|
||||
spin_lock_init(&osb->osb_lock);
|
||||
spin_lock_init(&osb->osb_xattr_lock);
|
||||
ocfs2_init_inode_steal_slot(osb);
|
||||
|
||||
atomic_set(&osb->alloc_stats.moves, 0);
|
||||
|
|
|
@ -82,13 +82,14 @@ struct ocfs2_xattr_set_ctxt {
|
|||
|
||||
#define OCFS2_XATTR_ROOT_SIZE (sizeof(struct ocfs2_xattr_def_value_root))
|
||||
#define OCFS2_XATTR_INLINE_SIZE 80
|
||||
#define OCFS2_XATTR_HEADER_GAP 4
|
||||
#define OCFS2_XATTR_FREE_IN_IBODY (OCFS2_MIN_XATTR_INLINE_SIZE \
|
||||
- sizeof(struct ocfs2_xattr_header) \
|
||||
- sizeof(__u32))
|
||||
- OCFS2_XATTR_HEADER_GAP)
|
||||
#define OCFS2_XATTR_FREE_IN_BLOCK(ptr) ((ptr)->i_sb->s_blocksize \
|
||||
- sizeof(struct ocfs2_xattr_block) \
|
||||
- sizeof(struct ocfs2_xattr_header) \
|
||||
- sizeof(__u32))
|
||||
- OCFS2_XATTR_HEADER_GAP)
|
||||
|
||||
static struct ocfs2_xattr_def_value_root def_xv = {
|
||||
.xv.xr_list.l_count = cpu_to_le16(1),
|
||||
|
@ -274,10 +275,12 @@ static int ocfs2_read_xattr_bucket(struct ocfs2_xattr_bucket *bucket,
|
|||
bucket->bu_blocks, bucket->bu_bhs, 0,
|
||||
NULL);
|
||||
if (!rc) {
|
||||
spin_lock(&OCFS2_SB(bucket->bu_inode->i_sb)->osb_xattr_lock);
|
||||
rc = ocfs2_validate_meta_ecc_bhs(bucket->bu_inode->i_sb,
|
||||
bucket->bu_bhs,
|
||||
bucket->bu_blocks,
|
||||
&bucket_xh(bucket)->xh_check);
|
||||
spin_unlock(&OCFS2_SB(bucket->bu_inode->i_sb)->osb_xattr_lock);
|
||||
if (rc)
|
||||
mlog_errno(rc);
|
||||
}
|
||||
|
@ -310,9 +313,11 @@ static void ocfs2_xattr_bucket_journal_dirty(handle_t *handle,
|
|||
{
|
||||
int i;
|
||||
|
||||
spin_lock(&OCFS2_SB(bucket->bu_inode->i_sb)->osb_xattr_lock);
|
||||
ocfs2_compute_meta_ecc_bhs(bucket->bu_inode->i_sb,
|
||||
bucket->bu_bhs, bucket->bu_blocks,
|
||||
&bucket_xh(bucket)->xh_check);
|
||||
spin_unlock(&OCFS2_SB(bucket->bu_inode->i_sb)->osb_xattr_lock);
|
||||
|
||||
for (i = 0; i < bucket->bu_blocks; i++)
|
||||
ocfs2_journal_dirty(handle, bucket->bu_bhs[i]);
|
||||
|
@ -1507,7 +1512,7 @@ static int ocfs2_xattr_set_entry(struct inode *inode,
|
|||
last += 1;
|
||||
}
|
||||
|
||||
free = min_offs - ((void *)last - xs->base) - sizeof(__u32);
|
||||
free = min_offs - ((void *)last - xs->base) - OCFS2_XATTR_HEADER_GAP;
|
||||
if (free < 0)
|
||||
return -EIO;
|
||||
|
||||
|
@ -2190,7 +2195,7 @@ static int ocfs2_xattr_can_be_in_inode(struct inode *inode,
|
|||
last += 1;
|
||||
}
|
||||
|
||||
free = min_offs - ((void *)last - xs->base) - sizeof(__u32);
|
||||
free = min_offs - ((void *)last - xs->base) - OCFS2_XATTR_HEADER_GAP;
|
||||
if (free < 0)
|
||||
return 0;
|
||||
|
||||
|
@ -2592,8 +2597,9 @@ static int __ocfs2_xattr_set_handle(struct inode *inode,
|
|||
|
||||
if (!ret) {
|
||||
/* Update inode ctime. */
|
||||
ret = ocfs2_journal_access(ctxt->handle, inode, xis->inode_bh,
|
||||
OCFS2_JOURNAL_ACCESS_WRITE);
|
||||
ret = ocfs2_journal_access_di(ctxt->handle, inode,
|
||||
xis->inode_bh,
|
||||
OCFS2_JOURNAL_ACCESS_WRITE);
|
||||
if (ret) {
|
||||
mlog_errno(ret);
|
||||
goto out;
|
||||
|
@ -5060,8 +5066,8 @@ try_again:
|
|||
xh_free_start = le16_to_cpu(xh->xh_free_start);
|
||||
header_size = sizeof(struct ocfs2_xattr_header) +
|
||||
count * sizeof(struct ocfs2_xattr_entry);
|
||||
max_free = OCFS2_XATTR_BUCKET_SIZE -
|
||||
le16_to_cpu(xh->xh_name_value_len) - header_size;
|
||||
max_free = OCFS2_XATTR_BUCKET_SIZE - header_size -
|
||||
le16_to_cpu(xh->xh_name_value_len) - OCFS2_XATTR_HEADER_GAP;
|
||||
|
||||
mlog_bug_on_msg(header_size > blocksize, "bucket %llu has header size "
|
||||
"of %u which exceed block size\n",
|
||||
|
@ -5094,7 +5100,7 @@ try_again:
|
|||
need = 0;
|
||||
}
|
||||
|
||||
free = xh_free_start - header_size;
|
||||
free = xh_free_start - header_size - OCFS2_XATTR_HEADER_GAP;
|
||||
/*
|
||||
* We need to make sure the new name/value pair
|
||||
* can exist in the same block.
|
||||
|
@ -5127,7 +5133,8 @@ try_again:
|
|||
}
|
||||
|
||||
xh_free_start = le16_to_cpu(xh->xh_free_start);
|
||||
free = xh_free_start - header_size;
|
||||
free = xh_free_start - header_size
|
||||
- OCFS2_XATTR_HEADER_GAP;
|
||||
if (xh_free_start % blocksize < need)
|
||||
free -= xh_free_start % blocksize;
|
||||
|
||||
|
|
|
@ -30,11 +30,14 @@
|
|||
* See Documentation/io_mapping.txt
|
||||
*/
|
||||
|
||||
/* this struct isn't actually defined anywhere */
|
||||
struct io_mapping;
|
||||
|
||||
#ifdef CONFIG_HAVE_ATOMIC_IOMAP
|
||||
|
||||
struct io_mapping {
|
||||
resource_size_t base;
|
||||
unsigned long size;
|
||||
pgprot_t prot;
|
||||
};
|
||||
|
||||
/*
|
||||
* For small address space machines, mapping large objects
|
||||
* into the kernel virtual space isn't practical. Where
|
||||
|
@ -43,23 +46,40 @@ struct io_mapping;
|
|||
*/
|
||||
|
||||
static inline struct io_mapping *
|
||||
io_mapping_create_wc(unsigned long base, unsigned long size)
|
||||
io_mapping_create_wc(resource_size_t base, unsigned long size)
|
||||
{
|
||||
return (struct io_mapping *) base;
|
||||
struct io_mapping *iomap;
|
||||
|
||||
if (!is_io_mapping_possible(base, size))
|
||||
return NULL;
|
||||
|
||||
iomap = kmalloc(sizeof(*iomap), GFP_KERNEL);
|
||||
if (!iomap)
|
||||
return NULL;
|
||||
|
||||
iomap->base = base;
|
||||
iomap->size = size;
|
||||
iomap->prot = pgprot_writecombine(__pgprot(__PAGE_KERNEL));
|
||||
return iomap;
|
||||
}
|
||||
|
||||
static inline void
|
||||
io_mapping_free(struct io_mapping *mapping)
|
||||
{
|
||||
kfree(mapping);
|
||||
}
|
||||
|
||||
/* Atomic map/unmap */
|
||||
static inline void *
|
||||
io_mapping_map_atomic_wc(struct io_mapping *mapping, unsigned long offset)
|
||||
{
|
||||
offset += (unsigned long) mapping;
|
||||
return iomap_atomic_prot_pfn(offset >> PAGE_SHIFT, KM_USER0,
|
||||
__pgprot(__PAGE_KERNEL_WC));
|
||||
resource_size_t phys_addr;
|
||||
unsigned long pfn;
|
||||
|
||||
BUG_ON(offset >= mapping->size);
|
||||
phys_addr = mapping->base + offset;
|
||||
pfn = (unsigned long) (phys_addr >> PAGE_SHIFT);
|
||||
return iomap_atomic_prot_pfn(pfn, KM_USER0, mapping->prot);
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
@ -71,8 +91,9 @@ io_mapping_unmap_atomic(void *vaddr)
|
|||
static inline void *
|
||||
io_mapping_map_wc(struct io_mapping *mapping, unsigned long offset)
|
||||
{
|
||||
offset += (unsigned long) mapping;
|
||||
return ioremap_wc(offset, PAGE_SIZE);
|
||||
BUG_ON(offset >= mapping->size);
|
||||
resource_size_t phys_addr = mapping->base + offset;
|
||||
return ioremap_wc(phys_addr, PAGE_SIZE);
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
@ -83,9 +104,12 @@ io_mapping_unmap(void *vaddr)
|
|||
|
||||
#else
|
||||
|
||||
/* this struct isn't actually defined anywhere */
|
||||
struct io_mapping;
|
||||
|
||||
/* Create the io_mapping object*/
|
||||
static inline struct io_mapping *
|
||||
io_mapping_create_wc(unsigned long base, unsigned long size)
|
||||
io_mapping_create_wc(resource_size_t base, unsigned long size)
|
||||
{
|
||||
return (struct io_mapping *) ioremap_wc(base, size);
|
||||
}
|
||||
|
|
|
@ -157,4 +157,7 @@ static inline void tracepoint_synchronize_unregister(void)
|
|||
#define TRACE_FORMAT(name, proto, args, fmt) \
|
||||
DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
|
||||
|
||||
#define TRACE_EVENT_FORMAT(name, proto, args, fmt, struct, tpfmt) \
|
||||
TRACE_FORMAT(name, PARAMS(proto), PARAMS(args), PARAMS(fmt))
|
||||
|
||||
#endif
|
||||
|
|
|
@ -13,6 +13,7 @@ struct user_namespace {
|
|||
struct kref kref;
|
||||
struct hlist_head uidhash_table[UIDHASH_SZ];
|
||||
struct user_struct *creator;
|
||||
struct work_struct destroyer;
|
||||
};
|
||||
|
||||
extern struct user_namespace init_user_ns;
|
||||
|
|
|
@ -5,13 +5,29 @@
|
|||
# error Unless you know what you are doing.
|
||||
#endif
|
||||
|
||||
TRACE_FORMAT(irq_handler_entry,
|
||||
#undef TRACE_SYSTEM
|
||||
#define TRACE_SYSTEM irq
|
||||
|
||||
TRACE_EVENT_FORMAT(irq_handler_entry,
|
||||
TPPROTO(int irq, struct irqaction *action),
|
||||
TPARGS(irq, action),
|
||||
TPFMT("irq=%d handler=%s", irq, action->name));
|
||||
TPFMT("irq=%d handler=%s", irq, action->name),
|
||||
TRACE_STRUCT(
|
||||
TRACE_FIELD(int, irq, irq)
|
||||
),
|
||||
TPRAWFMT("irq %d")
|
||||
);
|
||||
|
||||
TRACE_FORMAT(irq_handler_exit,
|
||||
TRACE_EVENT_FORMAT(irq_handler_exit,
|
||||
TPPROTO(int irq, struct irqaction *action, int ret),
|
||||
TPARGS(irq, action, ret),
|
||||
TPFMT("irq=%d handler=%s return=%s",
|
||||
irq, action->name, ret ? "handled" : "unhandled"));
|
||||
irq, action->name, ret ? "handled" : "unhandled"),
|
||||
TRACE_STRUCT(
|
||||
TRACE_FIELD(int, irq, irq)
|
||||
TRACE_FIELD(int, ret, ret)
|
||||
),
|
||||
TPRAWFMT("irq %d ret %d")
|
||||
);
|
||||
|
||||
#undef TRACE_SYSTEM
|
||||
|
|
|
@ -1,72 +1,146 @@
|
|||
|
||||
/* use <trace/sched.h> instead */
|
||||
#ifndef TRACE_FORMAT
|
||||
#ifndef TRACE_EVENT_FORMAT
|
||||
# error Do not include this file directly.
|
||||
# error Unless you know what you are doing.
|
||||
#endif
|
||||
|
||||
TRACE_FORMAT(sched_kthread_stop,
|
||||
#undef TRACE_SYSTEM
|
||||
#define TRACE_SYSTEM sched
|
||||
|
||||
TRACE_EVENT_FORMAT(sched_kthread_stop,
|
||||
TPPROTO(struct task_struct *t),
|
||||
TPARGS(t),
|
||||
TPFMT("task %s:%d", t->comm, t->pid));
|
||||
TPFMT("task %s:%d", t->comm, t->pid),
|
||||
TRACE_STRUCT(
|
||||
TRACE_FIELD(pid_t, pid, t->pid)
|
||||
),
|
||||
TPRAWFMT("task %d")
|
||||
);
|
||||
|
||||
TRACE_FORMAT(sched_kthread_stop_ret,
|
||||
TRACE_EVENT_FORMAT(sched_kthread_stop_ret,
|
||||
TPPROTO(int ret),
|
||||
TPARGS(ret),
|
||||
TPFMT("ret=%d", ret));
|
||||
TPFMT("ret=%d", ret),
|
||||
TRACE_STRUCT(
|
||||
TRACE_FIELD(int, ret, ret)
|
||||
),
|
||||
TPRAWFMT("ret=%d")
|
||||
);
|
||||
|
||||
TRACE_FORMAT(sched_wait_task,
|
||||
TRACE_EVENT_FORMAT(sched_wait_task,
|
||||
TPPROTO(struct rq *rq, struct task_struct *p),
|
||||
TPARGS(rq, p),
|
||||
TPFMT("task %s:%d", p->comm, p->pid));
|
||||
TPFMT("task %s:%d", p->comm, p->pid),
|
||||
TRACE_STRUCT(
|
||||
TRACE_FIELD(pid_t, pid, p->pid)
|
||||
),
|
||||
TPRAWFMT("task %d")
|
||||
);
|
||||
|
||||
TRACE_FORMAT(sched_wakeup,
|
||||
TRACE_EVENT_FORMAT(sched_wakeup,
|
||||
TPPROTO(struct rq *rq, struct task_struct *p, int success),
|
||||
TPARGS(rq, p, success),
|
||||
TPFMT("task %s:%d %s",
|
||||
p->comm, p->pid, success?"succeeded":"failed"));
|
||||
p->comm, p->pid, success ? "succeeded" : "failed"),
|
||||
TRACE_STRUCT(
|
||||
TRACE_FIELD(pid_t, pid, p->pid)
|
||||
TRACE_FIELD(int, success, success)
|
||||
),
|
||||
TPRAWFMT("task %d success=%d")
|
||||
);
|
||||
|
||||
TRACE_FORMAT(sched_wakeup_new,
|
||||
TRACE_EVENT_FORMAT(sched_wakeup_new,
|
||||
TPPROTO(struct rq *rq, struct task_struct *p, int success),
|
||||
TPARGS(rq, p, success),
|
||||
TPFMT("task %s:%d",
|
||||
p->comm, p->pid, success?"succeeded":"failed"));
|
||||
p->comm, p->pid, success ? "succeeded" : "failed"),
|
||||
TRACE_STRUCT(
|
||||
TRACE_FIELD(pid_t, pid, p->pid)
|
||||
TRACE_FIELD(int, success, success)
|
||||
),
|
||||
TPRAWFMT("task %d success=%d")
|
||||
);
|
||||
|
||||
TRACE_FORMAT(sched_switch,
|
||||
TRACE_EVENT_FORMAT(sched_switch,
|
||||
TPPROTO(struct rq *rq, struct task_struct *prev,
|
||||
struct task_struct *next),
|
||||
TPARGS(rq, prev, next),
|
||||
TPFMT("task %s:%d ==> %s:%d",
|
||||
prev->comm, prev->pid, next->comm, next->pid));
|
||||
prev->comm, prev->pid, next->comm, next->pid),
|
||||
TRACE_STRUCT(
|
||||
TRACE_FIELD(pid_t, prev_pid, prev->pid)
|
||||
TRACE_FIELD(int, prev_prio, prev->prio)
|
||||
TRACE_FIELD(pid_t, next_pid, next->pid)
|
||||
TRACE_FIELD(int, next_prio, next->prio)
|
||||
),
|
||||
TPRAWFMT("prev %d:%d ==> next %d:%d")
|
||||
);
|
||||
|
||||
TRACE_FORMAT(sched_migrate_task,
|
||||
TRACE_EVENT_FORMAT(sched_migrate_task,
|
||||
TPPROTO(struct task_struct *p, int orig_cpu, int dest_cpu),
|
||||
TPARGS(p, orig_cpu, dest_cpu),
|
||||
TPFMT("task %s:%d from: %d to: %d",
|
||||
p->comm, p->pid, orig_cpu, dest_cpu));
|
||||
p->comm, p->pid, orig_cpu, dest_cpu),
|
||||
TRACE_STRUCT(
|
||||
TRACE_FIELD(pid_t, pid, p->pid)
|
||||
TRACE_FIELD(int, orig_cpu, orig_cpu)
|
||||
TRACE_FIELD(int, dest_cpu, dest_cpu)
|
||||
),
|
||||
TPRAWFMT("task %d from: %d to: %d")
|
||||
);
|
||||
|
||||
TRACE_FORMAT(sched_process_free,
|
||||
TRACE_EVENT_FORMAT(sched_process_free,
|
||||
TPPROTO(struct task_struct *p),
|
||||
TPARGS(p),
|
||||
TPFMT("task %s:%d", p->comm, p->pid));
|
||||
TPFMT("task %s:%d", p->comm, p->pid),
|
||||
TRACE_STRUCT(
|
||||
TRACE_FIELD(pid_t, pid, p->pid)
|
||||
),
|
||||
TPRAWFMT("task %d")
|
||||
);
|
||||
|
||||
TRACE_FORMAT(sched_process_exit,
|
||||
TRACE_EVENT_FORMAT(sched_process_exit,
|
||||
TPPROTO(struct task_struct *p),
|
||||
TPARGS(p),
|
||||
TPFMT("task %s:%d", p->comm, p->pid));
|
||||
TPFMT("task %s:%d", p->comm, p->pid),
|
||||
TRACE_STRUCT(
|
||||
TRACE_FIELD(pid_t, pid, p->pid)
|
||||
),
|
||||
TPRAWFMT("task %d")
|
||||
);
|
||||
|
||||
TRACE_FORMAT(sched_process_wait,
|
||||
TRACE_EVENT_FORMAT(sched_process_wait,
|
||||
TPPROTO(struct pid *pid),
|
||||
TPARGS(pid),
|
||||
TPFMT("pid %d", pid));
|
||||
TPFMT("pid %d", pid_nr(pid)),
|
||||
TRACE_STRUCT(
|
||||
TRACE_FIELD(pid_t, pid, pid_nr(pid))
|
||||
),
|
||||
TPRAWFMT("task %d")
|
||||
);
|
||||
|
||||
TRACE_FORMAT(sched_process_fork,
|
||||
TRACE_EVENT_FORMAT(sched_process_fork,
|
||||
TPPROTO(struct task_struct *parent, struct task_struct *child),
|
||||
TPARGS(parent, child),
|
||||
TPFMT("parent %s:%d child %s:%d",
|
||||
parent->comm, parent->pid, child->comm, child->pid));
|
||||
parent->comm, parent->pid, child->comm, child->pid),
|
||||
TRACE_STRUCT(
|
||||
TRACE_FIELD(pid_t, parent, parent->pid)
|
||||
TRACE_FIELD(pid_t, child, child->pid)
|
||||
),
|
||||
TPRAWFMT("parent %d child %d")
|
||||
);
|
||||
|
||||
TRACE_FORMAT(sched_signal_send,
|
||||
TRACE_EVENT_FORMAT(sched_signal_send,
|
||||
TPPROTO(int sig, struct task_struct *p),
|
||||
TPARGS(sig, p),
|
||||
TPFMT("sig: %d task %s:%d", sig, p->comm, p->pid));
|
||||
TPFMT("sig: %d task %s:%d", sig, p->comm, p->pid),
|
||||
TRACE_STRUCT(
|
||||
TRACE_FIELD(int, sig, sig)
|
||||
TRACE_FIELD(pid_t, pid, p->pid)
|
||||
),
|
||||
TPRAWFMT("sig: %d task %d")
|
||||
);
|
||||
|
||||
#undef TRACE_SYSTEM
|
||||
|
|
4
include/trace/trace_event_types.h
Normal file
4
include/trace/trace_event_types.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
/* trace/<type>_event_types.h here */
|
||||
|
||||
#include <trace/sched_event_types.h>
|
||||
#include <trace/irq_event_types.h>
|
4
include/trace/trace_events.h
Normal file
4
include/trace/trace_events.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
/* trace/<type>.h here */
|
||||
|
||||
#include <trace/sched.h>
|
||||
#include <trace/irq.h>
|
|
@ -1,15 +1,17 @@
|
|||
/*
|
||||
* This is the place to register all trace points as events.
|
||||
* Include the trace/<type>.h at the top.
|
||||
* Include the trace/<type>_event_types.h at the bottom.
|
||||
*/
|
||||
|
||||
/* trace/<type>.h here */
|
||||
#include <trace/sched.h>
|
||||
#include <trace/irq.h>
|
||||
/* someday this needs to go in a generic header */
|
||||
#define __STR(x) #x
|
||||
#define STR(x) __STR(x)
|
||||
|
||||
#include "trace_events.h"
|
||||
#include <trace/trace_events.h>
|
||||
|
||||
/* trace/<type>_event_types.h here */
|
||||
#include <trace/sched_event_types.h>
|
||||
#include <trace/irq_event_types.h>
|
||||
#include "trace_output.h"
|
||||
|
||||
#include "trace_events_stage_1.h"
|
||||
#include "trace_events_stage_2.h"
|
||||
#include "trace_events_stage_3.h"
|
||||
|
||||
#include <trace/trace_event_types.h>
|
||||
|
|
|
@ -846,6 +846,20 @@ void trace_buffer_unlock_commit(struct trace_array *tr,
|
|||
trace_wake_up();
|
||||
}
|
||||
|
||||
struct ring_buffer_event *
|
||||
trace_current_buffer_lock_reserve(unsigned char type, unsigned long len,
|
||||
unsigned long flags, int pc)
|
||||
{
|
||||
return trace_buffer_lock_reserve(&global_trace,
|
||||
type, len, flags, pc);
|
||||
}
|
||||
|
||||
void trace_current_buffer_unlock_commit(struct ring_buffer_event *event,
|
||||
unsigned long flags, int pc)
|
||||
{
|
||||
return trace_buffer_unlock_commit(&global_trace, event, flags, pc);
|
||||
}
|
||||
|
||||
void
|
||||
trace_function(struct trace_array *tr,
|
||||
unsigned long ip, unsigned long parent_ip, unsigned long flags,
|
||||
|
@ -3328,7 +3342,7 @@ create_trace_option_files(struct tracer *tracer)
|
|||
for (cnt = 0; opts[cnt].name; cnt++)
|
||||
;
|
||||
|
||||
topts = kzalloc(sizeof(*topts) * (cnt + 1), GFP_KERNEL);
|
||||
topts = kcalloc(cnt + 1, sizeof(*topts), GFP_KERNEL);
|
||||
if (!topts)
|
||||
return NULL;
|
||||
|
||||
|
|
|
@ -442,6 +442,12 @@ void trace_buffer_unlock_commit(struct trace_array *tr,
|
|||
struct ring_buffer_event *event,
|
||||
unsigned long flags, int pc);
|
||||
|
||||
struct ring_buffer_event *
|
||||
trace_current_buffer_lock_reserve(unsigned char type, unsigned long len,
|
||||
unsigned long flags, int pc);
|
||||
void trace_current_buffer_unlock_commit(struct ring_buffer_event *event,
|
||||
unsigned long flags, int pc);
|
||||
|
||||
struct trace_entry *tracing_get_trace_entry(struct trace_array *tr,
|
||||
struct trace_array_cpu *data);
|
||||
|
||||
|
@ -720,4 +726,30 @@ static inline void trace_branch_disable(void)
|
|||
}
|
||||
#endif /* CONFIG_BRANCH_TRACER */
|
||||
|
||||
/* trace event type bit fields, not numeric */
|
||||
enum {
|
||||
TRACE_EVENT_TYPE_PRINTF = 1,
|
||||
TRACE_EVENT_TYPE_RAW = 2,
|
||||
};
|
||||
|
||||
struct ftrace_event_call {
|
||||
char *name;
|
||||
char *system;
|
||||
struct dentry *dir;
|
||||
int enabled;
|
||||
int (*regfunc)(void);
|
||||
void (*unregfunc)(void);
|
||||
int id;
|
||||
struct dentry *raw_dir;
|
||||
int raw_enabled;
|
||||
int type;
|
||||
int (*raw_init)(void);
|
||||
int (*raw_reg)(void);
|
||||
void (*raw_unreg)(void);
|
||||
};
|
||||
|
||||
void event_trace_printk(unsigned long ip, const char *fmt, ...);
|
||||
extern struct ftrace_event_call __start_ftrace_events[];
|
||||
extern struct ftrace_event_call __stop_ftrace_events[];
|
||||
|
||||
#endif /* _LINUX_KERNEL_TRACE_H */
|
||||
|
|
|
@ -10,7 +10,9 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/ctype.h>
|
||||
|
||||
#include "trace_events.h"
|
||||
#include "trace.h"
|
||||
|
||||
#define TRACE_SYSTEM "TRACE_SYSTEM"
|
||||
|
||||
#define events_for_each(event) \
|
||||
for (event = __start_ftrace_events; \
|
||||
|
@ -42,35 +44,87 @@ static void ftrace_clear_events(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void ftrace_event_enable_disable(struct ftrace_event_call *call,
|
||||
int enable)
|
||||
{
|
||||
|
||||
switch (enable) {
|
||||
case 0:
|
||||
if (call->enabled) {
|
||||
call->enabled = 0;
|
||||
call->unregfunc();
|
||||
}
|
||||
if (call->raw_enabled) {
|
||||
call->raw_enabled = 0;
|
||||
call->raw_unreg();
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (!call->enabled &&
|
||||
(call->type & TRACE_EVENT_TYPE_PRINTF)) {
|
||||
call->enabled = 1;
|
||||
call->regfunc();
|
||||
}
|
||||
if (!call->raw_enabled &&
|
||||
(call->type & TRACE_EVENT_TYPE_RAW)) {
|
||||
call->raw_enabled = 1;
|
||||
call->raw_reg();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int ftrace_set_clr_event(char *buf, int set)
|
||||
{
|
||||
struct ftrace_event_call *call = __start_ftrace_events;
|
||||
char *event = NULL, *sub = NULL, *match;
|
||||
int ret = -EINVAL;
|
||||
|
||||
/*
|
||||
* The buf format can be <subsystem>:<event-name>
|
||||
* *:<event-name> means any event by that name.
|
||||
* :<event-name> is the same.
|
||||
*
|
||||
* <subsystem>:* means all events in that subsystem
|
||||
* <subsystem>: means the same.
|
||||
*
|
||||
* <name> (no ':') means all events in a subsystem with
|
||||
* the name <name> or any event that matches <name>
|
||||
*/
|
||||
|
||||
match = strsep(&buf, ":");
|
||||
if (buf) {
|
||||
sub = match;
|
||||
event = buf;
|
||||
match = NULL;
|
||||
|
||||
if (!strlen(sub) || strcmp(sub, "*") == 0)
|
||||
sub = NULL;
|
||||
if (!strlen(event) || strcmp(event, "*") == 0)
|
||||
event = NULL;
|
||||
}
|
||||
|
||||
events_for_each(call) {
|
||||
|
||||
if (!call->name)
|
||||
continue;
|
||||
|
||||
if (strcmp(buf, call->name) != 0)
|
||||
if (match &&
|
||||
strcmp(match, call->name) != 0 &&
|
||||
strcmp(match, call->system) != 0)
|
||||
continue;
|
||||
|
||||
if (set) {
|
||||
/* Already set? */
|
||||
if (call->enabled)
|
||||
return 0;
|
||||
call->enabled = 1;
|
||||
call->regfunc();
|
||||
} else {
|
||||
/* Already cleared? */
|
||||
if (!call->enabled)
|
||||
return 0;
|
||||
call->enabled = 0;
|
||||
call->unregfunc();
|
||||
}
|
||||
return 0;
|
||||
if (sub && strcmp(sub, call->system) != 0)
|
||||
continue;
|
||||
|
||||
if (event && strcmp(event, call->name) != 0)
|
||||
continue;
|
||||
|
||||
ftrace_event_enable_disable(call, set);
|
||||
|
||||
ret = 0;
|
||||
}
|
||||
return -EINVAL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* 128 should be much more than enough */
|
||||
|
@ -200,6 +254,8 @@ static int t_show(struct seq_file *m, void *v)
|
|||
{
|
||||
struct ftrace_event_call *call = v;
|
||||
|
||||
if (strcmp(call->system, TRACE_SYSTEM) != 0)
|
||||
seq_printf(m, "%s:", call->system);
|
||||
seq_printf(m, "%s\n", call->name);
|
||||
|
||||
return 0;
|
||||
|
@ -236,7 +292,7 @@ event_enable_read(struct file *filp, char __user *ubuf, size_t cnt,
|
|||
struct ftrace_event_call *call = filp->private_data;
|
||||
char *buf;
|
||||
|
||||
if (call->enabled)
|
||||
if (call->enabled || call->raw_enabled)
|
||||
buf = "1\n";
|
||||
else
|
||||
buf = "0\n";
|
||||
|
@ -267,18 +323,8 @@ event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt,
|
|||
|
||||
switch (val) {
|
||||
case 0:
|
||||
if (!call->enabled)
|
||||
break;
|
||||
|
||||
call->enabled = 0;
|
||||
call->unregfunc();
|
||||
break;
|
||||
case 1:
|
||||
if (call->enabled)
|
||||
break;
|
||||
|
||||
call->enabled = 1;
|
||||
call->regfunc();
|
||||
ftrace_event_enable_disable(call, val);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -290,6 +336,107 @@ event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt,
|
|||
return cnt;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
event_type_read(struct file *filp, char __user *ubuf, size_t cnt,
|
||||
loff_t *ppos)
|
||||
{
|
||||
struct ftrace_event_call *call = filp->private_data;
|
||||
char buf[16];
|
||||
int r = 0;
|
||||
|
||||
if (call->type & TRACE_EVENT_TYPE_PRINTF)
|
||||
r += sprintf(buf, "printf\n");
|
||||
|
||||
if (call->type & TRACE_EVENT_TYPE_RAW)
|
||||
r += sprintf(buf+r, "raw\n");
|
||||
|
||||
return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
event_type_write(struct file *filp, const char __user *ubuf, size_t cnt,
|
||||
loff_t *ppos)
|
||||
{
|
||||
struct ftrace_event_call *call = filp->private_data;
|
||||
char buf[64];
|
||||
|
||||
/*
|
||||
* If there's only one type, we can't change it.
|
||||
* And currently we always have printf type, and we
|
||||
* may or may not have raw type.
|
||||
*
|
||||
* This is a redundant check, the file should be read
|
||||
* only if this is the case anyway.
|
||||
*/
|
||||
|
||||
if (!call->raw_init)
|
||||
return -EPERM;
|
||||
|
||||
if (cnt >= sizeof(buf))
|
||||
return -EINVAL;
|
||||
|
||||
if (copy_from_user(&buf, ubuf, cnt))
|
||||
return -EFAULT;
|
||||
|
||||
buf[cnt] = 0;
|
||||
|
||||
if (!strncmp(buf, "printf", 6) &&
|
||||
(!buf[6] || isspace(buf[6]))) {
|
||||
|
||||
call->type = TRACE_EVENT_TYPE_PRINTF;
|
||||
|
||||
/*
|
||||
* If raw enabled, the disable it and enable
|
||||
* printf type.
|
||||
*/
|
||||
if (call->raw_enabled) {
|
||||
call->raw_enabled = 0;
|
||||
call->raw_unreg();
|
||||
|
||||
call->enabled = 1;
|
||||
call->regfunc();
|
||||
}
|
||||
|
||||
} else if (!strncmp(buf, "raw", 3) &&
|
||||
(!buf[3] || isspace(buf[3]))) {
|
||||
|
||||
call->type = TRACE_EVENT_TYPE_RAW;
|
||||
|
||||
/*
|
||||
* If printf enabled, the disable it and enable
|
||||
* raw type.
|
||||
*/
|
||||
if (call->enabled) {
|
||||
call->enabled = 0;
|
||||
call->unregfunc();
|
||||
|
||||
call->raw_enabled = 1;
|
||||
call->raw_reg();
|
||||
}
|
||||
} else
|
||||
return -EINVAL;
|
||||
|
||||
*ppos += cnt;
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
event_available_types_read(struct file *filp, char __user *ubuf, size_t cnt,
|
||||
loff_t *ppos)
|
||||
{
|
||||
struct ftrace_event_call *call = filp->private_data;
|
||||
char buf[16];
|
||||
int r = 0;
|
||||
|
||||
r += sprintf(buf, "printf\n");
|
||||
|
||||
if (call->raw_init)
|
||||
r += sprintf(buf+r, "raw\n");
|
||||
|
||||
return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
|
||||
}
|
||||
|
||||
static const struct seq_operations show_event_seq_ops = {
|
||||
.start = t_start,
|
||||
.next = t_next,
|
||||
|
@ -325,6 +472,17 @@ static const struct file_operations ftrace_enable_fops = {
|
|||
.write = event_enable_write,
|
||||
};
|
||||
|
||||
static const struct file_operations ftrace_type_fops = {
|
||||
.open = tracing_open_generic,
|
||||
.read = event_type_read,
|
||||
.write = event_type_write,
|
||||
};
|
||||
|
||||
static const struct file_operations ftrace_available_types_fops = {
|
||||
.open = tracing_open_generic,
|
||||
.read = event_available_types_read,
|
||||
};
|
||||
|
||||
static struct dentry *event_trace_events_dir(void)
|
||||
{
|
||||
static struct dentry *d_tracer;
|
||||
|
@ -345,10 +503,71 @@ static struct dentry *event_trace_events_dir(void)
|
|||
return d_events;
|
||||
}
|
||||
|
||||
struct event_subsystem {
|
||||
struct list_head list;
|
||||
const char *name;
|
||||
struct dentry *entry;
|
||||
};
|
||||
|
||||
static LIST_HEAD(event_subsystems);
|
||||
|
||||
static struct dentry *
|
||||
event_subsystem_dir(const char *name, struct dentry *d_events)
|
||||
{
|
||||
struct event_subsystem *system;
|
||||
|
||||
/* First see if we did not already create this dir */
|
||||
list_for_each_entry(system, &event_subsystems, list) {
|
||||
if (strcmp(system->name, name) == 0)
|
||||
return system->entry;
|
||||
}
|
||||
|
||||
/* need to create new entry */
|
||||
system = kmalloc(sizeof(*system), GFP_KERNEL);
|
||||
if (!system) {
|
||||
pr_warning("No memory to create event subsystem %s\n",
|
||||
name);
|
||||
return d_events;
|
||||
}
|
||||
|
||||
system->entry = debugfs_create_dir(name, d_events);
|
||||
if (!system->entry) {
|
||||
pr_warning("Could not create event subsystem %s\n",
|
||||
name);
|
||||
kfree(system);
|
||||
return d_events;
|
||||
}
|
||||
|
||||
system->name = name;
|
||||
list_add(&system->list, &event_subsystems);
|
||||
|
||||
return system->entry;
|
||||
}
|
||||
|
||||
static int
|
||||
event_create_dir(struct ftrace_event_call *call, struct dentry *d_events)
|
||||
{
|
||||
struct dentry *entry;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* If the trace point header did not define TRACE_SYSTEM
|
||||
* then the system would be called "TRACE_SYSTEM".
|
||||
*/
|
||||
if (strcmp(call->system, "TRACE_SYSTEM") != 0)
|
||||
d_events = event_subsystem_dir(call->system, d_events);
|
||||
|
||||
if (call->raw_init) {
|
||||
ret = call->raw_init();
|
||||
if (ret < 0) {
|
||||
pr_warning("Could not initialize trace point"
|
||||
" events/%s\n", call->name);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* default the output to printf */
|
||||
call->type = TRACE_EVENT_TYPE_PRINTF;
|
||||
|
||||
call->dir = debugfs_create_dir(call->name, d_events);
|
||||
if (!call->dir) {
|
||||
|
@ -363,6 +582,21 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events)
|
|||
pr_warning("Could not create debugfs "
|
||||
"'%s/enable' entry\n", call->name);
|
||||
|
||||
/* Only let type be writable, if we can change it */
|
||||
entry = debugfs_create_file("type",
|
||||
call->raw_init ? 0644 : 0444,
|
||||
call->dir, call,
|
||||
&ftrace_type_fops);
|
||||
if (!entry)
|
||||
pr_warning("Could not create debugfs "
|
||||
"'%s/type' entry\n", call->name);
|
||||
|
||||
entry = debugfs_create_file("available_types", 0444, call->dir, call,
|
||||
&ftrace_available_types_fops);
|
||||
if (!entry)
|
||||
pr_warning("Could not create debugfs "
|
||||
"'%s/type' available_types\n", call->name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
#ifndef _LINUX_KERNEL_TRACE_EVENTS_H
|
||||
#define _LINUX_KERNEL_TRACE_EVENTS_H
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/ftrace.h>
|
||||
#include "trace.h"
|
||||
|
||||
struct ftrace_event_call {
|
||||
char *name;
|
||||
struct dentry *dir;
|
||||
int enabled;
|
||||
int (*regfunc)(void);
|
||||
void (*unregfunc)(void);
|
||||
};
|
||||
|
||||
|
||||
#undef TPFMT
|
||||
#define TPFMT(fmt, args...) fmt "\n", ##args
|
||||
|
||||
#undef TRACE_FORMAT
|
||||
#define TRACE_FORMAT(call, proto, args, fmt) \
|
||||
static void ftrace_event_##call(proto) \
|
||||
{ \
|
||||
event_trace_printk(_RET_IP_, "(" #call ") " fmt); \
|
||||
} \
|
||||
\
|
||||
static int ftrace_reg_event_##call(void) \
|
||||
{ \
|
||||
int ret; \
|
||||
\
|
||||
ret = register_trace_##call(ftrace_event_##call); \
|
||||
if (!ret) \
|
||||
pr_info("event trace: Could not activate trace point " \
|
||||
"probe to " #call); \
|
||||
return ret; \
|
||||
} \
|
||||
\
|
||||
static void ftrace_unreg_event_##call(void) \
|
||||
{ \
|
||||
unregister_trace_##call(ftrace_event_##call); \
|
||||
} \
|
||||
\
|
||||
static struct ftrace_event_call __used \
|
||||
__attribute__((__aligned__(4))) \
|
||||
__attribute__((section("_ftrace_events"))) event_##call = { \
|
||||
.name = #call, \
|
||||
.regfunc = ftrace_reg_event_##call, \
|
||||
.unregfunc = ftrace_unreg_event_##call, \
|
||||
}
|
||||
|
||||
void event_trace_printk(unsigned long ip, const char *fmt, ...);
|
||||
extern struct ftrace_event_call __start_ftrace_events[];
|
||||
extern struct ftrace_event_call __stop_ftrace_events[];
|
||||
|
||||
#endif /* _LINUX_KERNEL_TRACE_EVENTS_H */
|
34
kernel/trace/trace_events_stage_1.h
Normal file
34
kernel/trace/trace_events_stage_1.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Stage 1 of the trace events.
|
||||
*
|
||||
* Override the macros in <trace/trace_event_types.h> to include the following:
|
||||
*
|
||||
* struct ftrace_raw_<call> {
|
||||
* struct trace_entry ent;
|
||||
* <type> <item>;
|
||||
* [...]
|
||||
* };
|
||||
*
|
||||
* The <type> <item> is created by the TRACE_FIELD(type, item, assign)
|
||||
* macro. We simply do "type item;", and that will create the fields
|
||||
* in the structure.
|
||||
*/
|
||||
|
||||
#undef TRACE_FORMAT
|
||||
#define TRACE_FORMAT(call, proto, args, fmt)
|
||||
|
||||
#undef TRACE_EVENT_FORMAT
|
||||
#define TRACE_EVENT_FORMAT(name, proto, args, fmt, tstruct, tpfmt) \
|
||||
struct ftrace_raw_##name { \
|
||||
struct trace_entry ent; \
|
||||
tstruct \
|
||||
}; \
|
||||
static struct ftrace_event_call event_##name
|
||||
|
||||
#undef TRACE_STRUCT
|
||||
#define TRACE_STRUCT(args...) args
|
||||
|
||||
#define TRACE_FIELD(type, item, assign) \
|
||||
type item;
|
||||
|
||||
#include <trace/trace_event_types.h>
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue