Merge branch 'x86/core' into x86/mce2

This commit is contained in:
H. Peter Anvin 2009-03-03 21:05:42 -08:00
commit 2e22ea7cea
219 changed files with 10166 additions and 1235 deletions

View File

@ -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>

View File

@ -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.

View File

@ -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

View File

@ -868,8 +868,10 @@ and is between 256 and 4096 characters. It is defined in the file
icn= [HW,ISDN]
Format: <io>[,<membase>[,<icn_id>[,<icn_id2>]]]
ide= [HW] (E)IDE subsystem
Format: ide=nodma or ide=doubler
ide-core.nodma= [HW] (E)IDE subsystem
Format: =0.0 to prevent dma on hda, =0.1 hdb =1.0 hdc
.vlb_clock .pci_clock .noflush .noprobe .nowerr .cdrom
.chs .ignore_cable are additional options
See Documentation/ide/ide.txt.
idebus= [HW] (E)IDE subsystem - VLB/PCI bus speed
@ -1308,8 +1310,13 @@ and is between 256 and 4096 characters. It is defined in the file
memtest= [KNL,X86] Enable memtest
Format: <integer>
range: 0,4 : pattern number
default : 0 <disable>
Specifies the number of memtest passes to be
performed. Each pass selects another test
pattern from a given set of patterns. Memtest
fills the memory with this pattern, validates
memory contents and reserves bad memory
regions that are detected.
meye.*= [HW] Set MotionEye Camera parameters
See Documentation/video4linux/meye.txt.

View File

@ -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)

View File

@ -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,

View File

@ -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,
};

View File

@ -19,6 +19,7 @@
#include <linux/serial_8250.h>
#include <linux/ata_platform.h>
#include <linux/io.h>
#include <linux/i2c.h>
#include <asm/elf.h>
#include <asm/mach-types.h>
@ -201,8 +202,13 @@ static struct platform_device *devs[] __initdata = {
&pata_device,
};
static struct i2c_board_info i2c_rtc = {
I2C_BOARD_INFO("pcf8583", 0x50)
};
static int __init rpc_init(void)
{
i2c_register_board_info(0, &i2c_rtc, 1);
return platform_add_devices(devs, ARRAY_SIZE(devs));
}

View File

@ -638,6 +638,17 @@ config DMAR
and include PCI device scope covered by these DMA
remapping devices.
config DMAR_DEFAULT_ON
def_bool y
prompt "Enable DMA Remapping Devices by default"
depends on DMAR
help
Selecting this option will enable a DMAR device at boot time if
one is found. If this option is not selected, DMAR support can
be enabled by passing intel_iommu=on to the kernel. It is
recommended you say N here while the DMAR code remains
experimental.
endmenu
endif

View File

@ -507,7 +507,7 @@ static int iosapic_find_sharable_irq(unsigned long trigger, unsigned long pol)
if (trigger == IOSAPIC_EDGE)
return -EINVAL;
for (i = 0; i <= NR_IRQS; i++) {
for (i = 0; i < NR_IRQS; i++) {
info = &iosapic_intr_info[i];
if (info->trigger == trigger && info->polarity == pol &&
(info->dmode == IOSAPIC_FIXED ||

View File

@ -2149,7 +2149,7 @@ unw_remove_unwind_table (void *handle)
/* next, remove hash table entries for this table */
for (index = 0; index <= UNW_HASH_SIZE; ++index) {
for (index = 0; index < UNW_HASH_SIZE; ++index) {
tmp = unw.cache + unw.hash[index];
if (unw.hash[index] >= UNW_CACHE_SIZE
|| tmp->ip < table->start || tmp->ip >= table->end)

View File

@ -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.

View File

@ -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;

View File

@ -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)

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -367,27 +367,24 @@ static int emulate_multiple(struct pt_regs *regs, unsigned char __user *addr,
static int emulate_fp_pair(unsigned char __user *addr, unsigned int reg,
unsigned int flags)
{
char *ptr = (char *) &current->thread.TS_FPR(reg);
int i, ret;
char *ptr0 = (char *) &current->thread.TS_FPR(reg);
char *ptr1 = (char *) &current->thread.TS_FPR(reg+1);
int i, ret, sw = 0;
if (!(flags & F))
return 0;
if (reg & 1)
return 0; /* invalid form: FRS/FRT must be even */
if (!(flags & SW)) {
/* not byte-swapped - easy */
if (!(flags & ST))
ret = __copy_from_user(ptr, addr, 16);
else
ret = __copy_to_user(addr, ptr, 16);
} else {
/* each FPR value is byte-swapped separately */
ret = 0;
for (i = 0; i < 16; ++i) {
if (!(flags & ST))
ret |= __get_user(ptr[i^7], addr + i);
else
ret |= __put_user(ptr[i^7], addr + i);
if (flags & SW)
sw = 7;
ret = 0;
for (i = 0; i < 8; ++i) {
if (!(flags & ST)) {
ret |= __get_user(ptr0[i^sw], addr + i);
ret |= __get_user(ptr1[i^sw], addr + i + 8);
} else {
ret |= __put_user(ptr0[i^sw], addr + i);
ret |= __put_user(ptr1[i^sw], addr + i + 8);
}
}
if (ret)

View File

@ -62,18 +62,19 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD)
72: std r8,8(r3)
beq+ 3f
addi r3,r3,16
23: ld r9,8(r4)
.Ldo_tail:
bf cr7*4+1,1f
rotldi r9,r9,32
23: lwz r9,8(r4)
addi r4,r4,4
73: stw r9,0(r3)
addi r3,r3,4
1: bf cr7*4+2,2f
rotldi r9,r9,16
44: lhz r9,8(r4)
addi r4,r4,2
74: sth r9,0(r3)
addi r3,r3,2
2: bf cr7*4+3,3f
rotldi r9,r9,8
45: lbz r9,8(r4)
75: stb r9,0(r3)
3: li r3,0
blr
@ -141,11 +142,24 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD)
6: cmpwi cr1,r5,8
addi r3,r3,32
sld r9,r9,r10
ble cr1,.Ldo_tail
ble cr1,7f
34: ld r0,8(r4)
srd r7,r0,r11
or r9,r7,r9
b .Ldo_tail
7:
bf cr7*4+1,1f
rotldi r9,r9,32
94: stw r9,0(r3)
addi r3,r3,4
1: bf cr7*4+2,2f
rotldi r9,r9,16
95: sth r9,0(r3)
addi r3,r3,2
2: bf cr7*4+3,3f
rotldi r9,r9,8
96: stb r9,0(r3)
3: li r3,0
blr
.Ldst_unaligned:
PPC_MTOCRF 0x01,r6 /* put #bytes to 8B bdry into cr7 */
@ -218,7 +232,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD)
121:
132:
addi r3,r3,8
123:
134:
135:
138:
@ -226,6 +239,9 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD)
140:
141:
142:
123:
144:
145:
/*
* here we have had a fault on a load and r3 points to the first
@ -309,6 +325,9 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD)
187:
188:
189:
194:
195:
196:
1:
ld r6,-24(r1)
ld r5,-8(r1)
@ -329,7 +348,9 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD)
.llong 72b,172b
.llong 23b,123b
.llong 73b,173b
.llong 44b,144b
.llong 74b,174b
.llong 45b,145b
.llong 75b,175b
.llong 24b,124b
.llong 25b,125b
@ -347,6 +368,9 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD)
.llong 79b,179b
.llong 80b,180b
.llong 34b,134b
.llong 94b,194b
.llong 95b,195b
.llong 96b,196b
.llong 35b,135b
.llong 81b,181b
.llong 36b,136b

View File

@ -53,18 +53,19 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD)
3: std r8,8(r3)
beq 3f
addi r3,r3,16
ld r9,8(r4)
.Ldo_tail:
bf cr7*4+1,1f
rotldi r9,r9,32
lwz r9,8(r4)
addi r4,r4,4
stw r9,0(r3)
addi r3,r3,4
1: bf cr7*4+2,2f
rotldi r9,r9,16
lhz r9,8(r4)
addi r4,r4,2
sth r9,0(r3)
addi r3,r3,2
2: bf cr7*4+3,3f
rotldi r9,r9,8
lbz r9,8(r4)
stb r9,0(r3)
3: ld r3,48(r1) /* return dest pointer */
blr
@ -133,11 +134,24 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD)
cmpwi cr1,r5,8
addi r3,r3,32
sld r9,r9,r10
ble cr1,.Ldo_tail
ble cr1,6f
ld r0,8(r4)
srd r7,r0,r11
or r9,r7,r9
b .Ldo_tail
6:
bf cr7*4+1,1f
rotldi r9,r9,32
stw r9,0(r3)
addi r3,r3,4
1: bf cr7*4+2,2f
rotldi r9,r9,16
sth r9,0(r3)
addi r3,r3,2
2: bf cr7*4+3,3f
rotldi r9,r9,8
stb r9,0(r3)
3: ld r3,48(r1) /* return dest pointer */
blr
.Ldst_unaligned:
PPC_MTOCRF 0x01,r6 # put #bytes to 8B bdry into cr7

View File

@ -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",

View File

@ -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[] = {

View File

@ -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)

View File

@ -306,6 +306,7 @@ static int jbusmc_print_dimm(int syndrome_code,
buf[1] = '?';
buf[2] = '?';
buf[3] = '\0';
return 0;
}
p = dp->controller;
prop = &p->layout;

View File

@ -1827,7 +1827,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

View File

@ -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);

View File

@ -15,4 +15,7 @@ extern int reserve_memtype(u64 start, u64 end,
unsigned long req_type, unsigned long *ret_type);
extern int free_memtype(u64 start, u64 end);
extern int kernel_map_sync_memtype(u64 base, unsigned long size,
unsigned long flag);
#endif /* _ASM_X86_PAT_H */

View File

@ -157,7 +157,7 @@ __copy_from_user(void *to, const void __user *from, unsigned long n)
}
static __always_inline unsigned long __copy_from_user_nocache(void *to,
const void __user *from, unsigned long n)
const void __user *from, unsigned long n, unsigned long total)
{
might_fault();
if (__builtin_constant_p(n)) {
@ -180,7 +180,7 @@ static __always_inline unsigned long __copy_from_user_nocache(void *to,
static __always_inline unsigned long
__copy_from_user_inatomic_nocache(void *to, const void __user *from,
unsigned long n)
unsigned long n, unsigned long total)
{
return __copy_from_user_ll_nocache_nozero(to, from, n);
}

View File

@ -189,7 +189,7 @@ extern long __copy_user_nocache(void *dst, const void __user *src,
unsigned size, int zerorest);
static inline int __copy_from_user_nocache(void *dst, const void __user *src,
unsigned size)
unsigned size, unsigned long total)
{
might_sleep();
/*
@ -198,17 +198,16 @@ static inline int __copy_from_user_nocache(void *dst, const void __user *src,
* non-temporal stores here. Smaller writes get handled
* via regular __copy_from_user():
*/
if (likely(size >= PAGE_SIZE))
if (likely(total >= PAGE_SIZE))
return __copy_user_nocache(dst, src, size, 1);
else
return __copy_from_user(dst, src, size);
}
static inline int __copy_from_user_inatomic_nocache(void *dst,
const void __user *src,
unsigned size)
const void __user *src, unsigned size, unsigned total)
{
if (likely(size >= PAGE_SIZE))
if (likely(total >= PAGE_SIZE))
return __copy_user_nocache(dst, src, size, 0);
else
return __copy_from_user_inatomic(dst, src, size);

View File

@ -503,12 +503,12 @@ void *text_poke_early(void *addr, const void *opcode, size_t len)
*/
void *__kprobes text_poke(void *addr, const void *opcode, size_t len)
{
unsigned long flags;
char *vaddr;
int nr_pages = 2;
struct page *pages[2];
int i;
might_sleep();
if (!core_kernel_text((unsigned long)addr)) {
pages[0] = vmalloc_to_page(addr);
pages[1] = vmalloc_to_page(addr + PAGE_SIZE);
@ -522,9 +522,9 @@ void *__kprobes text_poke(void *addr, const void *opcode, size_t len)
nr_pages = 1;
vaddr = vmap(pages, nr_pages, VM_MAP, PAGE_KERNEL);
BUG_ON(!vaddr);
local_irq_save(flags);
local_irq_disable();
memcpy(&vaddr[(unsigned long)addr & ~PAGE_MASK], opcode, len);
local_irq_restore(flags);
local_irq_enable();
vunmap(vaddr);
sync_core();
/* Could also do a CLFLUSH here to speed up CPU recovery; but

View File

@ -48,7 +48,7 @@
#include <linux/gfp.h>
#include <linux/smp.h>
static inline unsigned summit_get_apic_id(unsigned long x)
static unsigned summit_get_apic_id(unsigned long x)
{
return (x >> 24) & 0xFF;
}
@ -58,7 +58,7 @@ static inline void summit_send_IPI_mask(const cpumask_t *mask, int vector)
default_send_IPI_mask_sequence_logical(mask, vector);
}
static inline void summit_send_IPI_allbutself(int vector)
static void summit_send_IPI_allbutself(int vector)
{
cpumask_t mask = cpu_online_map;
cpu_clear(smp_processor_id(), mask);
@ -67,7 +67,7 @@ static inline void summit_send_IPI_allbutself(int vector)
summit_send_IPI_mask(&mask, vector);
}
static inline void summit_send_IPI_all(int vector)
static void summit_send_IPI_all(int vector)
{
summit_send_IPI_mask(&cpu_online_map, vector);
}
@ -82,8 +82,8 @@ extern void setup_summit(void);
#define setup_summit() {}
#endif
static inline int
summit_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid)
static int summit_mps_oem_check(struct mpc_table *mpc, char *oem,
char *productid)
{
if (!strncmp(oem, "IBM ENSW", 8) &&
(!strncmp(productid, "VIGIL SMP", 9)
@ -98,7 +98,7 @@ summit_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid)
}
/* Hook from generic ACPI tables.c */
static inline int summit_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
static int summit_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
{
if (!strncmp(oem_id, "IBM", 3) &&
(!strncmp(oem_table_id, "SERVIGIL", 8)
@ -186,7 +186,7 @@ static inline int is_WPEG(struct rio_detail *rio){
#define SUMMIT_APIC_DFR_VALUE (APIC_DFR_CLUSTER)
static inline const cpumask_t *summit_target_cpus(void)
static const cpumask_t *summit_target_cpus(void)
{
/* CPU_MASK_ALL (0xff) has undefined behaviour with
* dest_LowestPrio mode logical clustered apic interrupt routing
@ -195,19 +195,18 @@ static inline const cpumask_t *summit_target_cpus(void)
return &cpumask_of_cpu(0);
}
static inline unsigned long
summit_check_apicid_used(physid_mask_t bitmap, int apicid)
static unsigned long summit_check_apicid_used(physid_mask_t bitmap, int apicid)
{
return 0;
}
/* we don't use the phys_cpu_present_map to indicate apicid presence */
static inline unsigned long summit_check_apicid_present(int bit)
static unsigned long summit_check_apicid_present(int bit)
{
return 1;
}
static inline void summit_init_apic_ldr(void)
static void summit_init_apic_ldr(void)
{
unsigned long val, id;
int count = 0;
@ -234,18 +233,18 @@ static inline void summit_init_apic_ldr(void)
apic_write(APIC_LDR, val);
}
static inline int summit_apic_id_registered(void)
static int summit_apic_id_registered(void)
{
return 1;
}
static inline void summit_setup_apic_routing(void)
static void summit_setup_apic_routing(void)
{
printk("Enabling APIC mode: Summit. Using %d I/O APICs\n",
nr_ioapics);
}
static inline int summit_apicid_to_node(int logical_apicid)
static int summit_apicid_to_node(int logical_apicid)
{
#ifdef CONFIG_SMP
return apicid_2_node[hard_smp_processor_id()];
@ -266,7 +265,7 @@ static inline int summit_cpu_to_logical_apicid(int cpu)
#endif
}
static inline int summit_cpu_present_to_apicid(int mps_cpu)
static int summit_cpu_present_to_apicid(int mps_cpu)
{
if (mps_cpu < nr_cpu_ids)
return (int)per_cpu(x86_bios_cpu_apicid, mps_cpu);
@ -274,28 +273,23 @@ static inline int summit_cpu_present_to_apicid(int mps_cpu)
return BAD_APICID;
}
static inline physid_mask_t
summit_ioapic_phys_id_map(physid_mask_t phys_id_map)
static physid_mask_t summit_ioapic_phys_id_map(physid_mask_t phys_id_map)
{
/* For clustered we don't have a good way to do this yet - hack */
return physids_promote(0x0F);
}
static inline physid_mask_t summit_apicid_to_cpu_present(int apicid)
static physid_mask_t summit_apicid_to_cpu_present(int apicid)
{
return physid_mask_of_physid(0);
}
static inline void summit_setup_portio_remap(void)
{
}
static inline int summit_check_phys_apicid_present(int boot_cpu_physical_apicid)
static int summit_check_phys_apicid_present(int boot_cpu_physical_apicid)
{
return 1;
}
static inline unsigned int summit_cpu_mask_to_apicid(const cpumask_t *cpumask)
static unsigned int summit_cpu_mask_to_apicid(const cpumask_t *cpumask)
{
int cpus_found = 0;
int num_bits_set;
@ -303,12 +297,10 @@ static inline unsigned int summit_cpu_mask_to_apicid(const cpumask_t *cpumask)
int cpu;
num_bits_set = cpus_weight(*cpumask);
/* Return id to all */
if (num_bits_set >= nr_cpu_ids)
return 0xFF;
return BAD_APICID;
/*
* The cpus in the mask must all be on the apic cluster. If are not
* on the same apicid cluster return default value of target_cpus():
* The cpus in the mask must all be on the apic cluster.
*/
cpu = first_cpu(*cpumask);
apicid = summit_cpu_to_logical_apicid(cpu);
@ -318,9 +310,9 @@ static inline unsigned int summit_cpu_mask_to_apicid(const cpumask_t *cpumask)
int new_apicid = summit_cpu_to_logical_apicid(cpu);
if (APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) {
printk ("%s: Not a valid mask!\n", __func__);
printk("%s: Not a valid mask!\n", __func__);
return 0xFF;
return BAD_APICID;
}
apicid = apicid | new_apicid;
cpus_found++;
@ -330,8 +322,7 @@ static inline unsigned int summit_cpu_mask_to_apicid(const cpumask_t *cpumask)
return apicid;
}
static inline unsigned int
summit_cpu_mask_to_apicid_and(const struct cpumask *inmask,
static unsigned int summit_cpu_mask_to_apicid_and(const struct cpumask *inmask,
const struct cpumask *andmask)
{
int apicid = summit_cpu_to_logical_apicid(0);
@ -356,7 +347,7 @@ summit_cpu_mask_to_apicid_and(const struct cpumask *inmask,
*
* See Intel's IA-32 SW Dev's Manual Vol2 under CPUID.
*/
static inline int summit_phys_pkg_id(int cpuid_apic, int index_msb)
static int summit_phys_pkg_id(int cpuid_apic, int index_msb)
{
return hard_smp_processor_id() >> index_msb;
}

View File

@ -858,6 +858,9 @@ void __init reserve_early_overlap_ok(u64 start, u64 end, char *name)
*/
void __init reserve_early(u64 start, u64 end, char *name)
{
if (start >= end)
return;
drop_overlaps_that_are_ok(start, end);
__reserve_early(start, end, name, 0);
}

View File

@ -20,6 +20,17 @@
#include <asm/pat.h>
#include <linux/module.h>
int is_io_mapping_possible(resource_size_t base, unsigned long size)
{
#ifndef CONFIG_X86_PAE
/* There is no way to map greater than 1 << 32 address without PAE */
if (base + size > 0x100000000ULL)
return 0;
#endif
return 1;
}
EXPORT_SYMBOL_GPL(is_io_mapping_possible);
/* Map 'pfn' using fixed map 'type' and protections 'prot'
*/
void *

View File

@ -9,44 +9,44 @@
#include <asm/e820.h>
static void __init memtest(unsigned long start_phys, unsigned long size,
unsigned pattern)
static u64 patterns[] __initdata = {
0,
0xffffffffffffffffULL,
0x5555555555555555ULL,
0xaaaaaaaaaaaaaaaaULL,
0x1111111111111111ULL,
0x2222222222222222ULL,
0x4444444444444444ULL,
0x8888888888888888ULL,
0x3333333333333333ULL,
0x6666666666666666ULL,
0x9999999999999999ULL,
0xccccccccccccccccULL,
0x7777777777777777ULL,
0xbbbbbbbbbbbbbbbbULL,
0xddddddddddddddddULL,
0xeeeeeeeeeeeeeeeeULL,
0x7a6c7258554e494cULL, /* yeah ;-) */
};
static void __init reserve_bad_mem(u64 pattern, u64 start_bad, u64 end_bad)
{
unsigned long i;
unsigned long *start;
unsigned long start_bad;
unsigned long last_bad;
unsigned long val;
unsigned long start_phys_aligned;
unsigned long count;
unsigned long incr;
printk(KERN_INFO " %016llx bad mem addr %010llx - %010llx reserved\n",
(unsigned long long) pattern,
(unsigned long long) start_bad,
(unsigned long long) end_bad);
reserve_early(start_bad, end_bad, "BAD RAM");
}
switch (pattern) {
case 0:
val = 0UL;
break;
case 1:
val = -1UL;
break;
case 2:
#ifdef CONFIG_X86_64
val = 0x5555555555555555UL;
#else
val = 0x55555555UL;
#endif
break;
case 3:
#ifdef CONFIG_X86_64
val = 0xaaaaaaaaaaaaaaaaUL;
#else
val = 0xaaaaaaaaUL;
#endif
break;
default:
return;
}
static void __init memtest(u64 pattern, u64 start_phys, u64 size)
{
u64 i, count;
u64 *start;
u64 start_bad, last_bad;
u64 start_phys_aligned;
size_t incr;
incr = sizeof(unsigned long);
incr = sizeof(pattern);
start_phys_aligned = ALIGN(start_phys, incr);
count = (size - (start_phys_aligned - start_phys))/incr;
start = __va(start_phys_aligned);
@ -54,25 +54,42 @@ static void __init memtest(unsigned long start_phys, unsigned long size,
last_bad = 0;
for (i = 0; i < count; i++)
start[i] = val;
start[i] = pattern;
for (i = 0; i < count; i++, start++, start_phys_aligned += incr) {
if (*start != val) {
if (start_phys_aligned == last_bad + incr) {
last_bad += incr;
} else {
if (start_bad) {
printk(KERN_CONT "\n %016lx bad mem addr %010lx - %010lx reserved",
val, start_bad, last_bad + incr);
reserve_early(start_bad, last_bad + incr, "BAD RAM");
}
start_bad = last_bad = start_phys_aligned;
}
if (*start == pattern)
continue;
if (start_phys_aligned == last_bad + incr) {
last_bad += incr;
continue;
}
if (start_bad)
reserve_bad_mem(pattern, start_bad, last_bad + incr);
start_bad = last_bad = start_phys_aligned;
}
if (start_bad) {
printk(KERN_CONT "\n %016lx bad mem addr %010lx - %010lx reserved",
val, start_bad, last_bad + incr);
reserve_early(start_bad, last_bad + incr, "BAD RAM");
if (start_bad)
reserve_bad_mem(pattern, start_bad, last_bad + incr);
}
static void __init do_one_pass(u64 pattern, u64 start, u64 end)
{
u64 size = 0;
while (start < end) {
start = find_e820_area_size(start, &size, 1);
/* done ? */
if (start >= end)
break;
if (start + size > end)
size = end - start;
printk(KERN_INFO " %010llx - %010llx pattern %016llx\n",
(unsigned long long) start,
(unsigned long long) start + size,
(unsigned long long) cpu_to_be64(pattern));
memtest(pattern, start, size);
start += size;
}
}
@ -90,33 +107,22 @@ early_param("memtest", parse_memtest);
void __init early_memtest(unsigned long start, unsigned long end)
{
u64 t_start, t_size;
unsigned pattern;
unsigned int i;
unsigned int idx = 0;
if (!memtest_pattern)
return;
printk(KERN_INFO "early_memtest: pattern num %d", memtest_pattern);
for (pattern = 0; pattern < memtest_pattern; pattern++) {
t_start = start;
t_size = 0;
while (t_start < end) {
t_start = find_e820_area_size(t_start, &t_size, 1);
/* done ? */
if (t_start >= end)
break;
if (t_start + t_size > end)
t_size = end - t_start;
printk(KERN_CONT "\n %010llx - %010llx pattern %d",
(unsigned long long)t_start,
(unsigned long long)t_start + t_size, pattern);
memtest(t_start, t_size, pattern);
t_start += t_size;
}
printk(KERN_INFO "early_memtest: # of tests: %d\n", memtest_pattern);
for (i = 0; i < memtest_pattern; i++) {
idx = i % ARRAY_SIZE(patterns);
do_one_pass(patterns[idx], start, end);
}
if (idx > 0) {
printk(KERN_INFO "early_memtest: wipe out "
"test pattern from memory\n");
/* additional test with pattern 0 will do this */
do_one_pass(0, start, end);
}
printk(KERN_CONT "\n");
}

View File

@ -11,6 +11,7 @@
#include <linux/bootmem.h>
#include <linux/debugfs.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/gfp.h>
#include <linux/mm.h>
#include <linux/fs.h>
@ -633,6 +634,33 @@ void unmap_devmem(unsigned long pfn, unsigned long size, pgprot_t vma_prot)
free_memtype(addr, addr + size);
}
/*
* Change the memory type for the physial address range in kernel identity
* mapping space if that range is a part of identity map.
*/
int kernel_map_sync_memtype(u64 base, unsigned long size, unsigned long flags)
{
unsigned long id_sz;
if (!pat_enabled || base >= __pa(high_memory))
return 0;
id_sz = (__pa(high_memory) < base + size) ?
__pa(high_memory) - base :
size;
if (ioremap_change_attr((unsigned long)__va(base), id_sz, flags) < 0) {
printk(KERN_INFO
"%s:%d ioremap_change_attr failed %s "
"for %Lx-%Lx\n",
current->comm, current->pid,
cattr_name(flags),
base, (unsigned long long)(base + size));
return -EINVAL;
}
return 0;
}
/*
* Internal interface to reserve a range of physical memory with prot.
* Reserved non RAM regions only and after successful reserve_memtype,
@ -642,7 +670,7 @@ static int reserve_pfn_range(u64 paddr, unsigned long size, pgprot_t *vma_prot,
int strict_prot)
{
int is_ram = 0;
int id_sz, ret;
int ret;
unsigned long flags;
unsigned long want_flags = (pgprot_val(*vma_prot) & _PAGE_CACHE_MASK);
@ -679,23 +707,8 @@ static int reserve_pfn_range(u64 paddr, unsigned long size, pgprot_t *vma_prot,
flags);
}
/* Need to keep identity mapping in sync */
if (paddr >= __pa(high_memory))
return 0;
id_sz = (__pa(high_memory) < paddr + size) ?
__pa(high_memory) - paddr :
size;
if (ioremap_change_attr((unsigned long)__va(paddr), id_sz, flags) < 0) {
if (kernel_map_sync_memtype(paddr, size, flags) < 0) {
free_memtype(paddr, paddr + size);
printk(KERN_ERR
"%s:%d reserve_pfn_range ioremap_change_attr failed %s "
"for %Lx-%Lx\n",
current->comm, current->pid,
cattr_name(flags),
(unsigned long long)paddr,
(unsigned long long)(paddr + size));
return -EINVAL;
}
return 0;
@ -877,6 +890,7 @@ pgprot_t pgprot_writecombine(pgprot_t prot)
else
return pgprot_noncached(prot);
}
EXPORT_SYMBOL_GPL(pgprot_writecombine);
#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_X86_PAT)

View File

@ -940,6 +940,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);

View File

@ -38,72 +38,84 @@ void blk_recalc_rq_sectors(struct request *rq, int nsect)
}
}
void blk_recalc_rq_segments(struct request *rq)
static unsigned int __blk_recalc_rq_segments(struct request_queue *q,
struct bio *bio,
unsigned int *seg_size_ptr)
{
int nr_phys_segs;
unsigned int phys_size;
struct bio_vec *bv, *bvprv = NULL;
int seg_size;
int cluster;
struct req_iterator iter;
int high, highprv = 1;
struct request_queue *q = rq->q;
int cluster, i, high, highprv = 1;
unsigned int seg_size, nr_phys_segs;
struct bio *fbio;
if (!rq->bio)
return;
if (!bio)
return 0;
fbio = bio;
cluster = test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags);
seg_size = 0;
phys_size = nr_phys_segs = 0;
rq_for_each_segment(bv, rq, iter) {
/*
* the trick here is making sure that a high page is never
* considered part of another segment, since that might
* change with the bounce page.
*/
high = page_to_pfn(bv->bv_page) > q->bounce_pfn;
if (high || highprv)
goto new_segment;
if (cluster) {
if (seg_size + bv->bv_len > q->max_segment_size)
goto new_segment;
if (!BIOVEC_PHYS_MERGEABLE(bvprv, bv))
goto new_segment;
if (!BIOVEC_SEG_BOUNDARY(q, bvprv, bv))
for_each_bio(bio) {
bio_for_each_segment(bv, bio, i) {
/*
* the trick here is making sure that a high page is
* never considered part of another segment, since that
* might change with the bounce page.
*/
high = page_to_pfn(bv->bv_page) > q->bounce_pfn;
if (high || highprv)
goto new_segment;
if (cluster) {
if (seg_size + bv->bv_len > q->max_segment_size)
goto new_segment;
if (!BIOVEC_PHYS_MERGEABLE(bvprv, bv))
goto new_segment;
if (!BIOVEC_SEG_BOUNDARY(q, bvprv, bv))
goto new_segment;
seg_size += bv->bv_len;
bvprv = bv;
continue;
}
seg_size += bv->bv_len;
bvprv = bv;
continue;
}
new_segment:
if (nr_phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size)
rq->bio->bi_seg_front_size = seg_size;
if (nr_phys_segs == 1 && seg_size >
fbio->bi_seg_front_size)
fbio->bi_seg_front_size = seg_size;
nr_phys_segs++;
bvprv = bv;
seg_size = bv->bv_len;
highprv = high;
nr_phys_segs++;
bvprv = bv;
seg_size = bv->bv_len;
highprv = high;
}
}
if (nr_phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size)
if (seg_size_ptr)
*seg_size_ptr = seg_size;
return nr_phys_segs;
}
void blk_recalc_rq_segments(struct request *rq)
{
unsigned int seg_size = 0, phys_segs;
phys_segs = __blk_recalc_rq_segments(rq->q, rq->bio, &seg_size);
if (phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size)
rq->bio->bi_seg_front_size = seg_size;
if (seg_size > rq->biotail->bi_seg_back_size)
rq->biotail->bi_seg_back_size = seg_size;
rq->nr_phys_segments = nr_phys_segs;
rq->nr_phys_segments = phys_segs;
}
void blk_recount_segments(struct request_queue *q, struct bio *bio)
{
struct request rq;
struct bio *nxt = bio->bi_next;
rq.q = q;
rq.bio = rq.biotail = bio;
bio->bi_next = NULL;
blk_recalc_rq_segments(&rq);
bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio, NULL);
bio->bi_next = nxt;
bio->bi_phys_segments = rq.nr_phys_segments;
bio->bi_flags |= (1 << BIO_SEG_VALID);
}
EXPORT_SYMBOL(blk_recount_segments);

View File

@ -256,6 +256,22 @@ void blkdev_show(struct seq_file *seqf, off_t offset)
}
#endif /* CONFIG_PROC_FS */
/**
* register_blkdev - register a new block device
*
* @major: the requested major device number [1..255]. If @major=0, try to
* allocate any unused major number.
* @name: the name of the new block device as a zero terminated string
*
* The @name must be unique within the system.
*
* The return value depends on the @major input parameter.
* - if a major device number was requested in range [1..255] then the
* function returns zero on success, or a negative error code
* - if any unused major number was requested with @major=0 parameter
* then the return value is the allocated major number in range
* [1..255] or a negative error code otherwise
*/
int register_blkdev(unsigned int major, const char *name)
{
struct blk_major_name **n, *p;

View File

@ -214,7 +214,7 @@ static void crypto_ahash_show(struct seq_file *m, struct crypto_alg *alg)
seq_printf(m, "async : %s\n", alg->cra_flags & CRYPTO_ALG_ASYNC ?
"yes" : "no");
seq_printf(m, "blocksize : %u\n", alg->cra_blocksize);
seq_printf(m, "digestsize : %u\n", alg->cra_hash.digestsize);
seq_printf(m, "digestsize : %u\n", alg->cra_ahash.digestsize);
}
const struct crypto_type crypto_ahash_type = {

View File

@ -24,7 +24,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_amd"
#define DRV_VERSION "0.3.11"
#define DRV_VERSION "0.4.1"
/**
* timing_setup - shared timing computation and load
@ -145,6 +145,13 @@ static int amd_pre_reset(struct ata_link *link, unsigned long deadline)
return ata_sff_prereset(link, deadline);
}
/**
* amd_cable_detect - report cable type
* @ap: port
*
* AMD controller/BIOS setups record the cable type in word 0x42
*/
static int amd_cable_detect(struct ata_port *ap)
{
static const u32 bitmask[2] = {0x03, 0x0C};
@ -157,6 +164,40 @@ static int amd_cable_detect(struct ata_port *ap)
return ATA_CBL_PATA40;
}
/**
* amd_fifo_setup - set the PIO FIFO for ATA/ATAPI
* @ap: ATA interface
* @adev: ATA device
*
* Set the PCI fifo for this device according to the devices present
* on the bus at this point in time. We need to turn the post write buffer
* off for ATAPI devices as we may need to issue a word sized write to the
* device as the final I/O
*/
static void amd_fifo_setup(struct ata_port *ap)
{
struct ata_device *adev;
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
static const u8 fifobit[2] = { 0xC0, 0x30};
u8 fifo = fifobit[ap->port_no];
u8 r;
ata_for_each_dev(adev, &ap->link, ENABLED) {
if (adev->class == ATA_DEV_ATAPI)
fifo = 0;
}
if (pdev->device == PCI_DEVICE_ID_AMD_VIPER_7411) /* FIFO is broken */
fifo = 0;
/* On the later chips the read prefetch bits become no-op bits */
pci_read_config_byte(pdev, 0x41, &r);
r &= ~fifobit[ap->port_no];
r |= fifo;
pci_write_config_byte(pdev, 0x41, r);
}
/**
* amd33_set_piomode - set initial PIO mode data
* @ap: ATA interface
@ -167,21 +208,25 @@ static int amd_cable_detect(struct ata_port *ap)
static void amd33_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
amd_fifo_setup(ap);
timing_setup(ap, adev, 0x40, adev->pio_mode, 1);
}
static void amd66_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
amd_fifo_setup(ap);
timing_setup(ap, adev, 0x40, adev->pio_mode, 2);
}
static void amd100_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
amd_fifo_setup(ap);
timing_setup(ap, adev, 0x40, adev->pio_mode, 3);
}
static void amd133_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
amd_fifo_setup(ap);
timing_setup(ap, adev, 0x40, adev->pio_mode, 4);
}
@ -397,6 +442,16 @@ static struct ata_port_operations nv133_port_ops = {
.set_dmamode = nv133_set_dmamode,
};
static void amd_clear_fifo(struct pci_dev *pdev)
{
u8 fifo;
/* Disable the FIFO, the FIFO logic will re-enable it as
appropriate */
pci_read_config_byte(pdev, 0x41, &fifo);
fifo &= 0x0F;
pci_write_config_byte(pdev, 0x41, fifo);
}
static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
static const struct ata_port_info info[10] = {
@ -503,14 +558,8 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
if (type < 3)
ata_pci_bmdma_clear_simplex(pdev);
/* Check for AMD7411 */
if (type == 3)
/* FIFO is broken */
pci_write_config_byte(pdev, 0x41, fifo & 0x0F);
else
pci_write_config_byte(pdev, 0x41, fifo | 0xF0);
if (pdev->vendor == PCI_VENDOR_ID_AMD)
amd_clear_fifo(pdev);
/* Cable detection on Nvidia chips doesn't work too well,
* cache BIOS programmed UDMA mode.
*/
@ -536,18 +585,11 @@ static int amd_reinit_one(struct pci_dev *pdev)
return rc;
if (pdev->vendor == PCI_VENDOR_ID_AMD) {
u8 fifo;
pci_read_config_byte(pdev, 0x41, &fifo);
if (pdev->device == PCI_DEVICE_ID_AMD_VIPER_7411)
/* FIFO is broken */
pci_write_config_byte(pdev, 0x41, fifo & 0x0F);
else
pci_write_config_byte(pdev, 0x41, fifo | 0xF0);
amd_clear_fifo(pdev);
if (pdev->device == PCI_DEVICE_ID_AMD_VIPER_7409 ||
pdev->device == PCI_DEVICE_ID_AMD_COBRA_7401)
ata_pci_bmdma_clear_simplex(pdev);
}
ata_host_resume(host);
return 0;
}

View File

@ -557,6 +557,9 @@ static unsigned int it821x_read_id(struct ata_device *adev,
id[83] |= 0x4400; /* Word 83 is valid and LBA48 */
id[86] |= 0x0400; /* LBA48 on */
id[ATA_ID_MAJOR_VER] |= 0x1F;
/* Clear the serial number because it's different each boot
which breaks validation on resume */
memset(&id[ATA_ID_SERNO], 0x20, ATA_ID_SERNO_LEN);
}
return err_mask;
}

View File

@ -283,9 +283,10 @@ static void pdc20230_set_piomode(struct ata_port *ap, struct ata_device *adev)
static unsigned int pdc_data_xfer_vlb(struct ata_device *dev,
unsigned char *buf, unsigned int buflen, int rw)
{
if (ata_id_has_dword_io(dev->id)) {
int slop = buflen & 3;
/* 32bit I/O capable *and* we need to write a whole number of dwords */
if (ata_id_has_dword_io(dev->id) && (slop == 0 || slop == 3)) {
struct ata_port *ap = dev->link->ap;
int slop = buflen & 3;
unsigned long flags;
local_irq_save(flags);
@ -735,7 +736,7 @@ static unsigned int vlb32_data_xfer(struct ata_device *adev, unsigned char *buf,
struct ata_port *ap = adev->link->ap;
int slop = buflen & 3;
if (ata_id_has_dword_io(adev->id)) {
if (ata_id_has_dword_io(adev->id) && (slop == 0 || slop == 3)) {
if (rw == WRITE)
iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
else

View File

@ -3114,19 +3114,17 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx)
writelfl(0, hc_mmio + HC_IRQ_CAUSE_OFS);
}
if (!IS_SOC(hpriv)) {
/* Clear any currently outstanding host interrupt conditions */
writelfl(0, mmio + hpriv->irq_cause_ofs);
/* Clear any currently outstanding host interrupt conditions */
writelfl(0, mmio + hpriv->irq_cause_ofs);
/* and unmask interrupt generation for host regs */
writelfl(hpriv->unmask_all_irqs, mmio + hpriv->irq_mask_ofs);
/* and unmask interrupt generation for host regs */
writelfl(hpriv->unmask_all_irqs, mmio + hpriv->irq_mask_ofs);
/*
* enable only global host interrupts for now.
* The per-port interrupts get done later as ports are set up.
*/
mv_set_main_irq_mask(host, 0, PCI_ERR);
}
/*
* enable only global host interrupts for now.
* The per-port interrupts get done later as ports are set up.
*/
mv_set_main_irq_mask(host, 0, PCI_ERR);
done:
return rc;
}

View File

@ -901,7 +901,7 @@ static int __devinit eeprom_read(struct lanai_dev *lanai)
clock_l(); udelay(5);
for (i = 128; i != 0; i >>= 1) { /* write command out */
tmp = (lanai->conf1 & ~CONFIG1_PROMDATA) |
(data & i) ? CONFIG1_PROMDATA : 0;
((data & i) ? CONFIG1_PROMDATA : 0);
if (lanai->conf1 != tmp) {
set_config1(tmp);
udelay(5); /* Let new data settle */

View File

@ -3611,11 +3611,15 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
schedule_timeout_uninterruptible(30*HZ);
/* Now try to get the controller to respond to a no-op */
for (i=0; i<12; i++) {
for (i=0; i<30; i++) {
if (cciss_noop(pdev) == 0)
break;
else
printk("cciss: no-op failed%s\n", (i < 11 ? "; re-trying" : ""));
schedule_timeout_uninterruptible(HZ);
}
if (i == 30) {
printk(KERN_ERR "cciss: controller seems dead\n");
return -EBUSY;
}
}

View File

@ -40,6 +40,7 @@
#include <linux/hdreg.h>
#include <linux/cdrom.h>
#include <linux/module.h>
#include <linux/scatterlist.h>
#include <xen/xenbus.h>
#include <xen/grant_table.h>
@ -82,6 +83,7 @@ struct blkfront_info
enum blkif_state connected;
int ring_ref;
struct blkif_front_ring ring;
struct scatterlist sg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
unsigned int evtchn, irq;
struct request_queue *rq;
struct work_struct work;
@ -204,12 +206,11 @@ static int blkif_queue_request(struct request *req)
struct blkfront_info *info = req->rq_disk->private_data;
unsigned long buffer_mfn;
struct blkif_request *ring_req;
struct req_iterator iter;
struct bio_vec *bvec;
unsigned long id;
unsigned int fsect, lsect;
int ref;
int i, ref;
grant_ref_t gref_head;
struct scatterlist *sg;
if (unlikely(info->connected != BLKIF_STATE_CONNECTED))
return 1;
@ -238,12 +239,13 @@ static int blkif_queue_request(struct request *req)
if (blk_barrier_rq(req))
ring_req->operation = BLKIF_OP_WRITE_BARRIER;
ring_req->nr_segments = 0;
rq_for_each_segment(bvec, req, iter) {
BUG_ON(ring_req->nr_segments == BLKIF_MAX_SEGMENTS_PER_REQUEST);
buffer_mfn = pfn_to_mfn(page_to_pfn(bvec->bv_page));
fsect = bvec->bv_offset >> 9;
lsect = fsect + (bvec->bv_len >> 9) - 1;
ring_req->nr_segments = blk_rq_map_sg(req->q, req, info->sg);
BUG_ON(ring_req->nr_segments > BLKIF_MAX_SEGMENTS_PER_REQUEST);
for_each_sg(info->sg, sg, ring_req->nr_segments, i) {
buffer_mfn = pfn_to_mfn(page_to_pfn(sg_page(sg)));
fsect = sg->offset >> 9;
lsect = fsect + (sg->length >> 9) - 1;
/* install a grant reference. */
ref = gnttab_claim_grant_reference(&gref_head);
BUG_ON(ref == -ENOSPC);
@ -254,16 +256,12 @@ static int blkif_queue_request(struct request *req)
buffer_mfn,
rq_data_dir(req) );
info->shadow[id].frame[ring_req->nr_segments] =
mfn_to_pfn(buffer_mfn);
ring_req->seg[ring_req->nr_segments] =
info->shadow[id].frame[i] = mfn_to_pfn(buffer_mfn);
ring_req->seg[i] =
(struct blkif_request_segment) {
.gref = ref,
.first_sect = fsect,
.last_sect = lsect };
ring_req->nr_segments++;
}
info->ring.req_prod_pvt++;
@ -622,6 +620,8 @@ static int setup_blkring(struct xenbus_device *dev,
SHARED_RING_INIT(sring);
FRONT_RING_INIT(&info->ring, sring, PAGE_SIZE);
sg_init_table(info->sg, BLKIF_MAX_SEGMENTS_PER_REQUEST);
err = xenbus_grant_ring(dev, virt_to_mfn(info->ring.sring));
if (err < 0) {
free_page((unsigned long)sring);

View File

@ -452,6 +452,59 @@ static void drm_setup_crtcs(struct drm_device *dev)
kfree(modes);
kfree(enabled);
}
/**
* drm_encoder_crtc_ok - can a given crtc drive a given encoder?
* @encoder: encoder to test
* @crtc: crtc to test
*
* Return false if @encoder can't be driven by @crtc, true otherwise.
*/
static bool drm_encoder_crtc_ok(struct drm_encoder *encoder,
struct drm_crtc *crtc)
{
struct drm_device *dev;
struct drm_crtc *tmp;
int crtc_mask = 1;
WARN(!crtc, "checking null crtc?");
dev = crtc->dev;
list_for_each_entry(tmp, &dev->mode_config.crtc_list, head) {
if (tmp == crtc)
break;
crtc_mask <<= 1;
}
if (encoder->possible_crtcs & crtc_mask)
return true;
return false;
}
/*
* Check the CRTC we're going to map each output to vs. its current
* CRTC. If they don't match, we have to disable the output and the CRTC
* since the driver will have to re-route things.
*/
static void
drm_crtc_prepare_encoders(struct drm_device *dev)
{
struct drm_encoder_helper_funcs *encoder_funcs;
struct drm_encoder *encoder;
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
encoder_funcs = encoder->helper_private;
/* Disable unused encoders */
if (encoder->crtc == NULL)
(*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
/* Disable encoders whose CRTC is about to change */
if (encoder_funcs->get_crtc &&
encoder->crtc != (*encoder_funcs->get_crtc)(encoder))
(*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
}
}
/**
* drm_crtc_set_mode - set a mode
* @crtc: CRTC to program
@ -547,6 +600,8 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
encoder_funcs->prepare(encoder);
}
drm_crtc_prepare_encoders(dev);
crtc_funcs->prepare(crtc);
/* Set up the DPLL and any encoders state that needs to adjust or depend
@ -617,7 +672,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
struct drm_device *dev;
struct drm_crtc **save_crtcs, *new_crtc;
struct drm_encoder **save_encoders, *new_encoder;
struct drm_framebuffer *old_fb;
struct drm_framebuffer *old_fb = NULL;
bool save_enabled;
bool mode_changed = false;
bool fb_changed = false;
@ -668,9 +723,10 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
* and then just flip_or_move it */
if (set->crtc->fb != set->fb) {
/* If we have no fb then treat it as a full mode set */
if (set->crtc->fb == NULL)
if (set->crtc->fb == NULL) {
DRM_DEBUG("crtc has no fb, full mode set\n");
mode_changed = true;
else if ((set->fb->bits_per_pixel !=
} else if ((set->fb->bits_per_pixel !=
set->crtc->fb->bits_per_pixel) ||
set->fb->depth != set->crtc->fb->depth)
fb_changed = true;
@ -682,7 +738,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
fb_changed = true;
if (set->mode && !drm_mode_equal(set->mode, &set->crtc->mode)) {
DRM_DEBUG("modes are different\n");
DRM_DEBUG("modes are different, full mode set\n");
drm_mode_debug_printmodeline(&set->crtc->mode);
drm_mode_debug_printmodeline(set->mode);
mode_changed = true;
@ -708,6 +764,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
}
if (new_encoder != connector->encoder) {
DRM_DEBUG("encoder changed, full mode switch\n");
mode_changed = true;
connector->encoder = new_encoder;
}
@ -734,10 +791,20 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
if (set->connectors[ro] == connector)
new_crtc = set->crtc;
}
/* Make sure the new CRTC will work with the encoder */
if (new_crtc &&
!drm_encoder_crtc_ok(connector->encoder, new_crtc)) {
ret = -EINVAL;
goto fail_set_mode;
}
if (new_crtc != connector->encoder->crtc) {
DRM_DEBUG("crtc changed, full mode switch\n");
mode_changed = true;
connector->encoder->crtc = new_crtc;
}
DRM_DEBUG("setting connector %d crtc to %p\n",
connector->base.id, new_crtc);
}
/* mode_set_base is not a required function */
@ -781,6 +848,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
fail_set_mode:
set->crtc->enabled = save_enabled;
set->crtc->fb = old_fb;
count = 0;
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
if (!connector->encoder)

View File

@ -125,7 +125,7 @@ static bool edid_is_valid(struct edid *edid)
DRM_ERROR("EDID has major version %d, instead of 1\n", edid->version);
goto bad;
}
if (edid->revision <= 0 || edid->revision > 3) {
if (edid->revision > 3) {
DRM_ERROR("EDID has minor version %d, which is not between 0-3\n", edid->revision);
goto bad;
}
@ -320,10 +320,10 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,
mode->htotal = mode->hdisplay + ((pt->hblank_hi << 8) | pt->hblank_lo);
mode->vdisplay = (pt->vactive_hi << 8) | pt->vactive_lo;
mode->vsync_start = mode->vdisplay + ((pt->vsync_offset_hi << 8) |
mode->vsync_start = mode->vdisplay + ((pt->vsync_offset_hi << 4) |
pt->vsync_offset_lo);
mode->vsync_end = mode->vsync_start +
((pt->vsync_pulse_width_hi << 8) |
((pt->vsync_pulse_width_hi << 4) |
pt->vsync_pulse_width_lo);
mode->vtotal = mode->vdisplay + ((pt->vblank_hi << 8) | pt->vblank_lo);

View File

@ -435,6 +435,8 @@ EXPORT_SYMBOL(drm_vblank_get);
*/
void drm_vblank_put(struct drm_device *dev, int crtc)
{
BUG_ON (atomic_read (&dev->vblank_refcount[crtc]) == 0);
/* Last user schedules interrupt disable */
if (atomic_dec_and_test(&dev->vblank_refcount[crtc]))
mod_timer(&dev->vblank_disable_timer, jiffies + 5*DRM_HZ);
@ -460,8 +462,9 @@ void drm_vblank_pre_modeset(struct drm_device *dev, int crtc)
* so that interrupts remain enabled in the interim.
*/
if (!dev->vblank_inmodeset[crtc]) {
dev->vblank_inmodeset[crtc] = 1;
drm_vblank_get(dev, crtc);
dev->vblank_inmodeset[crtc] = 0x1;
if (drm_vblank_get(dev, crtc) == 0)
dev->vblank_inmodeset[crtc] |= 0x2;
}
}
EXPORT_SYMBOL(drm_vblank_pre_modeset);
@ -473,9 +476,12 @@ void drm_vblank_post_modeset(struct drm_device *dev, int crtc)
if (dev->vblank_inmodeset[crtc]) {
spin_lock_irqsave(&dev->vbl_lock, irqflags);
dev->vblank_disable_allowed = 1;
dev->vblank_inmodeset[crtc] = 0;
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
drm_vblank_put(dev, crtc);
if (dev->vblank_inmodeset[crtc] & 0x2)
drm_vblank_put(dev, crtc);
dev->vblank_inmodeset[crtc] = 0;
}
}
EXPORT_SYMBOL(drm_vblank_post_modeset);

View File

@ -811,7 +811,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
dev_priv->hws_map.flags = 0;
dev_priv->hws_map.mtrr = 0;
drm_core_ioremap(&dev_priv->hws_map, dev);
drm_core_ioremap_wc(&dev_priv->hws_map, dev);
if (dev_priv->hws_map.handle == NULL) {
i915_dma_cleanup(dev);
dev_priv->status_gfx_addr = 0;
@ -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:

View File

@ -68,9 +68,11 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
i915_save_state(dev);
/* If KMS is active, we do the leavevt stuff here */
if (drm_core_check_feature(dev, DRIVER_MODESET) && i915_gem_idle(dev)) {
dev_err(&dev->pdev->dev, "GEM idle failed, aborting suspend\n");
return -EBUSY;
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
if (i915_gem_idle(dev))
dev_err(&dev->pdev->dev,
"GEM idle failed, resume may fail\n");
drm_irq_uninstall(dev);
}
intel_opregion_free(dev);
@ -108,6 +110,8 @@ static int i915_resume(struct drm_device *dev)
if (ret != 0)
ret = -1;
mutex_unlock(&dev->struct_mutex);
drm_irq_install(dev);
}
return ret;

View File

@ -211,7 +211,7 @@ fast_user_write(struct io_mapping *mapping,
vaddr_atomic = io_mapping_map_atomic_wc(mapping, page_base);
unwritten = __copy_from_user_inatomic_nocache(vaddr_atomic + page_offset,
user_data, length);
user_data, length, length);
io_mapping_unmap_atomic(vaddr_atomic);
if (unwritten)
return -EFAULT;
@ -1051,6 +1051,9 @@ i915_gem_retire_requests(struct drm_device *dev)
drm_i915_private_t *dev_priv = dev->dev_private;
uint32_t seqno;
if (!dev_priv->hw_status_page)
return;
seqno = i915_get_gem_seqno(dev);
while (!list_empty(&dev_priv->mm.request_list)) {
@ -3545,7 +3548,7 @@ i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
user_data = (char __user *) (uintptr_t) args->data_ptr;
obj_addr = obj_priv->phys_obj->handle->vaddr + args->offset;
DRM_ERROR("obj_addr %p, %lld\n", obj_addr, args->size);
DRM_DEBUG("obj_addr %p, %lld\n", obj_addr, args->size);
ret = copy_from_user(obj_addr, user_data, args->size);
if (ret)
return -EFAULT;

View File

@ -111,6 +111,12 @@ parse_panel_data(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
panel_fixed_mode->clock = dvo_timing->clock * 10;
panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED;
/* Some VBTs have bogus h/vtotal values */
if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal)
panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1;
if (panel_fixed_mode->vsync_end > panel_fixed_mode->vtotal)
panel_fixed_mode->vtotal = panel_fixed_mode->vsync_end + 1;
drm_mode_set_name(panel_fixed_mode);
dev_priv->vbt_mode = panel_fixed_mode;

View File

@ -217,7 +217,7 @@ bool intel_pipe_has_type (struct drm_crtc *crtc, int type)
return false;
}
#define INTELPllInvalid(s) do { DRM_DEBUG(s); return false; } while (0)
#define INTELPllInvalid(s) do { /* DRM_DEBUG(s); */ return false; } while (0)
/**
* Returns whether the given set of divisors are valid for a given refclk with
* the given connectors.

View File

@ -79,10 +79,11 @@ static struct i2c_algo_bit_data ioc_data = {
.getsda = ioc_getsda,
.getscl = ioc_getscl,
.udelay = 80,
.timeout = 100
.timeout = HZ,
};
static struct i2c_adapter ioc_ops = {
.nr = 0,
.algo_data = &ioc_data,
};
@ -90,7 +91,7 @@ static int __init i2c_ioc_init(void)
{
force_ones = FORCE_ONES | SCL | SDA;
return i2c_bit_add_bus(&ioc_ops);
return i2c_bit_add_numbered_bus(&ioc_ops);
}
module_init(i2c_ioc_init);

View File

@ -72,7 +72,7 @@ static unsigned int amd_ec_wait_write(struct amd_smbus *smbus)
{
int timeout = 500;
while (timeout-- && (inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_IBF))
while ((inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_IBF) && --timeout)
udelay(1);
if (!timeout) {
@ -88,7 +88,7 @@ static unsigned int amd_ec_wait_read(struct amd_smbus *smbus)
{
int timeout = 500;
while (timeout-- && (~inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_OBF))
while ((~inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_OBF) && --timeout)
udelay(1);
if (!timeout) {

View File

@ -114,7 +114,7 @@ static int ixp2000_i2c_probe(struct platform_device *plat_dev)
drv_data->algo_data.getsda = ixp2000_bit_getsda;
drv_data->algo_data.getscl = ixp2000_bit_getscl;
drv_data->algo_data.udelay = 6;
drv_data->algo_data.timeout = 100;
drv_data->algo_data.timeout = HZ;
strlcpy(drv_data->adapter.name, plat_dev->dev.driver->name,
sizeof(drv_data->adapter.name));

View File

@ -644,7 +644,7 @@ static int i2c_pxa_do_pio_xfer(struct pxa_i2c *i2c,
i2c_pxa_start_message(i2c);
while (timeout-- && i2c->msg_num > 0) {
while (i2c->msg_num > 0 && --timeout) {
i2c_pxa_handler(0, i2c);
udelay(10);
}

View File

@ -76,7 +76,7 @@ static struct i2c_algo_bit_data scx200_i2c_data = {
.getsda = scx200_i2c_getsda,
.getscl = scx200_i2c_getscl,
.udelay = 10,
.timeout = 100,
.timeout = HZ,
};
static struct i2c_adapter scx200_i2c_ops = {

View File

@ -1831,7 +1831,8 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
case I2C_SMBUS_QUICK:
msg[0].len = 0;
/* Special case: The read/write field is used as data */
msg[0].flags = flags | (read_write==I2C_SMBUS_READ)?I2C_M_RD:0;
msg[0].flags = flags | (read_write == I2C_SMBUS_READ ?
I2C_M_RD : 0);
num = 1;
break;
case I2C_SMBUS_BYTE:

View File

@ -35,6 +35,7 @@
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <linux/smp_lock.h>
#include <linux/jiffies.h>
#include <asm/uaccess.h>
static struct i2c_driver i2cdev_driver;
@ -422,7 +423,10 @@ static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
client->adapter->retries = arg;
break;
case I2C_TIMEOUT:
client->adapter->timeout = arg;
/* For historical reasons, user-space sets the timeout
* value in units of 10 ms.
*/
client->adapter->timeout = msecs_to_jiffies(arg * 10);
break;
default:
/* NOTE: returning a fault code here could cause trouble

View File

@ -46,7 +46,7 @@ menuconfig IDE
SMART parameters from disk drives.
To compile this driver as a module, choose M here: the
module will be called ide.
module will be called ide-core.ko.
For further information, please read <file:Documentation/ide/ide.txt>.

View File

@ -166,7 +166,7 @@ static unsigned int init_chipset_amd74xx(struct pci_dev *dev)
* Check for broken FIFO support.
*/
if (dev->vendor == PCI_VENDOR_ID_AMD &&
dev->vendor == PCI_DEVICE_ID_AMD_VIPER_7411)
dev->device == PCI_DEVICE_ID_AMD_VIPER_7411)
t &= 0x0f;
else
t |= 0xf0;

View File

@ -52,7 +52,7 @@ static void atiixp_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
unsigned long flags;
int timing_shift = (drive->dn & 2) ? 16 : 0 + (drive->dn & 1) ? 0 : 8;
int timing_shift = (drive->dn ^ 1) * 8;
u32 pio_timing_data;
u16 pio_mode_data;
@ -85,7 +85,7 @@ static void atiixp_set_dma_mode(ide_drive_t *drive, const u8 speed)
{
struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
unsigned long flags;
int timing_shift = (drive->dn & 2) ? 16 : 0 + (drive->dn & 1) ? 0 : 8;
int timing_shift = (drive->dn ^ 1) * 8;
u32 tmp32;
u16 tmp16;
u16 udma_ctl = 0;

View File

@ -55,7 +55,7 @@
static DEFINE_MUTEX(idecd_ref_mutex);
static void ide_cd_release(struct kref *);
static void ide_cd_release(struct device *);
static struct cdrom_info *ide_cd_get(struct gendisk *disk)
{
@ -67,7 +67,7 @@ static struct cdrom_info *ide_cd_get(struct gendisk *disk)
if (ide_device_get(cd->drive))
cd = NULL;
else
kref_get(&cd->kref);
get_device(&cd->dev);
}
mutex_unlock(&idecd_ref_mutex);
@ -79,7 +79,7 @@ static void ide_cd_put(struct cdrom_info *cd)
ide_drive_t *drive = cd->drive;
mutex_lock(&idecd_ref_mutex);
kref_put(&cd->kref, ide_cd_release);
put_device(&cd->dev);
ide_device_put(drive);
mutex_unlock(&idecd_ref_mutex);
}
@ -194,6 +194,14 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive,
bio_sectors = max(bio_sectors(failed_command->bio), 4U);
sector &= ~(bio_sectors - 1);
/*
* The SCSI specification allows for the value
* returned by READ CAPACITY to be up to 75 2K
* sectors past the last readable block.
* Therefore, if we hit a medium error within the
* last 75 2K sectors, we decrease the saved size
* value.
*/
if (sector < get_capacity(info->disk) &&
drive->probed_capacity - sector < 4 * 75)
set_capacity(info->disk, sector);
@ -1790,15 +1798,17 @@ static void ide_cd_remove(ide_drive_t *drive)
ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
ide_proc_unregister_driver(drive, info->driver);
device_del(&info->dev);
del_gendisk(info->disk);
ide_cd_put(info);
mutex_lock(&idecd_ref_mutex);
put_device(&info->dev);
mutex_unlock(&idecd_ref_mutex);
}
static void ide_cd_release(struct kref *kref)
static void ide_cd_release(struct device *dev)
{
struct cdrom_info *info = to_ide_drv(kref, cdrom_info);
struct cdrom_info *info = to_ide_drv(dev, cdrom_info);
struct cdrom_device_info *devinfo = &info->devinfo;
ide_drive_t *drive = info->drive;
struct gendisk *g = info->disk;
@ -1997,7 +2007,12 @@ static int ide_cd_probe(ide_drive_t *drive)
ide_init_disk(g, drive);
kref_init(&info->kref);
info->dev.parent = &drive->gendev;
info->dev.release = ide_cd_release;
dev_set_name(&info->dev, dev_name(&drive->gendev));
if (device_register(&info->dev))
goto out_free_disk;
info->drive = drive;
info->driver = &ide_cdrom_driver;
@ -2011,7 +2026,7 @@ static int ide_cd_probe(ide_drive_t *drive)
g->driverfs_dev = &drive->gendev;
g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE;
if (ide_cdrom_setup(drive)) {
ide_cd_release(&info->kref);
put_device(&info->dev);
goto failed;
}
@ -2021,6 +2036,8 @@ static int ide_cd_probe(ide_drive_t *drive)
add_disk(g);
return 0;
out_free_disk:
put_disk(g);
out_free_cd:
kfree(info);
failed:

View File

@ -80,7 +80,7 @@ struct cdrom_info {
ide_drive_t *drive;
struct ide_driver *driver;
struct gendisk *disk;
struct kref kref;
struct device dev;
/* Buffer for table of contents. NULL if we haven't allocated
a TOC buffer for this device yet. */

View File

@ -25,7 +25,7 @@ module_param(debug_mask, ulong, 0644);
static DEFINE_MUTEX(ide_disk_ref_mutex);
static void ide_disk_release(struct kref *);
static void ide_disk_release(struct device *);
static struct ide_disk_obj *ide_disk_get(struct gendisk *disk)
{
@ -37,7 +37,7 @@ static struct ide_disk_obj *ide_disk_get(struct gendisk *disk)
if (ide_device_get(idkp->drive))
idkp = NULL;
else
kref_get(&idkp->kref);
get_device(&idkp->dev);
}
mutex_unlock(&ide_disk_ref_mutex);
return idkp;
@ -48,7 +48,7 @@ static void ide_disk_put(struct ide_disk_obj *idkp)
ide_drive_t *drive = idkp->drive;
mutex_lock(&ide_disk_ref_mutex);
kref_put(&idkp->kref, ide_disk_release);
put_device(&idkp->dev);
ide_device_put(drive);
mutex_unlock(&ide_disk_ref_mutex);
}
@ -66,17 +66,18 @@ static void ide_gd_remove(ide_drive_t *drive)
struct gendisk *g = idkp->disk;
ide_proc_unregister_driver(drive, idkp->driver);
device_del(&idkp->dev);
del_gendisk(g);
drive->disk_ops->flush(drive);
ide_disk_put(idkp);
mutex_lock(&ide_disk_ref_mutex);
put_device(&idkp->dev);
mutex_unlock(&ide_disk_ref_mutex);
}
static void ide_disk_release(struct kref *kref)
static void ide_disk_release(struct device *dev)
{
struct ide_disk_obj *idkp = to_ide_drv(kref, ide_disk_obj);
struct ide_disk_obj *idkp = to_ide_drv(dev, ide_disk_obj);
ide_drive_t *drive = idkp->drive;
struct gendisk *g = idkp->disk;
@ -348,7 +349,12 @@ static int ide_gd_probe(ide_drive_t *drive)
ide_init_disk(g, drive);
kref_init(&idkp->kref);
idkp->dev.parent = &drive->gendev;
idkp->dev.release = ide_disk_release;
dev_set_name(&idkp->dev, dev_name(&drive->gendev));
if (device_register(&idkp->dev))
goto out_free_disk;
idkp->drive = drive;
idkp->driver = &ide_gd_driver;
@ -373,6 +379,8 @@ static int ide_gd_probe(ide_drive_t *drive)
add_disk(g);
return 0;
out_free_disk:
put_disk(g);
out_free_idkp:
kfree(idkp);
failed:

View File

@ -17,7 +17,7 @@ struct ide_disk_obj {
ide_drive_t *drive;
struct ide_driver *driver;
struct gendisk *disk;
struct kref kref;
struct device dev;
unsigned int openers; /* protected by BKL for now */
/* Last failed packet command */

View File

@ -169,7 +169,7 @@ typedef struct ide_tape_obj {
ide_drive_t *drive;
struct ide_driver *driver;
struct gendisk *disk;
struct kref kref;
struct device dev;
/*
* failed_pc points to the last failed packet command, or contains
@ -267,7 +267,7 @@ static DEFINE_MUTEX(idetape_ref_mutex);
static struct class *idetape_sysfs_class;
static void ide_tape_release(struct kref *);
static void ide_tape_release(struct device *);
static struct ide_tape_obj *ide_tape_get(struct gendisk *disk)
{
@ -279,7 +279,7 @@ static struct ide_tape_obj *ide_tape_get(struct gendisk *disk)
if (ide_device_get(tape->drive))
tape = NULL;
else
kref_get(&tape->kref);
get_device(&tape->dev);
}
mutex_unlock(&idetape_ref_mutex);
return tape;
@ -290,7 +290,7 @@ static void ide_tape_put(struct ide_tape_obj *tape)
ide_drive_t *drive = tape->drive;
mutex_lock(&idetape_ref_mutex);
kref_put(&tape->kref, ide_tape_release);
put_device(&tape->dev);
ide_device_put(drive);
mutex_unlock(&idetape_ref_mutex);
}
@ -308,7 +308,7 @@ static struct ide_tape_obj *ide_tape_chrdev_get(unsigned int i)
mutex_lock(&idetape_ref_mutex);
tape = idetape_devs[i];
if (tape)
kref_get(&tape->kref);
get_device(&tape->dev);
mutex_unlock(&idetape_ref_mutex);
return tape;
}
@ -2256,15 +2256,17 @@ static void ide_tape_remove(ide_drive_t *drive)
idetape_tape_t *tape = drive->driver_data;
ide_proc_unregister_driver(drive, tape->driver);
device_del(&tape->dev);
ide_unregister_region(tape->disk);
ide_tape_put(tape);
mutex_lock(&idetape_ref_mutex);
put_device(&tape->dev);
mutex_unlock(&idetape_ref_mutex);
}
static void ide_tape_release(struct kref *kref)
static void ide_tape_release(struct device *dev)
{
struct ide_tape_obj *tape = to_ide_drv(kref, ide_tape_obj);
struct ide_tape_obj *tape = to_ide_drv(dev, ide_tape_obj);
ide_drive_t *drive = tape->drive;
struct gendisk *g = tape->disk;
@ -2407,7 +2409,12 @@ static int ide_tape_probe(ide_drive_t *drive)
ide_init_disk(g, drive);
kref_init(&tape->kref);
tape->dev.parent = &drive->gendev;
tape->dev.release = ide_tape_release;
dev_set_name(&tape->dev, dev_name(&drive->gendev));
if (device_register(&tape->dev))
goto out_free_disk;
tape->drive = drive;
tape->driver = &idetape_driver;
@ -2436,6 +2443,8 @@ static int ide_tape_probe(ide_drive_t *drive)
return 0;
out_free_disk:
put_disk(g);
out_free_tape:
kfree(tape);
failed:

View File

@ -337,6 +337,7 @@ static int ide_set_dev_param_mask(const char *s, struct kernel_param *kp)
int a, b, i, j = 1;
unsigned int *dev_param_mask = (unsigned int *)kp->arg;
/* controller . device (0 or 1) [ : 1 (set) | 0 (clear) ] */
if (sscanf(s, "%d.%d:%d", &a, &b, &j) != 3 &&
sscanf(s, "%d.%d", &a, &b) != 2)
return -EINVAL;
@ -349,7 +350,7 @@ static int ide_set_dev_param_mask(const char *s, struct kernel_param *kp)
if (j)
*dev_param_mask |= (1 << i);
else
*dev_param_mask &= (1 << i);
*dev_param_mask &= ~(1 << i);
return 0;
}
@ -392,6 +393,8 @@ static int ide_set_disk_chs(const char *str, struct kernel_param *kp)
{
int a, b, c = 0, h = 0, s = 0, i, j = 1;
/* controller . device (0 or 1) : Cylinders , Heads , Sectors */
/* controller . device (0 or 1) : 1 (use CHS) | 0 (ignore CHS) */
if (sscanf(str, "%d.%d:%d,%d,%d", &a, &b, &c, &h, &s) != 5 &&
sscanf(str, "%d.%d:%d", &a, &b, &j) != 3)
return -EINVAL;
@ -407,7 +410,7 @@ static int ide_set_disk_chs(const char *str, struct kernel_param *kp)
if (j)
ide_disks |= (1 << i);
else
ide_disks &= (1 << i);
ide_disks &= ~(1 << i);
ide_disks_chs[i].cyl = c;
ide_disks_chs[i].head = h;
@ -469,6 +472,8 @@ static int ide_set_ignore_cable(const char *s, struct kernel_param *kp)
{
int i, j = 1;
/* controller (ignore) */
/* controller : 1 (ignore) | 0 (use) */
if (sscanf(s, "%d:%d", &i, &j) != 2 && sscanf(s, "%d", &i) != 1)
return -EINVAL;
@ -478,7 +483,7 @@ static int ide_set_ignore_cable(const char *s, struct kernel_param *kp)
if (j)
ide_ignore_cable |= (1 << i);
else
ide_ignore_cable &= (1 << i);
ide_ignore_cable &= ~(1 << i);
return 0;
}

View File

@ -5,9 +5,8 @@
* May be copied or modified under the terms of the GNU General Public License
* Based in part on the ITE vendor provided SCSI driver.
*
* Documentation available from
* http://www.ite.com.tw/pc/IT8212F_V04.pdf
* Some other documents are NDA.
* Documentation:
* Datasheet is freely available, some other documents under NDA.
*
* The ITE8212 isn't exactly a standard IDE controller. It has two
* modes. In pass through mode then it is an IDE controller. In its smart

View File

@ -12,6 +12,7 @@
#include <asm/types.h>
struct file;
struct pci_dev;
struct scatterlist;
struct vm_area_struct;

View File

@ -1275,7 +1275,7 @@ static void __exit ieee1394_cleanup(void)
unregister_chrdev_region(IEEE1394_CORE_DEV, 256);
}
module_init(ieee1394_init);
fs_initcall(ieee1394_init);
module_exit(ieee1394_cleanup);
/* Exported symbols */
@ -1314,6 +1314,7 @@ EXPORT_SYMBOL(hpsb_make_lock64packet);
EXPORT_SYMBOL(hpsb_make_phypacket);
EXPORT_SYMBOL(hpsb_read);
EXPORT_SYMBOL(hpsb_write);
EXPORT_SYMBOL(hpsb_lock);
EXPORT_SYMBOL(hpsb_packet_success);
/** highlevel.c **/

View File

@ -501,8 +501,6 @@ int hpsb_read(struct hpsb_host *host, nodeid_t node, unsigned int generation,
if (length == 0)
return -EINVAL;
BUG_ON(in_interrupt()); // We can't be called in an interrupt, yet
packet = hpsb_make_readpacket(host, node, addr, length);
if (!packet) {
@ -550,8 +548,6 @@ int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation,
if (length == 0)
return -EINVAL;
BUG_ON(in_interrupt()); // We can't be called in an interrupt, yet
packet = hpsb_make_writepacket(host, node, addr, buffer, length);
if (!packet)
@ -570,3 +566,30 @@ int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation,
return retval;
}
int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation,
u64 addr, int extcode, quadlet_t *data, quadlet_t arg)
{
struct hpsb_packet *packet;
int retval = 0;
packet = hpsb_make_lockpacket(host, node, addr, extcode, data, arg);
if (!packet)
return -ENOMEM;
packet->generation = generation;
retval = hpsb_send_packet_and_wait(packet);
if (retval < 0)
goto hpsb_lock_fail;
retval = hpsb_packet_success(packet);
if (retval == 0)
*data = packet->data[0];
hpsb_lock_fail:
hpsb_free_tlabel(packet);
hpsb_free_packet(packet);
return retval;
}

View File

@ -30,6 +30,8 @@ int hpsb_read(struct hpsb_host *host, nodeid_t node, unsigned int generation,
u64 addr, quadlet_t *buffer, size_t length);
int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation,
u64 addr, quadlet_t *buffer, size_t length);
int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation,
u64 addr, int extcode, quadlet_t *data, quadlet_t arg);
#ifdef HPSB_DEBUG_TLABELS
extern spinlock_t hpsb_tlabel_lock;

View File

@ -13,6 +13,7 @@
#define IEEE1394_ISO_H
#include <linux/spinlock_types.h>
#include <linux/wait.h>
#include <asm/atomic.h>
#include <asm/types.h>

View File

@ -971,6 +971,9 @@ static struct unit_directory *nodemgr_process_unit_directory
ud->ud_kv = ud_kv;
ud->id = (*id)++;
/* inherit vendor_id from root directory if none exists in unit dir */
ud->vendor_id = ne->vendor_id;
csr1212_for_each_dir_entry(ne->csr, kv, ud_kv, dentry) {
switch (kv->key.id) {
case CSR1212_KV_ID_VENDOR:
@ -1265,7 +1268,8 @@ static void nodemgr_update_node(struct node_entry *ne, struct csr1212_csr *csr,
csr1212_destroy_csr(csr);
}
/* Mark the node current */
/* Finally, mark the node current */
smp_wmb();
ne->generation = generation;
if (ne->in_limbo) {
@ -1798,7 +1802,7 @@ void hpsb_node_fill_packet(struct node_entry *ne, struct hpsb_packet *packet)
{
packet->host = ne->host;
packet->generation = ne->generation;
barrier();
smp_rmb();
packet->node_id = ne->nodeid;
}
@ -1807,7 +1811,7 @@ int hpsb_node_write(struct node_entry *ne, u64 addr,
{
unsigned int generation = ne->generation;
barrier();
smp_rmb();
return hpsb_write(ne->host, ne->nodeid, generation,
addr, buffer, length);
}

View File

@ -21,9 +21,11 @@
#define _IEEE1394_NODEMGR_H
#include <linux/device.h>
#include <asm/system.h>
#include <asm/types.h>
#include "ieee1394_core.h"
#include "ieee1394_transactions.h"
#include "ieee1394_types.h"
struct csr1212_csr;
@ -154,6 +156,22 @@ static inline int hpsb_node_entry_valid(struct node_entry *ne)
void hpsb_node_fill_packet(struct node_entry *ne, struct hpsb_packet *packet);
int hpsb_node_write(struct node_entry *ne, u64 addr,
quadlet_t *buffer, size_t length);
static inline int hpsb_node_read(struct node_entry *ne, u64 addr,
quadlet_t *buffer, size_t length)
{
unsigned int g = ne->generation;
smp_rmb();
return hpsb_read(ne->host, ne->nodeid, g, addr, buffer, length);
}
static inline int hpsb_node_lock(struct node_entry *ne, u64 addr, int extcode,
quadlet_t *buffer, quadlet_t arg)
{
unsigned int g = ne->generation;
smp_rmb();
return hpsb_lock(ne->host, ne->nodeid, g, addr, extcode, buffer, arg);
}
int nodemgr_for_each_host(void *data, int (*cb)(struct hpsb_host *, void *));
int init_ieee1394_nodemgr(void);

View File

@ -54,7 +54,7 @@ void memcpy_toshmem(int card, void *dest, const void *src, size_t n)
spin_unlock_irqrestore(&sc_adapter[card]->lock, flags);
pr_debug("%s: set page to %#x\n",sc_adapter[card]->devicename,
((sc_adapter[card]->shmem_magic + ch * SRAM_PAGESIZE)>>14)|0x80);
pr_debug("%s: copying %d bytes from %#lx to %#lx\n",
pr_debug("%s: copying %zu bytes from %#lx to %#lx\n",
sc_adapter[card]->devicename, n,
(unsigned long) src,
sc_adapter[card]->rambase + ((unsigned long) dest %0x4000));

View File

@ -1237,8 +1237,9 @@ static void end_sync_write(struct bio *bio, int error)
update_head_pos(mirror, r1_bio);
if (atomic_dec_and_test(&r1_bio->remaining)) {
md_done_sync(mddev, r1_bio->sectors, uptodate);
sector_t s = r1_bio->sectors;
put_buf(r1_bio);
md_done_sync(mddev, s, uptodate);
}
}

View File

@ -1236,6 +1236,7 @@ static void end_sync_read(struct bio *bio, int error)
/* for reconstruct, we always reschedule after a read.
* for resync, only after all reads
*/
rdev_dec_pending(conf->mirrors[d].rdev, conf->mddev);
if (test_bit(R10BIO_IsRecover, &r10_bio->state) ||
atomic_dec_and_test(&r10_bio->remaining)) {
/* we have read all the blocks,
@ -1243,7 +1244,6 @@ static void end_sync_read(struct bio *bio, int error)
*/
reschedule_retry(r10_bio);
}
rdev_dec_pending(conf->mirrors[d].rdev, conf->mddev);
}
static void end_sync_write(struct bio *bio, int error)
@ -1264,11 +1264,13 @@ static void end_sync_write(struct bio *bio, int error)
update_head_pos(i, r10_bio);
rdev_dec_pending(conf->mirrors[d].rdev, mddev);
while (atomic_dec_and_test(&r10_bio->remaining)) {
if (r10_bio->master_bio == NULL) {
/* the primary of several recovery bios */
md_done_sync(mddev, r10_bio->sectors, 1);
sector_t s = r10_bio->sectors;
put_buf(r10_bio);
md_done_sync(mddev, s, 1);
break;
} else {
r10bio_t *r10_bio2 = (r10bio_t *)r10_bio->master_bio;
@ -1276,7 +1278,6 @@ static void end_sync_write(struct bio *bio, int error)
r10_bio = r10_bio2;
}
}
rdev_dec_pending(conf->mirrors[d].rdev, mddev);
}
/*
@ -1749,8 +1750,6 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
if (!go_faster && conf->nr_waiting)
msleep_interruptible(1000);
bitmap_cond_end_sync(mddev->bitmap, sector_nr);
/* Again, very different code for resync and recovery.
* Both must result in an r10bio with a list of bios that
* have bi_end_io, bi_sector, bi_bdev set,
@ -1886,6 +1885,8 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
/* resync. Schedule a read for every block at this virt offset */
int count = 0;
bitmap_cond_end_sync(mddev->bitmap, sector_nr);
if (!bitmap_start_sync(mddev->bitmap, sector_nr,
&sync_blocks, mddev->degraded) &&
!conf->fullsync && !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) {
@ -2010,13 +2011,13 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
/* There is nowhere to write, so all non-sync
* drives must be failed, so try the next chunk...
*/
{
sector_t sec = max_sector - sector_nr;
sectors_skipped += sec;
if (sector_nr + max_sync < max_sector)
max_sector = sector_nr + max_sync;
sectors_skipped += (max_sector - sector_nr);
chunks_skipped ++;
sector_nr = max_sector;
goto skipped;
}
}
static int run(mddev_t *mddev)

View File

@ -51,6 +51,10 @@ comment "Supported SDMC DM1105 Adapters"
depends on DVB_CORE && PCI && I2C
source "drivers/media/dvb/dm1105/Kconfig"
comment "Supported FireWire (IEEE 1394) Adapters"
depends on DVB_CORE && IEEE1394
source "drivers/media/dvb/firewire/Kconfig"
comment "Supported DVB Frontends"
depends on DVB_CORE
source "drivers/media/dvb/frontends/Kconfig"

View File

@ -3,3 +3,5 @@
#
obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ dvb-usb/ pluto2/ siano/ dm1105/
obj-$(CONFIG_DVB_FIREDTV) += firewire/

View File

@ -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)
{

View File

@ -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);

View File

@ -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);
}

View File

@ -0,0 +1,22 @@
config DVB_FIREDTV
tristate "FireDTV and FloppyDTV"
depends on DVB_CORE && IEEE1394
help
Support for DVB receivers from Digital Everywhere
which are connected via IEEE 1394 (FireWire).
These devices don't have an MPEG decoder built in,
so you need an external software decoder to watch TV.
To compile this driver as a module, say M here:
the module will be called firedtv.
if DVB_FIREDTV
config DVB_FIREDTV_IEEE1394
def_bool IEEE1394
config DVB_FIREDTV_INPUT
def_bool INPUT = y || (INPUT = m && DVB_FIREDTV = m)
endif # DVB_FIREDTV

View File

@ -0,0 +1,8 @@
obj-$(CONFIG_DVB_FIREDTV) += firedtv.o
firedtv-y := firedtv-avc.o firedtv-ci.o firedtv-dvb.o firedtv-fe.o
firedtv-$(CONFIG_DVB_FIREDTV_IEEE1394) += firedtv-1394.o
firedtv-$(CONFIG_DVB_FIREDTV_INPUT) += firedtv-rc.o
ccflags-y += -Idrivers/media/dvb/dvb-core
ccflags-$(CONFIG_DVB_FIREDTV_IEEE1394) += -Idrivers/ieee1394

View File

@ -0,0 +1,285 @@
/*
* FireDTV driver (formerly known as FireSAT)
*
* Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
* Copyright (C) 2007-2008 Ben Backx <ben@bbackx.com>
* Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*/
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/types.h>
#include <dma.h>
#include <csr1212.h>
#include <highlevel.h>
#include <hosts.h>
#include <ieee1394.h>
#include <iso.h>
#include <nodemgr.h>
#include "firedtv.h"
static LIST_HEAD(node_list);
static DEFINE_SPINLOCK(node_list_lock);
#define FIREWIRE_HEADER_SIZE 4
#define CIP_HEADER_SIZE 8
static void rawiso_activity_cb(struct hpsb_iso *iso)
{
struct firedtv *f, *fdtv = NULL;
unsigned int i, num, packet;
unsigned char *buf;
unsigned long flags;
int count;
spin_lock_irqsave(&node_list_lock, flags);
list_for_each_entry(f, &node_list, list)
if (f->backend_data == iso) {
fdtv = f;
break;
}
spin_unlock_irqrestore(&node_list_lock, flags);
packet = iso->first_packet;
num = hpsb_iso_n_ready(iso);
if (!fdtv) {
dev_err(fdtv->device, "received at unknown iso channel\n");
goto out;
}
for (i = 0; i < num; i++, packet = (packet + 1) % iso->buf_packets) {
buf = dma_region_i(&iso->data_buf, unsigned char,
iso->infos[packet].offset + CIP_HEADER_SIZE);
count = (iso->infos[packet].len - CIP_HEADER_SIZE) /
(188 + FIREWIRE_HEADER_SIZE);
/* ignore empty packet */
if (iso->infos[packet].len <= CIP_HEADER_SIZE)
continue;
while (count--) {
if (buf[FIREWIRE_HEADER_SIZE] == 0x47)
dvb_dmx_swfilter_packets(&fdtv->demux,
&buf[FIREWIRE_HEADER_SIZE], 1);
else
dev_err(fdtv->device,
"skipping invalid packet\n");
buf += 188 + FIREWIRE_HEADER_SIZE;
}
}
out:
hpsb_iso_recv_release_packets(iso, num);
}
static inline struct node_entry *node_of(struct firedtv *fdtv)
{
return container_of(fdtv->device, struct unit_directory, device)->ne;
}
static int node_lock(struct firedtv *fdtv, u64 addr, void *data, __be32 arg)
{
return hpsb_node_lock(node_of(fdtv), addr, EXTCODE_COMPARE_SWAP, data,
(__force quadlet_t)arg);
}
static int node_read(struct firedtv *fdtv, u64 addr, void *data, size_t len)
{
return hpsb_node_read(node_of(fdtv), addr, data, len);
}
static int node_write(struct firedtv *fdtv, u64 addr, void *data, size_t len)
{
return hpsb_node_write(node_of(fdtv), addr, data, len);
}
#define FDTV_ISO_BUFFER_PACKETS 256
#define FDTV_ISO_BUFFER_SIZE (FDTV_ISO_BUFFER_PACKETS * 200)
static int start_iso(struct firedtv *fdtv)
{
struct hpsb_iso *iso_handle;
int ret;
iso_handle = hpsb_iso_recv_init(node_of(fdtv)->host,
FDTV_ISO_BUFFER_SIZE, FDTV_ISO_BUFFER_PACKETS,
fdtv->isochannel, HPSB_ISO_DMA_DEFAULT,
-1, /* stat.config.irq_interval */
rawiso_activity_cb);
if (iso_handle == NULL) {
dev_err(fdtv->device, "cannot initialize iso receive\n");
return -ENOMEM;
}
fdtv->backend_data = iso_handle;
ret = hpsb_iso_recv_start(iso_handle, -1, -1, 0);
if (ret != 0) {
dev_err(fdtv->device, "cannot start iso receive\n");
hpsb_iso_shutdown(iso_handle);
fdtv->backend_data = NULL;
}
return ret;
}
static void stop_iso(struct firedtv *fdtv)
{
struct hpsb_iso *iso_handle = fdtv->backend_data;
if (iso_handle != NULL) {
hpsb_iso_stop(iso_handle);
hpsb_iso_shutdown(iso_handle);
}
fdtv->backend_data = NULL;
}
static const struct firedtv_backend fdtv_1394_backend = {
.lock = node_lock,
.read = node_read,
.write = node_write,
.start_iso = start_iso,
.stop_iso = stop_iso,
};
static void fcp_request(struct hpsb_host *host, int nodeid, int direction,
int cts, u8 *data, size_t length)
{
struct firedtv *f, *fdtv = NULL;
unsigned long flags;
int su;
if (length == 0 || (data[0] & 0xf0) != 0)
return;
su = data[1] & 0x7;
spin_lock_irqsave(&node_list_lock, flags);
list_for_each_entry(f, &node_list, list)
if (node_of(f)->host == host &&
node_of(f)->nodeid == nodeid &&
(f->subunit == su || (f->subunit == 0 && su == 0x7))) {
fdtv = f;
break;
}
spin_unlock_irqrestore(&node_list_lock, flags);
if (fdtv)
avc_recv(fdtv, data, length);
}
static int node_probe(struct device *dev)
{
struct unit_directory *ud =
container_of(dev, struct unit_directory, device);
struct firedtv *fdtv;
int kv_len, err;
void *kv_str;
kv_len = (ud->model_name_kv->value.leaf.len - 2) * sizeof(quadlet_t);
kv_str = CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(ud->model_name_kv);
fdtv = fdtv_alloc(dev, &fdtv_1394_backend, kv_str, kv_len);
if (!fdtv)
return -ENOMEM;
/*
* Work around a bug in udev's path_id script: Use the fw-host's dev
* instead of the unit directory's dev as parent of the input device.
*/
err = fdtv_register_rc(fdtv, dev->parent->parent);
if (err)
goto fail_free;
spin_lock_irq(&node_list_lock);
list_add_tail(&fdtv->list, &node_list);
spin_unlock_irq(&node_list_lock);
err = avc_identify_subunit(fdtv);
if (err)
goto fail;
err = fdtv_dvb_register(fdtv);
if (err)
goto fail;
avc_register_remote_control(fdtv);
return 0;
fail:
spin_lock_irq(&node_list_lock);
list_del(&fdtv->list);
spin_unlock_irq(&node_list_lock);
fdtv_unregister_rc(fdtv);
fail_free:
kfree(fdtv);
return err;
}
static int node_remove(struct device *dev)
{
struct firedtv *fdtv = dev->driver_data;
fdtv_dvb_unregister(fdtv);
spin_lock_irq(&node_list_lock);
list_del(&fdtv->list);
spin_unlock_irq(&node_list_lock);
cancel_work_sync(&fdtv->remote_ctrl_work);
fdtv_unregister_rc(fdtv);
kfree(fdtv);
return 0;
}
static int node_update(struct unit_directory *ud)
{
struct firedtv *fdtv = ud->device.driver_data;
if (fdtv->isochannel >= 0)
cmp_establish_pp_connection(fdtv, fdtv->subunit,
fdtv->isochannel);
return 0;
}
static struct hpsb_protocol_driver fdtv_driver = {
.name = "firedtv",
.update = node_update,
.driver = {
.probe = node_probe,
.remove = node_remove,
},
};
static struct hpsb_highlevel fdtv_highlevel = {
.name = "firedtv",
.fcp_request = fcp_request,
};
int __init fdtv_1394_init(struct ieee1394_device_id id_table[])
{
int ret;
hpsb_register_highlevel(&fdtv_highlevel);
fdtv_driver.id_table = id_table;
ret = hpsb_register_protocol(&fdtv_driver);
if (ret) {
printk(KERN_ERR "firedtv: failed to register protocol\n");
hpsb_unregister_highlevel(&fdtv_highlevel);
}
return ret;
}
void __exit fdtv_1394_exit(void)
{
hpsb_unregister_protocol(&fdtv_driver);
hpsb_unregister_highlevel(&fdtv_highlevel);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,260 @@
/*
* FireDTV driver (formerly known as FireSAT)
*
* Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
* Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*/
#include <linux/device.h>
#include <linux/dvb/ca.h>
#include <linux/fs.h>
#include <linux/module.h>
#include <dvbdev.h>
#include "firedtv.h"
#define EN50221_TAG_APP_INFO_ENQUIRY 0x9f8020
#define EN50221_TAG_CA_INFO_ENQUIRY 0x9f8030
#define EN50221_TAG_CA_PMT 0x9f8032
#define EN50221_TAG_ENTER_MENU 0x9f8022
static int fdtv_ca_ready(struct firedtv_tuner_status *stat)
{
return stat->ca_initialization_status == 1 &&
stat->ca_error_flag == 0 &&
stat->ca_dvb_flag == 1 &&
stat->ca_module_present_status == 1;
}
static int fdtv_get_ca_flags(struct firedtv_tuner_status *stat)
{
int flags = 0;
if (stat->ca_module_present_status == 1)
flags |= CA_CI_MODULE_PRESENT;
if (stat->ca_initialization_status == 1 &&
stat->ca_error_flag == 0 &&
stat->ca_dvb_flag == 1)
flags |= CA_CI_MODULE_READY;
return flags;
}
static int fdtv_ca_reset(struct firedtv *fdtv)
{
return avc_ca_reset(fdtv) ? -EFAULT : 0;
}
static int fdtv_ca_get_caps(void *arg)
{
struct ca_caps *cap = arg;
cap->slot_num = 1;
cap->slot_type = CA_CI;
cap->descr_num = 1;
cap->descr_type = CA_ECD;
return 0;
}
static int fdtv_ca_get_slot_info(struct firedtv *fdtv, void *arg)
{
struct firedtv_tuner_status stat;
struct ca_slot_info *slot = arg;
if (avc_tuner_status(fdtv, &stat))
return -EFAULT;
if (slot->num != 0)
return -EFAULT;
slot->type = CA_CI;
slot->flags = fdtv_get_ca_flags(&stat);
return 0;
}
static int fdtv_ca_app_info(struct firedtv *fdtv, void *arg)
{
struct ca_msg *reply = arg;
return avc_ca_app_info(fdtv, reply->msg, &reply->length) ? -EFAULT : 0;
}
static int fdtv_ca_info(struct firedtv *fdtv, void *arg)
{
struct ca_msg *reply = arg;
return avc_ca_info(fdtv, reply->msg, &reply->length) ? -EFAULT : 0;
}
static int fdtv_ca_get_mmi(struct firedtv *fdtv, void *arg)
{
struct ca_msg *reply = arg;
return avc_ca_get_mmi(fdtv, reply->msg, &reply->length) ? -EFAULT : 0;
}
static int fdtv_ca_get_msg(struct firedtv *fdtv, void *arg)
{
struct firedtv_tuner_status stat;
int err;
switch (fdtv->ca_last_command) {
case EN50221_TAG_APP_INFO_ENQUIRY:
err = fdtv_ca_app_info(fdtv, arg);
break;
case EN50221_TAG_CA_INFO_ENQUIRY:
err = fdtv_ca_info(fdtv, arg);
break;
default:
if (avc_tuner_status(fdtv, &stat))
err = -EFAULT;
else if (stat.ca_mmi == 1)
err = fdtv_ca_get_mmi(fdtv, arg);
else {
dev_info(fdtv->device, "unhandled CA message 0x%08x\n",
fdtv->ca_last_command);
err = -EFAULT;
}
}
fdtv->ca_last_command = 0;
return err;
}
static int fdtv_ca_pmt(struct firedtv *fdtv, void *arg)
{
struct ca_msg *msg = arg;
int data_pos;
int data_length;
int i;
data_pos = 4;
if (msg->msg[3] & 0x80) {
data_length = 0;
for (i = 0; i < (msg->msg[3] & 0x7f); i++)
data_length = (data_length << 8) + msg->msg[data_pos++];
} else {
data_length = msg->msg[3];
}
return avc_ca_pmt(fdtv, &msg->msg[data_pos], data_length) ? -EFAULT : 0;
}
static int fdtv_ca_send_msg(struct firedtv *fdtv, void *arg)
{
struct ca_msg *msg = arg;
int err;
/* Do we need a semaphore for this? */
fdtv->ca_last_command =
(msg->msg[0] << 16) + (msg->msg[1] << 8) + msg->msg[2];
switch (fdtv->ca_last_command) {
case EN50221_TAG_CA_PMT:
err = fdtv_ca_pmt(fdtv, arg);
break;
case EN50221_TAG_APP_INFO_ENQUIRY:
/* handled in ca_get_msg */
err = 0;
break;
case EN50221_TAG_CA_INFO_ENQUIRY:
/* handled in ca_get_msg */
err = 0;
break;
case EN50221_TAG_ENTER_MENU:
err = avc_ca_enter_menu(fdtv);
break;
default:
dev_err(fdtv->device, "unhandled CA message 0x%08x\n",
fdtv->ca_last_command);
err = -EFAULT;
}
return err;
}
static int fdtv_ca_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, void *arg)
{
struct dvb_device *dvbdev = file->private_data;
struct firedtv *fdtv = dvbdev->priv;
struct firedtv_tuner_status stat;
int err;
switch (cmd) {
case CA_RESET:
err = fdtv_ca_reset(fdtv);
break;
case CA_GET_CAP:
err = fdtv_ca_get_caps(arg);
break;
case CA_GET_SLOT_INFO:
err = fdtv_ca_get_slot_info(fdtv, arg);
break;
case CA_GET_MSG:
err = fdtv_ca_get_msg(fdtv, arg);
break;
case CA_SEND_MSG:
err = fdtv_ca_send_msg(fdtv, arg);
break;
default:
dev_info(fdtv->device, "unhandled CA ioctl %u\n", cmd);
err = -EOPNOTSUPP;
}
/* FIXME Is this necessary? */
avc_tuner_status(fdtv, &stat);
return err;
}
static unsigned int fdtv_ca_io_poll(struct file *file, poll_table *wait)
{
return POLLIN;
}
static struct file_operations fdtv_ca_fops = {
.owner = THIS_MODULE,
.ioctl = dvb_generic_ioctl,
.open = dvb_generic_open,
.release = dvb_generic_release,
.poll = fdtv_ca_io_poll,
};
static struct dvb_device fdtv_ca = {
.users = 1,
.readers = 1,
.writers = 1,
.fops = &fdtv_ca_fops,
.kernel_ioctl = fdtv_ca_ioctl,
};
int fdtv_ca_register(struct firedtv *fdtv)
{
struct firedtv_tuner_status stat;
int err;
if (avc_tuner_status(fdtv, &stat))
return -EINVAL;
if (!fdtv_ca_ready(&stat))
return -EFAULT;
err = dvb_register_device(&fdtv->adapter, &fdtv->cadev,
&fdtv_ca, fdtv, DVB_DEVICE_CA);
if (stat.ca_application_info == 0)
dev_err(fdtv->device, "CaApplicationInfo is not set\n");
if (stat.ca_date_time_request == 1)
avc_ca_get_time_date(fdtv, &fdtv->ca_time_interval);
return err;
}
void fdtv_ca_release(struct firedtv *fdtv)
{
if (fdtv->cadev)
dvb_unregister_device(fdtv->cadev);
}

View File

@ -0,0 +1,364 @@
/*
* FireDTV driver (formerly known as FireSAT)
*
* Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
* Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*/
#include <linux/bitops.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/wait.h>
#include <linux/workqueue.h>
#include <dmxdev.h>
#include <dvb_demux.h>
#include <dvbdev.h>
#include <dvb_frontend.h>
#include "firedtv.h"
static int alloc_channel(struct firedtv *fdtv)
{
int i;
for (i = 0; i < 16; i++)
if (!__test_and_set_bit(i, &fdtv->channel_active))
break;
return i;
}
static void collect_channels(struct firedtv *fdtv, int *pidc, u16 pid[])
{
int i, n;
for (i = 0, n = 0; i < 16; i++)
if (test_bit(i, &fdtv->channel_active))
pid[n++] = fdtv->channel_pid[i];
*pidc = n;
}
static inline void dealloc_channel(struct firedtv *fdtv, int i)
{
__clear_bit(i, &fdtv->channel_active);
}
int fdtv_start_feed(struct dvb_demux_feed *dvbdmxfeed)
{
struct firedtv *fdtv = dvbdmxfeed->demux->priv;
int pidc, c, ret;
u16 pids[16];
switch (dvbdmxfeed->type) {
case DMX_TYPE_TS:
case DMX_TYPE_SEC:
break;
default:
dev_err(fdtv->device, "can't start dmx feed: invalid type %u\n",
dvbdmxfeed->type);
return -EINVAL;
}
if (mutex_lock_interruptible(&fdtv->demux_mutex))
return -EINTR;
if (dvbdmxfeed->type == DMX_TYPE_TS) {
switch (dvbdmxfeed->pes_type) {
case DMX_TS_PES_VIDEO:
case DMX_TS_PES_AUDIO:
case DMX_TS_PES_TELETEXT:
case DMX_TS_PES_PCR:
case DMX_TS_PES_OTHER:
c = alloc_channel(fdtv);
break;
default:
dev_err(fdtv->device,
"can't start dmx feed: invalid pes type %u\n",
dvbdmxfeed->pes_type);
ret = -EINVAL;
goto out;
}
} else {
c = alloc_channel(fdtv);
}
if (c > 15) {
dev_err(fdtv->device, "can't start dmx feed: busy\n");
ret = -EBUSY;
goto out;
}
dvbdmxfeed->priv = (typeof(dvbdmxfeed->priv))(unsigned long)c;
fdtv->channel_pid[c] = dvbdmxfeed->pid;
collect_channels(fdtv, &pidc, pids);
if (dvbdmxfeed->pid == 8192) {
ret = avc_tuner_get_ts(fdtv);
if (ret) {
dealloc_channel(fdtv, c);
dev_err(fdtv->device, "can't get TS\n");
goto out;
}
} else {
ret = avc_tuner_set_pids(fdtv, pidc, pids);
if (ret) {
dealloc_channel(fdtv, c);
dev_err(fdtv->device, "can't set PIDs\n");
goto out;
}
}
out:
mutex_unlock(&fdtv->demux_mutex);
return ret;
}
int fdtv_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
{
struct dvb_demux *demux = dvbdmxfeed->demux;
struct firedtv *fdtv = demux->priv;
int pidc, c, ret;
u16 pids[16];
if (dvbdmxfeed->type == DMX_TYPE_TS &&
!((dvbdmxfeed->ts_type & TS_PACKET) &&
(demux->dmx.frontend->source != DMX_MEMORY_FE))) {
if (dvbdmxfeed->ts_type & TS_DECODER) {
if (dvbdmxfeed->pes_type >= DMX_TS_PES_OTHER ||
!demux->pesfilter[dvbdmxfeed->pes_type])
return -EINVAL;
demux->pids[dvbdmxfeed->pes_type] |= 0x8000;
demux->pesfilter[dvbdmxfeed->pes_type] = NULL;
}
if (!(dvbdmxfeed->ts_type & TS_DECODER &&
dvbdmxfeed->pes_type < DMX_TS_PES_OTHER))
return 0;
}
if (mutex_lock_interruptible(&fdtv->demux_mutex))
return -EINTR;
c = (unsigned long)dvbdmxfeed->priv;
dealloc_channel(fdtv, c);
collect_channels(fdtv, &pidc, pids);
ret = avc_tuner_set_pids(fdtv, pidc, pids);
mutex_unlock(&fdtv->demux_mutex);
return ret;
}
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
int fdtv_dvb_register(struct firedtv *fdtv)
{
int err;
err = dvb_register_adapter(&fdtv->adapter, fdtv_model_names[fdtv->type],
THIS_MODULE, fdtv->device, adapter_nr);
if (err < 0)
goto fail_log;
/*DMX_TS_FILTERING | DMX_SECTION_FILTERING*/
fdtv->demux.dmx.capabilities = 0;
fdtv->demux.priv = fdtv;
fdtv->demux.filternum = 16;
fdtv->demux.feednum = 16;
fdtv->demux.start_feed = fdtv_start_feed;
fdtv->demux.stop_feed = fdtv_stop_feed;
fdtv->demux.write_to_decoder = NULL;
err = dvb_dmx_init(&fdtv->demux);
if (err)
goto fail_unreg_adapter;
fdtv->dmxdev.filternum = 16;
fdtv->dmxdev.demux = &fdtv->demux.dmx;
fdtv->dmxdev.capabilities = 0;
err = dvb_dmxdev_init(&fdtv->dmxdev, &fdtv->adapter);
if (err)
goto fail_dmx_release;
fdtv->frontend.source = DMX_FRONTEND_0;
err = fdtv->demux.dmx.add_frontend(&fdtv->demux.dmx, &fdtv->frontend);
if (err)
goto fail_dmxdev_release;
err = fdtv->demux.dmx.connect_frontend(&fdtv->demux.dmx,
&fdtv->frontend);
if (err)
goto fail_rem_frontend;
dvb_net_init(&fdtv->adapter, &fdtv->dvbnet, &fdtv->demux.dmx);
fdtv_frontend_init(fdtv);
err = dvb_register_frontend(&fdtv->adapter, &fdtv->fe);
if (err)
goto fail_net_release;
err = fdtv_ca_register(fdtv);
if (err)
dev_info(fdtv->device,
"Conditional Access Module not enabled\n");
return 0;
fail_net_release:
dvb_net_release(&fdtv->dvbnet);
fdtv->demux.dmx.close(&fdtv->demux.dmx);
fail_rem_frontend:
fdtv->demux.dmx.remove_frontend(&fdtv->demux.dmx, &fdtv->frontend);
fail_dmxdev_release:
dvb_dmxdev_release(&fdtv->dmxdev);
fail_dmx_release:
dvb_dmx_release(&fdtv->demux);
fail_unreg_adapter:
dvb_unregister_adapter(&fdtv->adapter);
fail_log:
dev_err(fdtv->device, "DVB initialization failed\n");
return err;
}
void fdtv_dvb_unregister(struct firedtv *fdtv)
{
fdtv_ca_release(fdtv);
dvb_unregister_frontend(&fdtv->fe);
dvb_net_release(&fdtv->dvbnet);
fdtv->demux.dmx.close(&fdtv->demux.dmx);
fdtv->demux.dmx.remove_frontend(&fdtv->demux.dmx, &fdtv->frontend);
dvb_dmxdev_release(&fdtv->dmxdev);
dvb_dmx_release(&fdtv->demux);
dvb_unregister_adapter(&fdtv->adapter);
}
const char *fdtv_model_names[] = {
[FIREDTV_UNKNOWN] = "unknown type",
[FIREDTV_DVB_S] = "FireDTV S/CI",
[FIREDTV_DVB_C] = "FireDTV C/CI",
[FIREDTV_DVB_T] = "FireDTV T/CI",
[FIREDTV_DVB_S2] = "FireDTV S2 ",
};
struct firedtv *fdtv_alloc(struct device *dev,
const struct firedtv_backend *backend,
const char *name, size_t name_len)
{
struct firedtv *fdtv;
int i;
fdtv = kzalloc(sizeof(*fdtv), GFP_KERNEL);
if (!fdtv)
return NULL;
dev->driver_data = fdtv;
fdtv->device = dev;
fdtv->isochannel = -1;
fdtv->voltage = 0xff;
fdtv->tone = 0xff;
fdtv->backend = backend;
mutex_init(&fdtv->avc_mutex);
init_waitqueue_head(&fdtv->avc_wait);
fdtv->avc_reply_received = true;
mutex_init(&fdtv->demux_mutex);
INIT_WORK(&fdtv->remote_ctrl_work, avc_remote_ctrl_work);
for (i = ARRAY_SIZE(fdtv_model_names); --i; )
if (strlen(fdtv_model_names[i]) <= name_len &&
strncmp(name, fdtv_model_names[i], name_len) == 0)
break;
fdtv->type = i;
return fdtv;
}
#define MATCH_FLAGS (IEEE1394_MATCH_VENDOR_ID | IEEE1394_MATCH_MODEL_ID | \
IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION)
#define DIGITAL_EVERYWHERE_OUI 0x001287
#define AVC_UNIT_SPEC_ID_ENTRY 0x00a02d
#define AVC_SW_VERSION_ENTRY 0x010001
static struct ieee1394_device_id fdtv_id_table[] = {
{
/* FloppyDTV S/CI and FloppyDTV S2 */
.match_flags = MATCH_FLAGS,
.vendor_id = DIGITAL_EVERYWHERE_OUI,
.model_id = 0x000024,
.specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
.version = AVC_SW_VERSION_ENTRY,
}, {
/* FloppyDTV T/CI */
.match_flags = MATCH_FLAGS,
.vendor_id = DIGITAL_EVERYWHERE_OUI,
.model_id = 0x000025,
.specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
.version = AVC_SW_VERSION_ENTRY,
}, {
/* FloppyDTV C/CI */
.match_flags = MATCH_FLAGS,
.vendor_id = DIGITAL_EVERYWHERE_OUI,
.model_id = 0x000026,
.specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
.version = AVC_SW_VERSION_ENTRY,
}, {
/* FireDTV S/CI and FloppyDTV S2 */
.match_flags = MATCH_FLAGS,
.vendor_id = DIGITAL_EVERYWHERE_OUI,
.model_id = 0x000034,
.specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
.version = AVC_SW_VERSION_ENTRY,
}, {
/* FireDTV T/CI */
.match_flags = MATCH_FLAGS,
.vendor_id = DIGITAL_EVERYWHERE_OUI,
.model_id = 0x000035,
.specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
.version = AVC_SW_VERSION_ENTRY,
}, {
/* FireDTV C/CI */
.match_flags = MATCH_FLAGS,
.vendor_id = DIGITAL_EVERYWHERE_OUI,
.model_id = 0x000036,
.specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
.version = AVC_SW_VERSION_ENTRY,
}, {}
};
MODULE_DEVICE_TABLE(ieee1394, fdtv_id_table);
static int __init fdtv_init(void)
{
return fdtv_1394_init(fdtv_id_table);
}
static void __exit fdtv_exit(void)
{
fdtv_1394_exit();
}
module_init(fdtv_init);
module_exit(fdtv_exit);
MODULE_AUTHOR("Andreas Monitzer <andy@monitzer.com>");
MODULE_AUTHOR("Ben Backx <ben@bbackx.com>");
MODULE_DESCRIPTION("FireDTV DVB Driver");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("FireDTV DVB");

View File

@ -0,0 +1,247 @@
/*
* FireDTV driver (formerly known as FireSAT)
*
* Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
* Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*/
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/types.h>
#include <dvb_frontend.h>
#include "firedtv.h"
static int fdtv_dvb_init(struct dvb_frontend *fe)
{
struct firedtv *fdtv = fe->sec_priv;
int err;
/* FIXME - allocate free channel at IRM */
fdtv->isochannel = fdtv->adapter.num;
err = cmp_establish_pp_connection(fdtv, fdtv->subunit,
fdtv->isochannel);
if (err) {
dev_err(fdtv->device,
"could not establish point to point connection\n");
return err;
}
return fdtv->backend->start_iso(fdtv);
}
static int fdtv_sleep(struct dvb_frontend *fe)
{
struct firedtv *fdtv = fe->sec_priv;
fdtv->backend->stop_iso(fdtv);
cmp_break_pp_connection(fdtv, fdtv->subunit, fdtv->isochannel);
fdtv->isochannel = -1;
return 0;
}
#define LNBCONTROL_DONTCARE 0xff
static int fdtv_diseqc_send_master_cmd(struct dvb_frontend *fe,
struct dvb_diseqc_master_cmd *cmd)
{
struct firedtv *fdtv = fe->sec_priv;
return avc_lnb_control(fdtv, LNBCONTROL_DONTCARE, LNBCONTROL_DONTCARE,
LNBCONTROL_DONTCARE, 1, cmd);
}
static int fdtv_diseqc_send_burst(struct dvb_frontend *fe,
fe_sec_mini_cmd_t minicmd)
{
return 0;
}
static int fdtv_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
{
struct firedtv *fdtv = fe->sec_priv;
fdtv->tone = tone;
return 0;
}
static int fdtv_set_voltage(struct dvb_frontend *fe,
fe_sec_voltage_t voltage)
{
struct firedtv *fdtv = fe->sec_priv;
fdtv->voltage = voltage;
return 0;
}
static int fdtv_read_status(struct dvb_frontend *fe, fe_status_t *status)
{
struct firedtv *fdtv = fe->sec_priv;
struct firedtv_tuner_status stat;
if (avc_tuner_status(fdtv, &stat))
return -EINVAL;
if (stat.no_rf)
*status = 0;
else
*status = FE_HAS_SIGNAL | FE_HAS_VITERBI | FE_HAS_SYNC |
FE_HAS_CARRIER | FE_HAS_LOCK;
return 0;
}
static int fdtv_read_ber(struct dvb_frontend *fe, u32 *ber)
{
struct firedtv *fdtv = fe->sec_priv;
struct firedtv_tuner_status stat;
if (avc_tuner_status(fdtv, &stat))
return -EINVAL;
*ber = stat.ber;
return 0;
}
static int fdtv_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
{
struct firedtv *fdtv = fe->sec_priv;
struct firedtv_tuner_status stat;
if (avc_tuner_status(fdtv, &stat))
return -EINVAL;
*strength = stat.signal_strength << 8;
return 0;
}
static int fdtv_read_snr(struct dvb_frontend *fe, u16 *snr)
{
struct firedtv *fdtv = fe->sec_priv;
struct firedtv_tuner_status stat;
if (avc_tuner_status(fdtv, &stat))
return -EINVAL;
/* C/N[dB] = -10 * log10(snr / 65535) */
*snr = stat.carrier_noise_ratio * 257;
return 0;
}
static int fdtv_read_uncorrected_blocks(struct dvb_frontend *fe, u32 *ucblocks)
{
return -EOPNOTSUPP;
}
#define ACCEPTED 0x9
static int fdtv_set_frontend(struct dvb_frontend *fe,
struct dvb_frontend_parameters *params)
{
struct firedtv *fdtv = fe->sec_priv;
/* FIXME: avc_tuner_dsd never returns ACCEPTED. Check status? */
if (avc_tuner_dsd(fdtv, params) != ACCEPTED)
return -EINVAL;
else
return 0; /* not sure of this... */
}
static int fdtv_get_frontend(struct dvb_frontend *fe,
struct dvb_frontend_parameters *params)
{
return -EOPNOTSUPP;
}
void fdtv_frontend_init(struct firedtv *fdtv)
{
struct dvb_frontend_ops *ops = &fdtv->fe.ops;
struct dvb_frontend_info *fi = &ops->info;
ops->init = fdtv_dvb_init;
ops->sleep = fdtv_sleep;
ops->set_frontend = fdtv_set_frontend;
ops->get_frontend = fdtv_get_frontend;
ops->read_status = fdtv_read_status;
ops->read_ber = fdtv_read_ber;
ops->read_signal_strength = fdtv_read_signal_strength;
ops->read_snr = fdtv_read_snr;
ops->read_ucblocks = fdtv_read_uncorrected_blocks;
ops->diseqc_send_master_cmd = fdtv_diseqc_send_master_cmd;
ops->diseqc_send_burst = fdtv_diseqc_send_burst;
ops->set_tone = fdtv_set_tone;
ops->set_voltage = fdtv_set_voltage;
switch (fdtv->type) {
case FIREDTV_DVB_S:
case FIREDTV_DVB_S2:
fi->type = FE_QPSK;
fi->frequency_min = 950000;
fi->frequency_max = 2150000;
fi->frequency_stepsize = 125;
fi->symbol_rate_min = 1000000;
fi->symbol_rate_max = 40000000;
fi->caps = FE_CAN_INVERSION_AUTO |
FE_CAN_FEC_1_2 |
FE_CAN_FEC_2_3 |
FE_CAN_FEC_3_4 |
FE_CAN_FEC_5_6 |
FE_CAN_FEC_7_8 |
FE_CAN_FEC_AUTO |
FE_CAN_QPSK;
break;
case FIREDTV_DVB_C:
fi->type = FE_QAM;
fi->frequency_min = 47000000;
fi->frequency_max = 866000000;
fi->frequency_stepsize = 62500;
fi->symbol_rate_min = 870000;
fi->symbol_rate_max = 6900000;
fi->caps = FE_CAN_INVERSION_AUTO |
FE_CAN_QAM_16 |
FE_CAN_QAM_32 |
FE_CAN_QAM_64 |
FE_CAN_QAM_128 |
FE_CAN_QAM_256 |
FE_CAN_QAM_AUTO;
break;
case FIREDTV_DVB_T:
fi->type = FE_OFDM;
fi->frequency_min = 49000000;
fi->frequency_max = 861000000;
fi->frequency_stepsize = 62500;
fi->caps = FE_CAN_INVERSION_AUTO |
FE_CAN_FEC_2_3 |
FE_CAN_TRANSMISSION_MODE_AUTO |
FE_CAN_GUARD_INTERVAL_AUTO |
FE_CAN_HIERARCHY_AUTO;
break;
default:
dev_err(fdtv->device, "no frontend for model type %d\n",
fdtv->type);
}
strcpy(fi->name, fdtv_model_names[fdtv->type]);
fdtv->fe.dvb = &fdtv->adapter;
fdtv->fe.sec_priv = fdtv;
}

View File

@ -0,0 +1,190 @@
/*
* FireDTV driver (formerly known as FireSAT)
*
* Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*/
#include <linux/bitops.h>
#include <linux/input.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/types.h>
#include "firedtv.h"
/* fixed table with older keycodes, geared towards MythTV */
const static u16 oldtable[] = {
/* code from device: 0x4501...0x451f */
KEY_ESC,
KEY_F9,
KEY_1,
KEY_2,
KEY_3,
KEY_4,
KEY_5,
KEY_6,
KEY_7,
KEY_8,
KEY_9,
KEY_I,
KEY_0,
KEY_ENTER,
KEY_RED,
KEY_UP,
KEY_GREEN,
KEY_F10,
KEY_SPACE,
KEY_F11,
KEY_YELLOW,
KEY_DOWN,
KEY_BLUE,
KEY_Z,
KEY_P,
KEY_PAGEDOWN,
KEY_LEFT,
KEY_W,
KEY_RIGHT,
KEY_P,
KEY_M,
/* code from device: 0x4540...0x4542 */
KEY_R,
KEY_V,
KEY_C,
};
/* user-modifiable table for a remote as sold in 2008 */
const static u16 keytable[] = {
/* code from device: 0x0300...0x031f */
[0x00] = KEY_POWER,
[0x01] = KEY_SLEEP,
[0x02] = KEY_STOP,
[0x03] = KEY_OK,
[0x04] = KEY_RIGHT,
[0x05] = KEY_1,
[0x06] = KEY_2,
[0x07] = KEY_3,
[0x08] = KEY_LEFT,
[0x09] = KEY_4,
[0x0a] = KEY_5,
[0x0b] = KEY_6,
[0x0c] = KEY_UP,
[0x0d] = KEY_7,
[0x0e] = KEY_8,
[0x0f] = KEY_9,
[0x10] = KEY_DOWN,
[0x11] = KEY_TITLE, /* "OSD" - fixme */
[0x12] = KEY_0,
[0x13] = KEY_F20, /* "16:9" - fixme */
[0x14] = KEY_SCREEN, /* "FULL" - fixme */
[0x15] = KEY_MUTE,
[0x16] = KEY_SUBTITLE,
[0x17] = KEY_RECORD,
[0x18] = KEY_TEXT,
[0x19] = KEY_AUDIO,
[0x1a] = KEY_RED,
[0x1b] = KEY_PREVIOUS,
[0x1c] = KEY_REWIND,
[0x1d] = KEY_PLAYPAUSE,
[0x1e] = KEY_NEXT,
[0x1f] = KEY_VOLUMEUP,
/* code from device: 0x0340...0x0354 */
[0x20] = KEY_CHANNELUP,
[0x21] = KEY_F21, /* "4:3" - fixme */
[0x22] = KEY_TV,
[0x23] = KEY_DVD,
[0x24] = KEY_VCR,
[0x25] = KEY_AUX,
[0x26] = KEY_GREEN,
[0x27] = KEY_YELLOW,
[0x28] = KEY_BLUE,
[0x29] = KEY_CHANNEL, /* "CH.LIST" */
[0x2a] = KEY_VENDOR, /* "CI" - fixme */
[0x2b] = KEY_VOLUMEDOWN,
[0x2c] = KEY_CHANNELDOWN,
[0x2d] = KEY_LAST,
[0x2e] = KEY_INFO,
[0x2f] = KEY_FORWARD,
[0x30] = KEY_LIST,
[0x31] = KEY_FAVORITES,
[0x32] = KEY_MENU,
[0x33] = KEY_EPG,
[0x34] = KEY_EXIT,
};
int fdtv_register_rc(struct firedtv *fdtv, struct device *dev)
{
struct input_dev *idev;
int i, err;
idev = input_allocate_device();
if (!idev)
return -ENOMEM;
fdtv->remote_ctrl_dev = idev;
idev->name = "FireDTV remote control";
idev->dev.parent = dev;
idev->evbit[0] = BIT_MASK(EV_KEY);
idev->keycode = kmemdup(keytable, sizeof(keytable), GFP_KERNEL);
if (!idev->keycode) {
err = -ENOMEM;
goto fail;
}
idev->keycodesize = sizeof(keytable[0]);
idev->keycodemax = ARRAY_SIZE(keytable);
for (i = 0; i < ARRAY_SIZE(keytable); i++)
set_bit(keytable[i], idev->keybit);
err = input_register_device(idev);
if (err)
goto fail_free_keymap;
return 0;
fail_free_keymap:
kfree(idev->keycode);
fail:
input_free_device(idev);
return err;
}
void fdtv_unregister_rc(struct firedtv *fdtv)
{
kfree(fdtv->remote_ctrl_dev->keycode);
input_unregister_device(fdtv->remote_ctrl_dev);
}
void fdtv_handle_rc(struct firedtv *fdtv, unsigned int code)
{
u16 *keycode = fdtv->remote_ctrl_dev->keycode;
if (code >= 0x0300 && code <= 0x031f)
code = keycode[code - 0x0300];
else if (code >= 0x0340 && code <= 0x0354)
code = keycode[code - 0x0320];
else if (code >= 0x4501 && code <= 0x451f)
code = oldtable[code - 0x4501];
else if (code >= 0x4540 && code <= 0x4542)
code = oldtable[code - 0x4521];
else {
printk(KERN_DEBUG "firedtv: invalid key code 0x%04x "
"from remote control\n", code);
return;
}
input_report_key(fdtv->remote_ctrl_dev, code, 1);
input_report_key(fdtv->remote_ctrl_dev, code, 0);
}

Some files were not shown because too many files have changed in this diff Show More