Merge from Linus' tree.
This commit is contained in:
commit
e5baa396af
|
@ -1105,7 +1105,7 @@ static struct block_device_operations opt_fops = {
|
|||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Function names as strings (__func__).
|
||||
Function names as strings (__FUNCTION__).
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
Device-mapper snapshot support
|
||||
==============================
|
||||
|
||||
Device-mapper allows you, without massive data copying:
|
||||
|
||||
*) To create snapshots of any block device i.e. mountable, saved states of
|
||||
the block device which are also writable without interfering with the
|
||||
original content;
|
||||
*) To create device "forks", i.e. multiple different versions of the
|
||||
same data stream.
|
||||
|
||||
|
||||
In both cases, dm copies only the chunks of data that get changed and
|
||||
uses a separate copy-on-write (COW) block device for storage.
|
||||
|
||||
|
||||
There are two dm targets available: snapshot and snapshot-origin.
|
||||
|
||||
*) snapshot-origin <origin>
|
||||
|
||||
which will normally have one or more snapshots based on it.
|
||||
You must create the snapshot-origin device before you can create snapshots.
|
||||
Reads will be mapped directly to the backing device. For each write, the
|
||||
original data will be saved in the <COW device> of each snapshot to keep
|
||||
its visible content unchanged, at least until the <COW device> fills up.
|
||||
|
||||
|
||||
*) snapshot <origin> <COW device> <persistent?> <chunksize>
|
||||
|
||||
A snapshot is created of the <origin> block device. Changed chunks of
|
||||
<chunksize> sectors will be stored on the <COW device>. Writes will
|
||||
only go to the <COW device>. Reads will come from the <COW device> or
|
||||
from <origin> for unchanged data. <COW device> will often be
|
||||
smaller than the origin and if it fills up the snapshot will become
|
||||
useless and be disabled, returning errors. So it is important to monitor
|
||||
the amount of free space and expand the <COW device> before it fills up.
|
||||
|
||||
<persistent?> is P (Persistent) or N (Not persistent - will not survive
|
||||
after reboot).
|
||||
|
||||
|
||||
How this is used by LVM2
|
||||
========================
|
||||
When you create the first LVM2 snapshot of a volume, four dm devices are used:
|
||||
|
||||
1) a device containing the original mapping table of the source volume;
|
||||
2) a device used as the <COW device>;
|
||||
3) a "snapshot" device, combining #1 and #2, which is the visible snapshot
|
||||
volume;
|
||||
4) the "original" volume (which uses the device number used by the original
|
||||
source volume), whose table is replaced by a "snapshot-origin" mapping
|
||||
from device #1.
|
||||
|
||||
A fixed naming scheme is used, so with the following commands:
|
||||
|
||||
lvcreate -L 1G -n base volumeGroup
|
||||
lvcreate -L 100M --snapshot -n snap volumeGroup/base
|
||||
|
||||
we'll have this situation (with volumes in above order):
|
||||
|
||||
# dmsetup table|grep volumeGroup
|
||||
|
||||
volumeGroup-base-real: 0 2097152 linear 8:19 384
|
||||
volumeGroup-snap-cow: 0 204800 linear 8:19 2097536
|
||||
volumeGroup-snap: 0 2097152 snapshot 254:11 254:12 P 16
|
||||
volumeGroup-base: 0 2097152 snapshot-origin 254:11
|
||||
|
||||
# ls -lL /dev/mapper/volumeGroup-*
|
||||
brw------- 1 root root 254, 11 29 ago 18:15 /dev/mapper/volumeGroup-base-real
|
||||
brw------- 1 root root 254, 12 29 ago 18:15 /dev/mapper/volumeGroup-snap-cow
|
||||
brw------- 1 root root 254, 13 29 ago 18:15 /dev/mapper/volumeGroup-snap
|
||||
brw------- 1 root root 254, 10 29 ago 18:14 /dev/mapper/volumeGroup-base
|
||||
|
|
@ -51,9 +51,9 @@ or you don't get any checking at all.
|
|||
Where to get sparse
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
With BK, you can just get it from
|
||||
With git, you can just get it from
|
||||
|
||||
bk://sparse.bkbits.net/sparse
|
||||
rsync://rsync.kernel.org/pub/scm/devel/sparse/sparse.git
|
||||
|
||||
and DaveJ has tar-balls at
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
Revised: 2000-Dec-05.
|
||||
Again: 2002-Jul-06
|
||||
Again: 2005-Sep-19
|
||||
|
||||
NOTE:
|
||||
|
||||
|
@ -18,8 +19,8 @@ called USB Request Block, or URB for short.
|
|||
and deliver the data and status back.
|
||||
|
||||
- Execution of an URB is inherently an asynchronous operation, i.e. the
|
||||
usb_submit_urb(urb) call returns immediately after it has successfully queued
|
||||
the requested action.
|
||||
usb_submit_urb(urb) call returns immediately after it has successfully
|
||||
queued the requested action.
|
||||
|
||||
- Transfers for one URB can be canceled with usb_unlink_urb(urb) at any time.
|
||||
|
||||
|
@ -94,8 +95,9 @@ To free an URB, use
|
|||
|
||||
void usb_free_urb(struct urb *urb)
|
||||
|
||||
You may not free an urb that you've submitted, but which hasn't yet been
|
||||
returned to you in a completion callback.
|
||||
You may free an urb that you've submitted, but which hasn't yet been
|
||||
returned to you in a completion callback. It will automatically be
|
||||
deallocated when it is no longer in use.
|
||||
|
||||
|
||||
1.4. What has to be filled in?
|
||||
|
@ -145,30 +147,36 @@ to get seamless ISO streaming.
|
|||
|
||||
1.6. How to cancel an already running URB?
|
||||
|
||||
For an URB which you've submitted, but which hasn't been returned to
|
||||
your driver by the host controller, call
|
||||
There are two ways to cancel an URB you've submitted but which hasn't
|
||||
been returned to your driver yet. For an asynchronous cancel, call
|
||||
|
||||
int usb_unlink_urb(struct urb *urb)
|
||||
|
||||
It removes the urb from the internal list and frees all allocated
|
||||
HW descriptors. The status is changed to reflect unlinking. After
|
||||
usb_unlink_urb() returns with that status code, you can free the URB
|
||||
with usb_free_urb().
|
||||
HW descriptors. The status is changed to reflect unlinking. Note
|
||||
that the URB will not normally have finished when usb_unlink_urb()
|
||||
returns; you must still wait for the completion handler to be called.
|
||||
|
||||
There is also an asynchronous unlink mode. To use this, set the
|
||||
the URB_ASYNC_UNLINK flag in urb->transfer flags before calling
|
||||
usb_unlink_urb(). When using async unlinking, the URB will not
|
||||
normally be unlinked when usb_unlink_urb() returns. Instead, wait
|
||||
for the completion handler to be called.
|
||||
To cancel an URB synchronously, call
|
||||
|
||||
void usb_kill_urb(struct urb *urb)
|
||||
|
||||
It does everything usb_unlink_urb does, and in addition it waits
|
||||
until after the URB has been returned and the completion handler
|
||||
has finished. It also marks the URB as temporarily unusable, so
|
||||
that if the completion handler or anyone else tries to resubmit it
|
||||
they will get a -EPERM error. Thus you can be sure that when
|
||||
usb_kill_urb() returns, the URB is totally idle.
|
||||
|
||||
|
||||
1.7. What about the completion handler?
|
||||
|
||||
The handler is of the following type:
|
||||
|
||||
typedef void (*usb_complete_t)(struct urb *);
|
||||
typedef void (*usb_complete_t)(struct urb *, struct pt_regs *)
|
||||
|
||||
i.e. it gets just the URB that caused the completion call.
|
||||
I.e., it gets the URB that caused the completion call, plus the
|
||||
register values at the time of the corresponding interrupt (if any).
|
||||
In the completion handler, you should have a look at urb->status to
|
||||
detect any USB errors. Since the context parameter is included in the URB,
|
||||
you can pass information to the completion handler.
|
||||
|
@ -176,17 +184,11 @@ you can pass information to the completion handler.
|
|||
Note that even when an error (or unlink) is reported, data may have been
|
||||
transferred. That's because USB transfers are packetized; it might take
|
||||
sixteen packets to transfer your 1KByte buffer, and ten of them might
|
||||
have transferred succesfully before the completion is called.
|
||||
have transferred succesfully before the completion was called.
|
||||
|
||||
|
||||
NOTE: ***** WARNING *****
|
||||
Don't use urb->dev field in your completion handler; it's cleared
|
||||
as part of giving urbs back to drivers. (Addressing an issue with
|
||||
ownership of periodic URBs, which was otherwise ambiguous.) Instead,
|
||||
use urb->context to hold all the data your driver needs.
|
||||
|
||||
NOTE: ***** WARNING *****
|
||||
Also, NEVER SLEEP IN A COMPLETION HANDLER. These are normally called
|
||||
NEVER SLEEP IN A COMPLETION HANDLER. These are normally called
|
||||
during hardware interrupt processing. If you can, defer substantial
|
||||
work to a tasklet (bottom half) to keep system latencies low. You'll
|
||||
probably need to use spinlocks to protect data structures you manipulate
|
||||
|
@ -229,24 +231,10 @@ ISO data with some other event stream.
|
|||
Interrupt transfers, like isochronous transfers, are periodic, and happen
|
||||
in intervals that are powers of two (1, 2, 4 etc) units. Units are frames
|
||||
for full and low speed devices, and microframes for high speed ones.
|
||||
|
||||
Currently, after you submit one interrupt URB, that urb is owned by the
|
||||
host controller driver until you cancel it with usb_unlink_urb(). You
|
||||
may unlink interrupt urbs in their completion handlers, if you need to.
|
||||
|
||||
After a transfer completion is called, the URB is automagically resubmitted.
|
||||
THIS BEHAVIOR IS EXPECTED TO BE REMOVED!!
|
||||
|
||||
Interrupt transfers may only send (or receive) the "maxpacket" value for
|
||||
the given interrupt endpoint; if you need more data, you will need to
|
||||
copy that data out of (or into) another buffer. Similarly, you can't
|
||||
queue interrupt transfers.
|
||||
THESE RESTRICTIONS ARE EXPECTED TO BE REMOVED!!
|
||||
|
||||
Note that this automagic resubmission model does make it awkward to use
|
||||
interrupt OUT transfers. The portable solution involves unlinking those
|
||||
OUT urbs after the data is transferred, and perhaps submitting a final
|
||||
URB for a short packet.
|
||||
|
||||
The usb_submit_urb() call modifies urb->interval to the implemented interval
|
||||
value that is less than or equal to the requested interval value.
|
||||
|
||||
In Linux 2.6, unlike earlier versions, interrupt URBs are not automagically
|
||||
restarted when they complete. They end when the completion handler is
|
||||
called, just like other URBs. If you want an interrupt URB to be restarted,
|
||||
your completion handler must resubmit it.
|
||||
|
|
20
MAINTAINERS
20
MAINTAINERS
|
@ -1063,8 +1063,6 @@ M: wli@holomorphy.com
|
|||
S: Maintained
|
||||
|
||||
I2C SUBSYSTEM
|
||||
P: Greg Kroah-Hartman
|
||||
M: greg@kroah.com
|
||||
P: Jean Delvare
|
||||
M: khali@linux-fr.org
|
||||
L: lm-sensors@lm-sensors.org
|
||||
|
@ -1404,6 +1402,18 @@ L: linux-kernel@vger.kernel.org
|
|||
L: fastboot@osdl.org
|
||||
S: Maintained
|
||||
|
||||
KPROBES
|
||||
P: Prasanna S Panchamukhi
|
||||
M: prasanna@in.ibm.com
|
||||
P: Ananth N Mavinakayanahalli
|
||||
M: ananth@in.ibm.com
|
||||
P: Anil S Keshavamurthy
|
||||
M: anil.s.keshavamurthy@intel.com
|
||||
P: David S. Miller
|
||||
M: davem@davemloft.net
|
||||
L: linux-kernel@vger.kernel.org
|
||||
S: Maintained
|
||||
|
||||
LANMEDIA WAN CARD DRIVER
|
||||
P: Andrew Stanley-Jones
|
||||
M: asj@lanmedia.com
|
||||
|
@ -2266,6 +2276,12 @@ M: kristen.c.accardi@intel.com
|
|||
L: pcihpd-discuss@lists.sourceforge.net
|
||||
S: Maintained
|
||||
|
||||
SKGE, SKY2 10/100/1000 GIGABIT ETHERNET DRIVERS
|
||||
P: Stephen Hemminger
|
||||
M: shemminger@osdl.org
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
|
||||
SPARC (sparc32):
|
||||
P: William L. Irwin
|
||||
M: wli@holomorphy.com
|
||||
|
|
2
Makefile
2
Makefile
|
@ -1,7 +1,7 @@
|
|||
VERSION = 2
|
||||
PATCHLEVEL = 6
|
||||
SUBLEVEL = 14
|
||||
EXTRAVERSION =-rc1
|
||||
EXTRAVERSION =-rc2
|
||||
NAME=Affluent Albatross
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
|
9
README
9
README
|
@ -149,6 +149,9 @@ CONFIGURING the kernel:
|
|||
"make gconfig" X windows (Gtk) based configuration tool.
|
||||
"make oldconfig" Default all questions based on the contents of
|
||||
your existing ./.config file.
|
||||
"make silentoldconfig"
|
||||
Like above, but avoids cluttering the screen
|
||||
with questions already answered.
|
||||
|
||||
NOTES on "make config":
|
||||
- having unnecessary drivers will make the kernel bigger, and can
|
||||
|
@ -169,9 +172,6 @@ CONFIGURING the kernel:
|
|||
should probably answer 'n' to the questions for
|
||||
"development", "experimental", or "debugging" features.
|
||||
|
||||
- Check the top Makefile for further site-dependent configuration
|
||||
(default SVGA mode etc).
|
||||
|
||||
COMPILING the kernel:
|
||||
|
||||
- Make sure you have gcc 2.95.3 available.
|
||||
|
@ -199,6 +199,9 @@ COMPILING the kernel:
|
|||
are installing a new kernel with the same version number as your
|
||||
working kernel, make a backup of your modules directory before you
|
||||
do a "make modules_install".
|
||||
Alternatively, before compiling, use the kernel config option
|
||||
"LOCALVERSION" to append a unique suffix to the regular kernel version.
|
||||
LOCALVERSION can be set in the "General Setup" menu.
|
||||
|
||||
- In order to boot your new kernel, you'll need to copy the kernel
|
||||
image (e.g. .../linux/arch/i386/boot/bzImage after compilation)
|
||||
|
|
|
@ -127,6 +127,10 @@ common_shutdown_1(void *generic_ptr)
|
|||
/* If booted from SRM, reset some of the original environment. */
|
||||
if (alpha_using_srm) {
|
||||
#ifdef CONFIG_DUMMY_CONSOLE
|
||||
/* If we've gotten here after SysRq-b, leave interrupt
|
||||
context before taking over the console. */
|
||||
if (in_interrupt())
|
||||
irq_exit();
|
||||
/* This has the effect of resetting the VGA video origin. */
|
||||
take_over_console(&dummy_con, 0, MAX_NR_CONSOLES-1, 1);
|
||||
#endif
|
||||
|
|
|
@ -394,6 +394,22 @@ clipper_init_irq(void)
|
|||
* 10 64 bit PCI option slot 3 (not bus 0)
|
||||
*/
|
||||
|
||||
static int __init
|
||||
isa_irq_fixup(struct pci_dev *dev, int irq)
|
||||
{
|
||||
u8 irq8;
|
||||
|
||||
if (irq > 0)
|
||||
return irq;
|
||||
|
||||
/* This interrupt is routed via ISA bridge, so we'll
|
||||
just have to trust whatever value the console might
|
||||
have assigned. */
|
||||
pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq8);
|
||||
|
||||
return irq8 & 0xf;
|
||||
}
|
||||
|
||||
static int __init
|
||||
dp264_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
|
||||
{
|
||||
|
@ -407,25 +423,13 @@ dp264_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
|
|||
{ 16+ 3, 16+ 3, 16+ 2, 16+ 1, 16+ 0} /* IdSel 10 slot 3 */
|
||||
};
|
||||
const long min_idsel = 5, max_idsel = 10, irqs_per_slot = 5;
|
||||
|
||||
struct pci_controller *hose = dev->sysdata;
|
||||
int irq = COMMON_TABLE_LOOKUP;
|
||||
|
||||
if (irq > 0) {
|
||||
if (irq > 0)
|
||||
irq += 16 * hose->index;
|
||||
} else {
|
||||
/* ??? The Contaq IDE controller on the ISA bridge uses
|
||||
"legacy" interrupts 14 and 15. I don't know if anything
|
||||
can wind up at the same slot+pin on hose1, so we'll
|
||||
just have to trust whatever value the console might
|
||||
have assigned. */
|
||||
|
||||
u8 irq8;
|
||||
pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq8);
|
||||
irq = irq8;
|
||||
}
|
||||
|
||||
return irq;
|
||||
return isa_irq_fixup(dev, irq);
|
||||
}
|
||||
|
||||
static int __init
|
||||
|
@ -453,7 +457,8 @@ monet_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
|
|||
{ 24, 24, 25, 26, 27} /* IdSel 15 slot 5 PCI2*/
|
||||
};
|
||||
const long min_idsel = 3, max_idsel = 15, irqs_per_slot = 5;
|
||||
return COMMON_TABLE_LOOKUP;
|
||||
|
||||
return isa_irq_fixup(dev, COMMON_TABLE_LOOKUP);
|
||||
}
|
||||
|
||||
static u8 __init
|
||||
|
@ -507,7 +512,8 @@ webbrick_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
|
|||
{ 47, 47, 46, 45, 44}, /* IdSel 17 slot 3 */
|
||||
};
|
||||
const long min_idsel = 7, max_idsel = 17, irqs_per_slot = 5;
|
||||
return COMMON_TABLE_LOOKUP;
|
||||
|
||||
return isa_irq_fixup(dev, COMMON_TABLE_LOOKUP);
|
||||
}
|
||||
|
||||
static int __init
|
||||
|
@ -524,14 +530,13 @@ clipper_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
|
|||
{ -1, -1, -1, -1, -1} /* IdSel 7 ISA Bridge */
|
||||
};
|
||||
const long min_idsel = 1, max_idsel = 7, irqs_per_slot = 5;
|
||||
|
||||
struct pci_controller *hose = dev->sysdata;
|
||||
int irq = COMMON_TABLE_LOOKUP;
|
||||
|
||||
if (irq > 0)
|
||||
irq += 16 * hose->index;
|
||||
|
||||
return irq;
|
||||
return isa_irq_fixup(dev, irq);
|
||||
}
|
||||
|
||||
static void __init
|
||||
|
|
|
@ -256,5 +256,5 @@ asmlinkage void ofw_init(ofw_handle_t o, int *nomr, int *pointer)
|
|||
temp[11]='\0';
|
||||
mem_len = OF_getproplen(o,phandle, temp);
|
||||
OF_getprop(o,phandle, temp, buffer, mem_len);
|
||||
(unsigned char) pointer[32] = ((unsigned char *) buffer)[mem_len-2];
|
||||
* ((unsigned char *) &pointer[32]) = ((unsigned char *) buffer)[mem_len-2];
|
||||
}
|
||||
|
|
|
@ -537,7 +537,7 @@ ENTRY(__switch_to)
|
|||
#ifdef CONFIG_CPU_MPCORE
|
||||
clrex
|
||||
#else
|
||||
strex r3, r4, [ip] @ Clear exclusive monitor
|
||||
strex r5, r4, [ip] @ Clear exclusive monitor
|
||||
#endif
|
||||
#endif
|
||||
#if defined(CONFIG_CPU_XSCALE) && !defined(CONFIG_IWMMXT)
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* Copy data from IO memory space to "real" memory space.
|
||||
* This needs to be optimized.
|
||||
*/
|
||||
void _memcpy_fromio(void *to, void __iomem *from, size_t count)
|
||||
void _memcpy_fromio(void *to, const volatile void __iomem *from, size_t count)
|
||||
{
|
||||
unsigned char *t = to;
|
||||
while (count) {
|
||||
|
@ -22,7 +22,7 @@ void _memcpy_fromio(void *to, void __iomem *from, size_t count)
|
|||
* Copy data from "real" memory space to IO memory space.
|
||||
* This needs to be optimized.
|
||||
*/
|
||||
void _memcpy_toio(void __iomem *to, const void *from, size_t count)
|
||||
void _memcpy_toio(volatile void __iomem *to, const void *from, size_t count)
|
||||
{
|
||||
const unsigned char *f = from;
|
||||
while (count) {
|
||||
|
@ -37,7 +37,7 @@ void _memcpy_toio(void __iomem *to, const void *from, size_t count)
|
|||
* "memset" on IO memory space.
|
||||
* This needs to be optimized.
|
||||
*/
|
||||
void _memset_io(void __iomem *dst, int c, size_t count)
|
||||
void _memset_io(volatile void __iomem *dst, int c, size_t count)
|
||||
{
|
||||
while (count) {
|
||||
count--;
|
||||
|
|
|
@ -178,7 +178,7 @@ int __down_trylock(struct semaphore * sem)
|
|||
* registers (r0 to r3 and lr), but not ip, as we use it as a return
|
||||
* value in some cases..
|
||||
*/
|
||||
asm(" .section .sched.text,\"ax\" \n\
|
||||
asm(" .section .sched.text,\"ax\",%progbits \n\
|
||||
.align 5 \n\
|
||||
.globl __down_failed \n\
|
||||
__down_failed: \n\
|
||||
|
|
|
@ -624,6 +624,9 @@ void __attribute__((noreturn)) __bug(const char *file, int line, void *data)
|
|||
printk(" - extra data = %p", data);
|
||||
printk("\n");
|
||||
*(int *)0 = 0;
|
||||
|
||||
/* Avoid "noreturn function does return" */
|
||||
for (;;);
|
||||
}
|
||||
EXPORT_SYMBOL(__bug);
|
||||
|
||||
|
|
|
@ -23,20 +23,20 @@ SECTIONS
|
|||
*(.init.text)
|
||||
_einittext = .;
|
||||
__proc_info_begin = .;
|
||||
*(.proc.info)
|
||||
*(.proc.info.init)
|
||||
__proc_info_end = .;
|
||||
__arch_info_begin = .;
|
||||
*(.arch.info)
|
||||
*(.arch.info.init)
|
||||
__arch_info_end = .;
|
||||
__tagtable_begin = .;
|
||||
*(.taglist)
|
||||
*(.taglist.init)
|
||||
__tagtable_end = .;
|
||||
. = ALIGN(16);
|
||||
__setup_start = .;
|
||||
*(.init.setup)
|
||||
__setup_end = .;
|
||||
__early_begin = .;
|
||||
*(__early_param)
|
||||
*(.early_param.init)
|
||||
__early_end = .;
|
||||
__initcall_start = .;
|
||||
*(.initcall1.init)
|
||||
|
|
|
@ -123,6 +123,7 @@ static void __init ixdp425_init(void)
|
|||
platform_add_devices(ixdp425_devices, ARRAY_SIZE(ixdp425_devices));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARCH_IXDP465
|
||||
MACHINE_START(IXDP425, "Intel IXDP425 Development Platform")
|
||||
/* Maintainer: MontaVista Software, Inc. */
|
||||
.phys_ram = PHYS_OFFSET,
|
||||
|
@ -134,7 +135,9 @@ MACHINE_START(IXDP425, "Intel IXDP425 Development Platform")
|
|||
.boot_params = 0x0100,
|
||||
.init_machine = ixdp425_init,
|
||||
MACHINE_END
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MACH_IXDP465
|
||||
MACHINE_START(IXDP465, "Intel IXDP465 Development Platform")
|
||||
/* Maintainer: MontaVista Software, Inc. */
|
||||
.phys_ram = PHYS_OFFSET,
|
||||
|
@ -146,7 +149,9 @@ MACHINE_START(IXDP465, "Intel IXDP465 Development Platform")
|
|||
.boot_params = 0x0100,
|
||||
.init_machine = ixdp425_init,
|
||||
MACHINE_END
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_PRPMC1100
|
||||
MACHINE_START(IXCDP1100, "Intel IXCDP1100 Development Platform")
|
||||
/* Maintainer: MontaVista Software, Inc. */
|
||||
.phys_ram = PHYS_OFFSET,
|
||||
|
@ -158,6 +163,7 @@ MACHINE_START(IXCDP1100, "Intel IXCDP1100 Development Platform")
|
|||
.boot_params = 0x0100,
|
||||
.init_machine = ixdp425_init,
|
||||
MACHINE_END
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Avila is functionally equivalent to IXDP425 except that it adds
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
*
|
||||
* Modifications:
|
||||
* 02-May-2005 BJD Copied from mach-bast.c
|
||||
* 20-Sep-2005 BJD Added static to non-exported items
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
|
@ -232,7 +233,7 @@ static struct s3c24xx_board anubis_board __initdata = {
|
|||
.clocks_count = ARRAY_SIZE(anubis_clocks)
|
||||
};
|
||||
|
||||
void __init anubis_map_io(void)
|
||||
static void __init anubis_map_io(void)
|
||||
{
|
||||
/* initialise the clocks */
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
* 17-Jul-2005 BJD Changed to platform device for SuperIO 16550s
|
||||
* 25-Jul-2005 BJD Removed ASIX static mappings
|
||||
* 27-Jul-2005 BJD Ensure maximum frequency of i2c bus
|
||||
* 20-Sep-2005 BJD Added static to non-exported items
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
|
@ -428,7 +429,7 @@ static struct s3c24xx_board bast_board __initdata = {
|
|||
.clocks_count = ARRAY_SIZE(bast_clocks)
|
||||
};
|
||||
|
||||
void __init bast_map_io(void)
|
||||
static void __init bast_map_io(void)
|
||||
{
|
||||
/* initialise the clocks */
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
* 10-Jan-2005 BJD Removed include of s3c2410.h
|
||||
* 14-Jan-2005 BJD Added clock init
|
||||
* 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
|
||||
* 20-Sep-2005 BJD Added static to non-exported items
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
|
@ -147,7 +148,7 @@ static struct s3c24xx_board h1940_board __initdata = {
|
|||
.devices_count = ARRAY_SIZE(h1940_devices)
|
||||
};
|
||||
|
||||
void __init h1940_map_io(void)
|
||||
static void __init h1940_map_io(void)
|
||||
{
|
||||
s3c24xx_init_io(h1940_iodesc, ARRAY_SIZE(h1940_iodesc));
|
||||
s3c24xx_init_clocks(0);
|
||||
|
@ -155,13 +156,13 @@ void __init h1940_map_io(void)
|
|||
s3c24xx_set_board(&h1940_board);
|
||||
}
|
||||
|
||||
void __init h1940_init_irq(void)
|
||||
static void __init h1940_init_irq(void)
|
||||
{
|
||||
s3c24xx_init_irq();
|
||||
|
||||
}
|
||||
|
||||
void __init h1940_init(void)
|
||||
static void __init h1940_init(void)
|
||||
{
|
||||
set_s3c2410fb_info(&h1940_lcdcfg);
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ static struct s3c24xx_board n30_board __initdata = {
|
|||
.devices_count = ARRAY_SIZE(n30_devices)
|
||||
};
|
||||
|
||||
void __init n30_map_io(void)
|
||||
static void __init n30_map_io(void)
|
||||
{
|
||||
s3c24xx_init_io(n30_iodesc, ARRAY_SIZE(n30_iodesc));
|
||||
s3c24xx_init_clocks(0);
|
||||
|
@ -105,14 +105,14 @@ void __init n30_map_io(void)
|
|||
s3c24xx_set_board(&n30_board);
|
||||
}
|
||||
|
||||
void __init n30_init_irq(void)
|
||||
static void __init n30_init_irq(void)
|
||||
{
|
||||
s3c24xx_init_irq();
|
||||
}
|
||||
|
||||
/* GPB3 is the line that controls the pull-up for the USB D+ line */
|
||||
|
||||
void __init n30_init(void)
|
||||
static void __init n30_init(void)
|
||||
{
|
||||
s3c_device_i2c.dev.platform_data = &n30_i2ccfg;
|
||||
|
||||
|
|
|
@ -136,7 +136,7 @@ static void __init nexcoder_sensorboard_init(void)
|
|||
s3c2410_gpio_cfgpin(S3C2410_GPF2, S3C2410_GPF2_OUTP); // CAM_GPIO6 => CAM_PWRDN
|
||||
}
|
||||
|
||||
void __init nexcoder_map_io(void)
|
||||
static void __init nexcoder_map_io(void)
|
||||
{
|
||||
s3c24xx_init_io(nexcoder_iodesc, ARRAY_SIZE(nexcoder_iodesc));
|
||||
s3c24xx_init_clocks(0);
|
||||
|
|
|
@ -105,7 +105,7 @@ static struct s3c24xx_board otom11_board __initdata = {
|
|||
};
|
||||
|
||||
|
||||
void __init otom11_map_io(void)
|
||||
static void __init otom11_map_io(void)
|
||||
{
|
||||
s3c24xx_init_io(otom11_iodesc, ARRAY_SIZE(otom11_iodesc));
|
||||
s3c24xx_init_clocks(0);
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
* 14-Jan-2005 BJD Added new clock init
|
||||
* 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
|
||||
* 14-Mar-2005 BJD Fixed __iomem warnings
|
||||
* 20-Sep-2005 BJD Added static to non-exported items
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
|
@ -108,7 +109,7 @@ static struct s3c24xx_board rx3715_board __initdata = {
|
|||
.devices_count = ARRAY_SIZE(rx3715_devices)
|
||||
};
|
||||
|
||||
void __init rx3715_map_io(void)
|
||||
static void __init rx3715_map_io(void)
|
||||
{
|
||||
s3c24xx_init_io(rx3715_iodesc, ARRAY_SIZE(rx3715_iodesc));
|
||||
s3c24xx_init_clocks(16934000);
|
||||
|
@ -116,7 +117,7 @@ void __init rx3715_map_io(void)
|
|||
s3c24xx_set_board(&rx3715_board);
|
||||
}
|
||||
|
||||
void __init rx3715_init_irq(void)
|
||||
static void __init rx3715_init_irq(void)
|
||||
{
|
||||
s3c24xx_init_irq();
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
* Ben Dooks <ben@simtec.co.uk>
|
||||
*
|
||||
* 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
|
||||
* 20-Sep-2005 BJD Added static to non-exported items
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
|
@ -97,7 +98,7 @@ static struct s3c24xx_board smdk2410_board __initdata = {
|
|||
.devices_count = ARRAY_SIZE(smdk2410_devices)
|
||||
};
|
||||
|
||||
void __init smdk2410_map_io(void)
|
||||
static void __init smdk2410_map_io(void)
|
||||
{
|
||||
s3c24xx_init_io(smdk2410_iodesc, ARRAY_SIZE(smdk2410_iodesc));
|
||||
s3c24xx_init_clocks(0);
|
||||
|
@ -105,7 +106,7 @@ void __init smdk2410_map_io(void)
|
|||
s3c24xx_set_board(&smdk2410_board);
|
||||
}
|
||||
|
||||
void __init smdk2410_init_irq(void)
|
||||
static void __init smdk2410_init_irq(void)
|
||||
{
|
||||
s3c24xx_init_irq();
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
* 22-Feb-2005 BJD Updated for 2.6.11-rc5 relesa
|
||||
* 10-Mar-2005 LCVR Replaced S3C2410_VA by S3C24XX_VA
|
||||
* 14-Mar-2005 BJD void __iomem fixes
|
||||
* 20-Sep-2005 BJD Added static to non-exported items
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
|
@ -98,7 +99,7 @@ static struct s3c24xx_board smdk2440_board __initdata = {
|
|||
.devices_count = ARRAY_SIZE(smdk2440_devices)
|
||||
};
|
||||
|
||||
void __init smdk2440_map_io(void)
|
||||
static void __init smdk2440_map_io(void)
|
||||
{
|
||||
s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc));
|
||||
s3c24xx_init_clocks(16934400);
|
||||
|
@ -106,7 +107,7 @@ void __init smdk2440_map_io(void)
|
|||
s3c24xx_set_board(&smdk2440_board);
|
||||
}
|
||||
|
||||
void __init smdk2440_machine_init(void)
|
||||
static void __init smdk2440_machine_init(void)
|
||||
{
|
||||
/* Configure the LEDs (even if we have no LED support)*/
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
* 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
|
||||
* 14-Mar-2006 BJD void __iomem fixes
|
||||
* 22-Jun-2006 BJD Added DM9000 platform information
|
||||
* 20-Sep-2005 BJD Added static to non-exported items
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
|
@ -347,7 +348,7 @@ static void vr1000_power_off(void)
|
|||
s3c2410_gpio_setpin(S3C2410_GPB9, 1);
|
||||
}
|
||||
|
||||
void __init vr1000_map_io(void)
|
||||
static void __init vr1000_map_io(void)
|
||||
{
|
||||
/* initialise clock sources */
|
||||
|
||||
|
|
|
@ -39,3 +39,6 @@ extern void sa11x0_set_ssp_data(struct sa11x0_ssp_plat_ops *ops);
|
|||
|
||||
struct irda_platform_data;
|
||||
void sa11x0_set_irda_data(struct irda_platform_data *irda);
|
||||
|
||||
struct mcp_plat_data;
|
||||
void sa11x0_set_mcp_data(struct mcp_plat_data *data);
|
||||
|
|
|
@ -233,7 +233,17 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
|
|||
if (in_interrupt() || !mm)
|
||||
goto no_context;
|
||||
|
||||
/*
|
||||
* As per x86, we may deadlock here. However, since the kernel only
|
||||
* validly references user space from well defined areas of the code,
|
||||
* we can bug out early if this is from code which shouldn't.
|
||||
*/
|
||||
if (!down_read_trylock(&mm->mmap_sem)) {
|
||||
if (!user_mode(regs) && !search_exception_tables(regs->ARM_pc))
|
||||
goto no_context;
|
||||
down_read(&mm->mmap_sem);
|
||||
}
|
||||
|
||||
fault = __do_page_fault(mm, addr, fsr, tsk);
|
||||
up_read(&mm->mmap_sem);
|
||||
|
||||
|
|
|
@ -509,7 +509,7 @@ cpu_arm1020_name:
|
|||
|
||||
.align
|
||||
|
||||
.section ".proc.info", #alloc, #execinstr
|
||||
.section ".proc.info.init", #alloc, #execinstr
|
||||
|
||||
.type __arm1020_proc_info,#object
|
||||
__arm1020_proc_info:
|
||||
|
|
|
@ -491,7 +491,7 @@ cpu_arm1020e_name:
|
|||
|
||||
.align
|
||||
|
||||
.section ".proc.info", #alloc, #execinstr
|
||||
.section ".proc.info.init", #alloc, #execinstr
|
||||
|
||||
.type __arm1020e_proc_info,#object
|
||||
__arm1020e_proc_info:
|
||||
|
|
|
@ -473,7 +473,7 @@ cpu_arm1022_name:
|
|||
|
||||
.align
|
||||
|
||||
.section ".proc.info", #alloc, #execinstr
|
||||
.section ".proc.info.init", #alloc, #execinstr
|
||||
|
||||
.type __arm1022_proc_info,#object
|
||||
__arm1022_proc_info:
|
||||
|
|
|
@ -469,7 +469,7 @@ cpu_arm1026_name:
|
|||
|
||||
.align
|
||||
|
||||
.section ".proc.info", #alloc, #execinstr
|
||||
.section ".proc.info.init", #alloc, #execinstr
|
||||
|
||||
.type __arm1026_proc_info,#object
|
||||
__arm1026_proc_info:
|
||||
|
|
|
@ -332,7 +332,7 @@ cpu_arm710_name:
|
|||
|
||||
.align
|
||||
|
||||
.section ".proc.info", #alloc, #execinstr
|
||||
.section ".proc.info.init", #alloc, #execinstr
|
||||
|
||||
.type __arm6_proc_info, #object
|
||||
__arm6_proc_info:
|
||||
|
|
|
@ -222,7 +222,7 @@ cpu_arm720_name:
|
|||
* See linux/include/asm-arm/procinfo.h for a definition of this structure.
|
||||
*/
|
||||
|
||||
.section ".proc.info", #alloc, #execinstr
|
||||
.section ".proc.info.init", #alloc, #execinstr
|
||||
|
||||
.type __arm710_proc_info, #object
|
||||
__arm710_proc_info:
|
||||
|
|
|
@ -452,7 +452,7 @@ cpu_arm920_name:
|
|||
|
||||
.align
|
||||
|
||||
.section ".proc.info", #alloc, #execinstr
|
||||
.section ".proc.info.init", #alloc, #execinstr
|
||||
|
||||
.type __arm920_proc_info,#object
|
||||
__arm920_proc_info:
|
||||
|
|
|
@ -456,7 +456,7 @@ cpu_arm922_name:
|
|||
|
||||
.align
|
||||
|
||||
.section ".proc.info", #alloc, #execinstr
|
||||
.section ".proc.info.init", #alloc, #execinstr
|
||||
|
||||
.type __arm922_proc_info,#object
|
||||
__arm922_proc_info:
|
||||
|
|
|
@ -521,7 +521,7 @@ cpu_arm925_name:
|
|||
|
||||
.align
|
||||
|
||||
.section ".proc.info", #alloc, #execinstr
|
||||
.section ".proc.info.init", #alloc, #execinstr
|
||||
|
||||
.type __arm925_proc_info,#object
|
||||
__arm925_proc_info:
|
||||
|
|
|
@ -471,7 +471,7 @@ cpu_arm926_name:
|
|||
|
||||
.align
|
||||
|
||||
.section ".proc.info", #alloc, #execinstr
|
||||
.section ".proc.info.init", #alloc, #execinstr
|
||||
|
||||
.type __arm926_proc_info,#object
|
||||
__arm926_proc_info:
|
||||
|
|
|
@ -249,7 +249,7 @@ cpu_sa110_name:
|
|||
|
||||
.align
|
||||
|
||||
.section ".proc.info", #alloc, #execinstr
|
||||
.section ".proc.info.init", #alloc, #execinstr
|
||||
|
||||
.type __sa110_proc_info,#object
|
||||
__sa110_proc_info:
|
||||
|
|
|
@ -280,7 +280,7 @@ cpu_sa1110_name:
|
|||
|
||||
.align
|
||||
|
||||
.section ".proc.info", #alloc, #execinstr
|
||||
.section ".proc.info.init", #alloc, #execinstr
|
||||
|
||||
.type __sa1100_proc_info,#object
|
||||
__sa1100_proc_info:
|
||||
|
|
|
@ -240,7 +240,7 @@ cpu_elf_name:
|
|||
.size cpu_elf_name, . - cpu_elf_name
|
||||
.align
|
||||
|
||||
.section ".proc.info", #alloc, #execinstr
|
||||
.section ".proc.info.init", #alloc, #execinstr
|
||||
|
||||
/*
|
||||
* Match any ARMv6 processor core.
|
||||
|
|
|
@ -578,7 +578,7 @@ cpu_pxa270_name:
|
|||
|
||||
.align
|
||||
|
||||
.section ".proc.info", #alloc, #execinstr
|
||||
.section ".proc.info.init", #alloc, #execinstr
|
||||
|
||||
.type __80200_proc_info,#object
|
||||
__80200_proc_info:
|
||||
|
|
|
@ -233,6 +233,23 @@ simscsi_readwrite10 (struct scsi_cmnd *sc, int mode)
|
|||
simscsi_readwrite(sc, mode, offset, ((sc->cmnd[7] << 8) | sc->cmnd[8])*512);
|
||||
}
|
||||
|
||||
static void simscsi_fillresult(struct scsi_cmnd *sc, char *buf, unsigned len)
|
||||
{
|
||||
|
||||
int scatterlen = sc->use_sg;
|
||||
struct scatterlist *slp;
|
||||
|
||||
if (scatterlen == 0)
|
||||
memcpy(sc->request_buffer, buf, len);
|
||||
else for (slp = (struct scatterlist *)sc->buffer; scatterlen-- > 0 && len > 0; slp++) {
|
||||
unsigned thislen = min(len, slp->length);
|
||||
|
||||
memcpy(page_address(slp->page) + slp->offset, buf, thislen);
|
||||
slp++;
|
||||
len -= thislen;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
|
||||
{
|
||||
|
@ -240,6 +257,7 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
|
|||
char fname[MAX_ROOT_LEN+16];
|
||||
size_t disk_size;
|
||||
char *buf;
|
||||
char localbuf[36];
|
||||
#if DEBUG_SIMSCSI
|
||||
register long sp asm ("sp");
|
||||
|
||||
|
@ -263,7 +281,7 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
|
|||
/* disk doesn't exist... */
|
||||
break;
|
||||
}
|
||||
buf = sc->request_buffer;
|
||||
buf = localbuf;
|
||||
buf[0] = 0; /* magnetic disk */
|
||||
buf[1] = 0; /* not a removable medium */
|
||||
buf[2] = 2; /* SCSI-2 compliant device */
|
||||
|
@ -273,6 +291,7 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
|
|||
buf[6] = 0; /* reserved */
|
||||
buf[7] = 0; /* various flags */
|
||||
memcpy(buf + 8, "HP SIMULATED DISK 0.00", 28);
|
||||
simscsi_fillresult(sc, buf, 36);
|
||||
sc->result = GOOD;
|
||||
break;
|
||||
|
||||
|
@ -304,16 +323,13 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
|
|||
simscsi_readwrite10(sc, SSC_WRITE);
|
||||
break;
|
||||
|
||||
|
||||
case READ_CAPACITY:
|
||||
if (desc[target_id] < 0 || sc->request_bufflen < 8) {
|
||||
break;
|
||||
}
|
||||
buf = sc->request_buffer;
|
||||
|
||||
buf = localbuf;
|
||||
disk_size = simscsi_get_disk_size(desc[target_id]);
|
||||
|
||||
/* pretend to be a 1GB disk (partition table contains real stuff): */
|
||||
buf[0] = (disk_size >> 24) & 0xff;
|
||||
buf[1] = (disk_size >> 16) & 0xff;
|
||||
buf[2] = (disk_size >> 8) & 0xff;
|
||||
|
@ -323,13 +339,14 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
|
|||
buf[5] = 0;
|
||||
buf[6] = 2;
|
||||
buf[7] = 0;
|
||||
simscsi_fillresult(sc, buf, 8);
|
||||
sc->result = GOOD;
|
||||
break;
|
||||
|
||||
case MODE_SENSE:
|
||||
case MODE_SENSE_10:
|
||||
/* sd.c uses this to determine whether disk does write-caching. */
|
||||
memset(sc->request_buffer, 0, 128);
|
||||
simscsi_fillresult(sc, (char *)empty_zero_page, sc->request_bufflen);
|
||||
sc->result = GOOD;
|
||||
break;
|
||||
|
||||
|
|
|
@ -489,24 +489,27 @@ ia64_state_save:
|
|||
;;
|
||||
st8 [temp1]=r17,16 // pal_min_state
|
||||
st8 [temp2]=r6,16 // prev_IA64_KR_CURRENT
|
||||
mov r6=IA64_KR(CURRENT_STACK)
|
||||
;;
|
||||
st8 [temp1]=r6,16 // prev_IA64_KR_CURRENT_STACK
|
||||
st8 [temp2]=r0,16 // prev_task, starts off as NULL
|
||||
mov r6=cr.ifa
|
||||
;;
|
||||
st8 [temp1]=r0,16 // prev_task, starts off as NULL
|
||||
st8 [temp2]=r12,16 // cr.isr
|
||||
st8 [temp1]=r12,16 // cr.isr
|
||||
st8 [temp2]=r6,16 // cr.ifa
|
||||
mov r12=cr.itir
|
||||
;;
|
||||
st8 [temp1]=r6,16 // cr.ifa
|
||||
st8 [temp2]=r12,16 // cr.itir
|
||||
st8 [temp1]=r12,16 // cr.itir
|
||||
st8 [temp2]=r11,16 // cr.iipa
|
||||
mov r12=cr.iim
|
||||
;;
|
||||
st8 [temp1]=r11,16 // cr.iipa
|
||||
st8 [temp2]=r12,16 // cr.iim
|
||||
mov r6=cr.iha
|
||||
st8 [temp1]=r12,16 // cr.iim
|
||||
(p1) mov r12=IA64_MCA_COLD_BOOT
|
||||
(p2) mov r12=IA64_INIT_WARM_BOOT
|
||||
mov r6=cr.iha
|
||||
;;
|
||||
st8 [temp1]=r6,16 // cr.iha
|
||||
st8 [temp2]=r12 // os_status, default is cold boot
|
||||
st8 [temp2]=r6,16 // cr.iha
|
||||
st8 [temp1]=r12 // os_status, default is cold boot
|
||||
mov r6=IA64_MCA_SAME_CONTEXT
|
||||
;;
|
||||
st8 [temp1]=r6 // context, default is same context
|
||||
|
@ -823,9 +826,12 @@ ia64_state_restore:
|
|||
ld8 r12=[temp1],16 // sal_ra
|
||||
ld8 r9=[temp2],16 // sal_gp
|
||||
;;
|
||||
ld8 r22=[temp1],24 // pal_min_state, virtual. skip prev_task
|
||||
ld8 r22=[temp1],16 // pal_min_state, virtual
|
||||
ld8 r21=[temp2],16 // prev_IA64_KR_CURRENT
|
||||
;;
|
||||
ld8 r16=[temp1],16 // prev_IA64_KR_CURRENT_STACK
|
||||
ld8 r20=[temp2],16 // prev_task
|
||||
;;
|
||||
ld8 temp3=[temp1],16 // cr.isr
|
||||
ld8 temp4=[temp2],16 // cr.ifa
|
||||
;;
|
||||
|
@ -846,6 +852,45 @@ ia64_state_restore:
|
|||
ld8 r8=[temp1] // os_status
|
||||
ld8 r10=[temp2] // context
|
||||
|
||||
/* Wire IA64_TR_CURRENT_STACK to the stack that we are resuming to. To
|
||||
* avoid any dependencies on the algorithm in ia64_switch_to(), just
|
||||
* purge any existing CURRENT_STACK mapping and insert the new one.
|
||||
*
|
||||
* r16 contains prev_IA64_KR_CURRENT_STACK, r21 contains
|
||||
* prev_IA64_KR_CURRENT, these values may have been changed by the C
|
||||
* code. Do not use r8, r9, r10, r22, they contain values ready for
|
||||
* the return to SAL.
|
||||
*/
|
||||
|
||||
mov r15=IA64_KR(CURRENT_STACK) // physical granule mapped by IA64_TR_CURRENT_STACK
|
||||
;;
|
||||
shl r15=r15,IA64_GRANULE_SHIFT
|
||||
;;
|
||||
dep r15=-1,r15,61,3 // virtual granule
|
||||
mov r18=IA64_GRANULE_SHIFT<<2 // for cr.itir.ps
|
||||
;;
|
||||
ptr.d r15,r18
|
||||
;;
|
||||
srlz.d
|
||||
|
||||
extr.u r19=r21,61,3 // r21 = prev_IA64_KR_CURRENT
|
||||
shl r20=r16,IA64_GRANULE_SHIFT // r16 = prev_IA64_KR_CURRENT_STACK
|
||||
movl r21=PAGE_KERNEL // page properties
|
||||
;;
|
||||
mov IA64_KR(CURRENT_STACK)=r16
|
||||
cmp.ne p6,p0=RGN_KERNEL,r19 // new stack is in the kernel region?
|
||||
or r21=r20,r21 // construct PA | page properties
|
||||
(p6) br.spnt 1f // the dreaded cpu 0 idle task in region 5:(
|
||||
;;
|
||||
mov cr.itir=r18
|
||||
mov cr.ifa=r21
|
||||
mov r20=IA64_TR_CURRENT_STACK
|
||||
;;
|
||||
itr.d dtr[r20]=r21
|
||||
;;
|
||||
srlz.d
|
||||
1:
|
||||
|
||||
br.sptk b0
|
||||
|
||||
//EndStub//////////////////////////////////////////////////////////////////////
|
||||
|
@ -982,6 +1027,7 @@ ia64_set_kernel_registers:
|
|||
add temp4=temp4, temp1 // &struct ia64_sal_os_state.os_gp
|
||||
add r12=temp1, temp3 // kernel stack pointer on MCA/INIT stack
|
||||
add r13=temp1, r3 // set current to start of MCA/INIT stack
|
||||
add r20=temp1, r3 // physical start of MCA/INIT stack
|
||||
;;
|
||||
ld8 r1=[temp4] // OS GP from SAL OS state
|
||||
;;
|
||||
|
@ -991,7 +1037,35 @@ ia64_set_kernel_registers:
|
|||
;;
|
||||
mov IA64_KR(CURRENT)=r13
|
||||
|
||||
// FIXME: do I need to wire IA64_KR_CURRENT_STACK and IA64_TR_CURRENT_STACK?
|
||||
/* Wire IA64_TR_CURRENT_STACK to the MCA/INIT handler stack. To avoid
|
||||
* any dependencies on the algorithm in ia64_switch_to(), just purge
|
||||
* any existing CURRENT_STACK mapping and insert the new one.
|
||||
*/
|
||||
|
||||
mov r16=IA64_KR(CURRENT_STACK) // physical granule mapped by IA64_TR_CURRENT_STACK
|
||||
;;
|
||||
shl r16=r16,IA64_GRANULE_SHIFT
|
||||
;;
|
||||
dep r16=-1,r16,61,3 // virtual granule
|
||||
mov r18=IA64_GRANULE_SHIFT<<2 // for cr.itir.ps
|
||||
;;
|
||||
ptr.d r16,r18
|
||||
;;
|
||||
srlz.d
|
||||
|
||||
shr.u r16=r20,IA64_GRANULE_SHIFT // r20 = physical start of MCA/INIT stack
|
||||
movl r21=PAGE_KERNEL // page properties
|
||||
;;
|
||||
mov IA64_KR(CURRENT_STACK)=r16
|
||||
or r21=r20,r21 // construct PA | page properties
|
||||
;;
|
||||
mov cr.itir=r18
|
||||
mov cr.ifa=r13
|
||||
mov r20=IA64_TR_CURRENT_STACK
|
||||
;;
|
||||
itr.d dtr[r20]=r21
|
||||
;;
|
||||
srlz.d
|
||||
|
||||
br.sptk b0
|
||||
|
||||
|
|
|
@ -56,8 +56,9 @@ static struct page *page_isolate[MAX_PAGE_ISOLATE];
|
|||
static int num_page_isolate = 0;
|
||||
|
||||
typedef enum {
|
||||
ISOLATE_NG = 0,
|
||||
ISOLATE_OK = 1
|
||||
ISOLATE_NG,
|
||||
ISOLATE_OK,
|
||||
ISOLATE_NONE
|
||||
} isolate_status_t;
|
||||
|
||||
/*
|
||||
|
@ -74,7 +75,7 @@ static struct {
|
|||
* @paddr: poisoned memory location
|
||||
*
|
||||
* Return value:
|
||||
* ISOLATE_OK / ISOLATE_NG
|
||||
* one of isolate_status_t, ISOLATE_OK/NG/NONE.
|
||||
*/
|
||||
|
||||
static isolate_status_t
|
||||
|
@ -85,7 +86,10 @@ mca_page_isolate(unsigned long paddr)
|
|||
|
||||
/* whether physical address is valid or not */
|
||||
if (!ia64_phys_addr_valid(paddr))
|
||||
return ISOLATE_NG;
|
||||
return ISOLATE_NONE;
|
||||
|
||||
if (!pfn_valid(paddr))
|
||||
return ISOLATE_NONE;
|
||||
|
||||
/* convert physical address to physical page number */
|
||||
p = pfn_to_page(paddr>>PAGE_SHIFT);
|
||||
|
@ -122,10 +126,15 @@ mca_handler_bh(unsigned long paddr)
|
|||
current->pid, current->comm);
|
||||
|
||||
spin_lock(&mca_bh_lock);
|
||||
if (mca_page_isolate(paddr) == ISOLATE_OK) {
|
||||
switch (mca_page_isolate(paddr)) {
|
||||
case ISOLATE_OK:
|
||||
printk(KERN_DEBUG "Page isolation: ( %lx ) success.\n", paddr);
|
||||
} else {
|
||||
break;
|
||||
case ISOLATE_NG:
|
||||
printk(KERN_DEBUG "Page isolation: ( %lx ) failure.\n", paddr);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
spin_unlock(&mca_bh_lock);
|
||||
|
||||
|
|
|
@ -15,9 +15,8 @@ extra-y += vmlinux.lds
|
|||
obj-y := entry.o traps.o irq.o idle.o time.o misc.o \
|
||||
process.o signal.o ptrace.o align.o \
|
||||
semaphore.o syscalls.o setup.o \
|
||||
cputable.o ppc_htab.o
|
||||
cputable.o ppc_htab.o perfmon.o
|
||||
obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o
|
||||
obj-$(CONFIG_E500) += perfmon.o
|
||||
obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o
|
||||
obj-$(CONFIG_POWER4) += cpu_setup_power4.o
|
||||
obj-$(CONFIG_MODULES) += module.o ppc_ksyms.o
|
||||
|
|
|
@ -45,7 +45,7 @@ static void dummy_perf(struct pt_regs *regs)
|
|||
mtpmr(PMRN_PMGC0, pmgc0);
|
||||
}
|
||||
|
||||
#else
|
||||
#elif CONFIG_6xx
|
||||
/* Ensure exceptions are disabled */
|
||||
|
||||
static void dummy_perf(struct pt_regs *regs)
|
||||
|
@ -55,6 +55,10 @@ static void dummy_perf(struct pt_regs *regs)
|
|||
mmcr0 &= ~MMCR0_PMXE;
|
||||
mtspr(SPRN_MMCR0, mmcr0);
|
||||
}
|
||||
#else
|
||||
static void dummy_perf(struct pt_regs *regs)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
void (*perf_irq)(struct pt_regs *) = dummy_perf;
|
||||
|
|
|
@ -719,7 +719,8 @@ pmac_declare_of_platform_devices(void)
|
|||
if (np) {
|
||||
for (np = np->child; np != NULL; np = np->sibling)
|
||||
if (strncmp(np->name, "i2c", 3) == 0) {
|
||||
of_platform_device_create(np, "uni-n-i2c");
|
||||
of_platform_device_create(np, "uni-n-i2c",
|
||||
NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -727,17 +728,18 @@ pmac_declare_of_platform_devices(void)
|
|||
if (np) {
|
||||
for (np = np->child; np != NULL; np = np->sibling)
|
||||
if (strncmp(np->name, "i2c", 3) == 0) {
|
||||
of_platform_device_create(np, "u3-i2c");
|
||||
of_platform_device_create(np, "u3-i2c",
|
||||
NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
np = find_devices("valkyrie");
|
||||
if (np)
|
||||
of_platform_device_create(np, "valkyrie");
|
||||
of_platform_device_create(np, "valkyrie", NULL);
|
||||
np = find_devices("platinum");
|
||||
if (np)
|
||||
of_platform_device_create(np, "platinum");
|
||||
of_platform_device_create(np, "platinum", NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -234,7 +234,9 @@ void of_device_unregister(struct of_device *ofdev)
|
|||
device_unregister(&ofdev->dev);
|
||||
}
|
||||
|
||||
struct of_device* of_platform_device_create(struct device_node *np, const char *bus_id)
|
||||
struct of_device* of_platform_device_create(struct device_node *np,
|
||||
const char *bus_id,
|
||||
struct device *parent)
|
||||
{
|
||||
struct of_device *dev;
|
||||
u32 *reg;
|
||||
|
@ -247,7 +249,7 @@ struct of_device* of_platform_device_create(struct device_node *np, const char *
|
|||
dev->node = of_node_get(np);
|
||||
dev->dma_mask = 0xffffffffUL;
|
||||
dev->dev.dma_mask = &dev->dma_mask;
|
||||
dev->dev.parent = NULL;
|
||||
dev->dev.parent = parent;
|
||||
dev->dev.bus = &of_platform_bus_type;
|
||||
dev->dev.release = of_release_dev;
|
||||
|
||||
|
|
|
@ -184,8 +184,8 @@ mpc85xx_setup_pci1(struct pci_controller *hose)
|
|||
pci->powar1 = 0x80044000 |
|
||||
(__ilog2(MPC85XX_PCI1_UPPER_MEM - MPC85XX_PCI1_LOWER_MEM + 1) - 1);
|
||||
|
||||
/* Setup outboud IO windows @ MPC85XX_PCI1_IO_BASE */
|
||||
pci->potar2 = 0x00000000;
|
||||
/* Setup outbound IO windows @ MPC85XX_PCI1_IO_BASE */
|
||||
pci->potar2 = (MPC85XX_PCI1_LOWER_IO >> 12) & 0x000fffff;
|
||||
pci->potear2 = 0x00000000;
|
||||
pci->powbar2 = (MPC85XX_PCI1_IO_BASE >> 12) & 0x000fffff;
|
||||
/* Enable, IO R/W */
|
||||
|
@ -235,8 +235,8 @@ mpc85xx_setup_pci2(struct pci_controller *hose)
|
|||
pci->powar1 = 0x80044000 |
|
||||
(__ilog2(MPC85XX_PCI2_UPPER_MEM - MPC85XX_PCI2_LOWER_MEM + 1) - 1);
|
||||
|
||||
/* Setup outboud IO windows @ MPC85XX_PCI2_IO_BASE */
|
||||
pci->potar2 = 0x00000000;
|
||||
/* Setup outbound IO windows @ MPC85XX_PCI2_IO_BASE */
|
||||
pci->potar2 = (MPC85XX_PCI2_LOWER_IO >> 12) & 0x000fffff;;
|
||||
pci->potear2 = 0x00000000;
|
||||
pci->powbar2 = (MPC85XX_PCI2_IO_BASE >> 12) & 0x000fffff;
|
||||
/* Enable, IO R/W */
|
||||
|
|
|
@ -107,7 +107,7 @@ install: vmlinux
|
|||
$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) $@
|
||||
|
||||
defaultimage-$(CONFIG_PPC_PSERIES) := zImage
|
||||
defaultimage-$(CONFIG_PPC_PMAC) := vmlinux
|
||||
defaultimage-$(CONFIG_PPC_PMAC) := zImage.vmode
|
||||
defaultimage-$(CONFIG_PPC_MAPLE) := zImage
|
||||
defaultimage-$(CONFIG_PPC_ISERIES) := vmlinux
|
||||
KBUILD_IMAGE := $(defaultimage-y)
|
||||
|
|
|
@ -233,7 +233,9 @@ void of_device_unregister(struct of_device *ofdev)
|
|||
device_unregister(&ofdev->dev);
|
||||
}
|
||||
|
||||
struct of_device* of_platform_device_create(struct device_node *np, const char *bus_id)
|
||||
struct of_device* of_platform_device_create(struct device_node *np,
|
||||
const char *bus_id,
|
||||
struct device *parent)
|
||||
{
|
||||
struct of_device *dev;
|
||||
|
||||
|
@ -245,7 +247,7 @@ struct of_device* of_platform_device_create(struct device_node *np, const char *
|
|||
dev->node = np;
|
||||
dev->dma_mask = 0xffffffffUL;
|
||||
dev->dev.dma_mask = &dev->dma_mask;
|
||||
dev->dev.parent = NULL;
|
||||
dev->dev.parent = parent;
|
||||
dev->dev.bus = &of_platform_bus_type;
|
||||
dev->dev.release = of_release_dev;
|
||||
|
||||
|
@ -259,6 +261,7 @@ struct of_device* of_platform_device_create(struct device_node *np, const char *
|
|||
return dev;
|
||||
}
|
||||
|
||||
|
||||
EXPORT_SYMBOL(of_match_device);
|
||||
EXPORT_SYMBOL(of_platform_bus_type);
|
||||
EXPORT_SYMBOL(of_register_driver);
|
||||
|
|
|
@ -281,8 +281,10 @@ static void iommu_table_setparms(struct pci_controller *phb,
|
|||
tbl->it_offset = phb->dma_window_base_cur >> PAGE_SHIFT;
|
||||
|
||||
/* Test if we are going over 2GB of DMA space */
|
||||
if (phb->dma_window_base_cur + phb->dma_window_size > (1L << 31))
|
||||
if (phb->dma_window_base_cur + phb->dma_window_size > 0x80000000ul) {
|
||||
udbg_printf("PCI_DMA: Unexpected number of IOAs under this PHB.\n");
|
||||
panic("PCI_DMA: Unexpected number of IOAs under this PHB.\n");
|
||||
}
|
||||
|
||||
phb->dma_window_base_cur += phb->dma_window_size;
|
||||
|
||||
|
@ -326,92 +328,85 @@ static void iommu_table_setparms_lpar(struct pci_controller *phb,
|
|||
|
||||
static void iommu_bus_setup_pSeries(struct pci_bus *bus)
|
||||
{
|
||||
struct device_node *dn, *pdn;
|
||||
struct pci_dn *pci;
|
||||
struct device_node *dn;
|
||||
struct iommu_table *tbl;
|
||||
struct device_node *isa_dn, *isa_dn_orig;
|
||||
struct device_node *tmp;
|
||||
struct pci_dn *pci;
|
||||
int children;
|
||||
|
||||
DBG("iommu_bus_setup_pSeries, bus %p, bus->self %p\n", bus, bus->self);
|
||||
|
||||
/* For each (root) bus, we carve up the available DMA space in 256MB
|
||||
* pieces. Since each piece is used by one (sub) bus/device, that would
|
||||
* give a maximum of 7 devices per PHB. In most cases, this is plenty.
|
||||
*
|
||||
* The exception is on Python PHBs (pre-POWER4). Here we don't have EADS
|
||||
* bridges below the PHB to allocate the sectioned tables to, so instead
|
||||
* we allocate a 1GB table at the PHB level.
|
||||
*/
|
||||
|
||||
dn = pci_bus_to_OF_node(bus);
|
||||
pci = dn->data;
|
||||
pci = PCI_DN(dn);
|
||||
|
||||
if (!bus->self) {
|
||||
/* Root bus */
|
||||
if (is_python(dn)) {
|
||||
unsigned int *iohole;
|
||||
|
||||
DBG("Python root bus %s\n", bus->name);
|
||||
|
||||
iohole = (unsigned int *)get_property(dn, "io-hole", 0);
|
||||
|
||||
if (iohole) {
|
||||
/* On first bus we need to leave room for the
|
||||
* ISA address space. Just skip the first 256MB
|
||||
* alltogether. This leaves 768MB for the window.
|
||||
if (bus->self) {
|
||||
/* This is not a root bus, any setup will be done for the
|
||||
* device-side of the bridge in iommu_dev_setup_pSeries().
|
||||
*/
|
||||
DBG("PHB has io-hole, reserving 256MB\n");
|
||||
pci->phb->dma_window_size = 3 << 28;
|
||||
pci->phb->dma_window_base_cur = 1 << 28;
|
||||
} else {
|
||||
/* 1GB window by default */
|
||||
pci->phb->dma_window_size = 1 << 30;
|
||||
pci->phb->dma_window_base_cur = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
|
||||
/* Check if the ISA bus on the system is under
|
||||
* this PHB.
|
||||
*/
|
||||
isa_dn = isa_dn_orig = of_find_node_by_type(NULL, "isa");
|
||||
|
||||
iommu_table_setparms(pci->phb, dn, tbl);
|
||||
pci->iommu_table = iommu_init_table(tbl);
|
||||
} else {
|
||||
/* Do a 128MB table at root. This is used for the IDE
|
||||
* controller on some SMP-mode POWER4 machines. It
|
||||
* doesn't hurt to allocate it on other machines
|
||||
* -- it'll just be unused since new tables are
|
||||
* allocated on the EADS level.
|
||||
while (isa_dn && isa_dn != dn)
|
||||
isa_dn = isa_dn->parent;
|
||||
|
||||
if (isa_dn_orig)
|
||||
of_node_put(isa_dn_orig);
|
||||
|
||||
/* Count number of direct PCI children of the PHB.
|
||||
* All PCI device nodes have class-code property, so it's
|
||||
* an easy way to find them.
|
||||
*/
|
||||
for (children = 0, tmp = dn->child; tmp; tmp = tmp->sibling)
|
||||
if (get_property(tmp, "class-code", NULL))
|
||||
children++;
|
||||
|
||||
DBG("Children: %d\n", children);
|
||||
|
||||
/* Calculate amount of DMA window per slot. Each window must be
|
||||
* a power of two (due to pci_alloc_consistent requirements).
|
||||
*
|
||||
* Allocate at offset 128MB to avoid having to deal
|
||||
* with ISA holes; 128MB table for IDE is plenty.
|
||||
* Keep 256MB aside for PHBs with ISA.
|
||||
*/
|
||||
pci->phb->dma_window_size = 1 << 27;
|
||||
pci->phb->dma_window_base_cur = 1 << 27;
|
||||
|
||||
if (!isa_dn) {
|
||||
/* No ISA/IDE - just set window size and return */
|
||||
pci->phb->dma_window_size = 0x80000000ul; /* To be divided */
|
||||
|
||||
while (pci->phb->dma_window_size * children > 0x80000000ul)
|
||||
pci->phb->dma_window_size >>= 1;
|
||||
DBG("No ISA/IDE, window size is 0x%lx\n",
|
||||
pci->phb->dma_window_size);
|
||||
pci->phb->dma_window_base_cur = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* If we have ISA, then we probably have an IDE
|
||||
* controller too. Allocate a 128MB table but
|
||||
* skip the first 128MB to avoid stepping on ISA
|
||||
* space.
|
||||
*/
|
||||
pci->phb->dma_window_size = 0x8000000ul;
|
||||
pci->phb->dma_window_base_cur = 0x8000000ul;
|
||||
|
||||
tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
|
||||
|
||||
iommu_table_setparms(pci->phb, dn, tbl);
|
||||
pci->iommu_table = iommu_init_table(tbl);
|
||||
|
||||
/* All child buses have 256MB tables */
|
||||
pci->phb->dma_window_size = 1 << 28;
|
||||
}
|
||||
} else {
|
||||
pdn = pci_bus_to_OF_node(bus->parent);
|
||||
/* Divide the rest (1.75GB) among the children */
|
||||
pci->phb->dma_window_size = 0x80000000ul;
|
||||
while (pci->phb->dma_window_size * children > 0x70000000ul)
|
||||
pci->phb->dma_window_size >>= 1;
|
||||
|
||||
if (!bus->parent->self && !is_python(pdn)) {
|
||||
struct iommu_table *tbl;
|
||||
/* First child and not python means this is the EADS
|
||||
* level. Allocate new table for this slot with 256MB
|
||||
* window.
|
||||
*/
|
||||
DBG("ISA/IDE, window size is 0x%lx\n", pci->phb->dma_window_size);
|
||||
|
||||
tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
|
||||
|
||||
iommu_table_setparms(pci->phb, dn, tbl);
|
||||
|
||||
pci->iommu_table = iommu_init_table(tbl);
|
||||
} else {
|
||||
/* Lower than first child or under python, use parent table */
|
||||
pci->iommu_table = PCI_DN(pdn)->iommu_table;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -462,21 +457,36 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus)
|
|||
static void iommu_dev_setup_pSeries(struct pci_dev *dev)
|
||||
{
|
||||
struct device_node *dn, *mydn;
|
||||
struct iommu_table *tbl;
|
||||
|
||||
DBG("iommu_dev_setup_pSeries, dev %p (%s)\n", dev, pci_name(dev));
|
||||
|
||||
DBG("iommu_dev_setup_pSeries, dev %p (%s)\n", dev, dev->pretty_name);
|
||||
/* Now copy the iommu_table ptr from the bus device down to the
|
||||
* pci device_node. This means get_iommu_table() won't need to search
|
||||
* up the device tree to find it.
|
||||
*/
|
||||
mydn = dn = pci_device_to_OF_node(dev);
|
||||
|
||||
/* If we're the direct child of a root bus, then we need to allocate
|
||||
* an iommu table ourselves. The bus setup code should have setup
|
||||
* the window sizes already.
|
||||
*/
|
||||
if (!dev->bus->self) {
|
||||
DBG(" --> first child, no bridge. Allocating iommu table.\n");
|
||||
tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
|
||||
iommu_table_setparms(PCI_DN(dn)->phb, dn, tbl);
|
||||
PCI_DN(mydn)->iommu_table = iommu_init_table(tbl);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* If this device is further down the bus tree, search upwards until
|
||||
* an already allocated iommu table is found and use that.
|
||||
*/
|
||||
|
||||
while (dn && dn->data && PCI_DN(dn)->iommu_table == NULL)
|
||||
dn = dn->parent;
|
||||
|
||||
if (dn && dn->data) {
|
||||
PCI_DN(mydn)->iommu_table = PCI_DN(dn)->iommu_table;
|
||||
} else {
|
||||
DBG("iommu_dev_setup_pSeries, dev %p (%s) has no iommu table\n", dev, dev->pretty_name);
|
||||
DBG("iommu_dev_setup_pSeries, dev %p (%s) has no iommu table\n", dev, pci_name(dev));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -510,7 +520,7 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
|
|||
int *dma_window = NULL;
|
||||
struct pci_dn *pci;
|
||||
|
||||
DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, dev->pretty_name);
|
||||
DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, pci_name(dev));
|
||||
|
||||
/* dev setup for LPAR is a little tricky, since the device tree might
|
||||
* contain the dma-window properties per-device and not neccesarily
|
||||
|
@ -532,9 +542,8 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
|
|||
* slots on POWER4 machines.
|
||||
*/
|
||||
if (dma_window == NULL || pdn->parent == NULL) {
|
||||
/* Fall back to regular (non-LPAR) dev setup */
|
||||
DBG("No dma window for device, falling back to regular setup\n");
|
||||
iommu_dev_setup_pSeries(dev);
|
||||
DBG("No dma window for device, linking to parent\n");
|
||||
PCI_DN(dn)->iommu_table = PCI_DN(pdn)->iommu_table;
|
||||
return;
|
||||
} else {
|
||||
DBG("Found DMA window, allocating table\n");
|
||||
|
|
|
@ -246,11 +246,14 @@ static unsigned int pci_parse_of_flags(u32 addr0)
|
|||
unsigned int flags = 0;
|
||||
|
||||
if (addr0 & 0x02000000) {
|
||||
flags |= IORESOURCE_MEM;
|
||||
flags = IORESOURCE_MEM | PCI_BASE_ADDRESS_SPACE_MEMORY;
|
||||
flags |= (addr0 >> 22) & PCI_BASE_ADDRESS_MEM_TYPE_64;
|
||||
flags |= (addr0 >> 28) & PCI_BASE_ADDRESS_MEM_TYPE_1M;
|
||||
if (addr0 & 0x40000000)
|
||||
flags |= IORESOURCE_PREFETCH;
|
||||
flags |= IORESOURCE_PREFETCH
|
||||
| PCI_BASE_ADDRESS_MEM_PREFETCH;
|
||||
} else if (addr0 & 0x01000000)
|
||||
flags |= IORESOURCE_IO;
|
||||
flags = IORESOURCE_IO | PCI_BASE_ADDRESS_SPACE_IO;
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
|
|
@ -434,16 +434,24 @@ static int pmac_check_legacy_ioport(unsigned int baseport)
|
|||
|
||||
static int __init pmac_declare_of_platform_devices(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
struct device_node *np, *npp;
|
||||
|
||||
np = find_devices("u3");
|
||||
if (np) {
|
||||
for (np = np->child; np != NULL; np = np->sibling)
|
||||
npp = of_find_node_by_name(NULL, "u3");
|
||||
if (npp) {
|
||||
for (np = NULL; (np = of_get_next_child(npp, np)) != NULL;) {
|
||||
if (strncmp(np->name, "i2c", 3) == 0) {
|
||||
of_platform_device_create(np, "u3-i2c");
|
||||
of_platform_device_create(np, "u3-i2c", NULL);
|
||||
of_node_put(np);
|
||||
break;
|
||||
}
|
||||
}
|
||||
of_node_put(npp);
|
||||
}
|
||||
npp = of_find_node_by_type(NULL, "smu");
|
||||
if (npp) {
|
||||
of_platform_device_create(npp, "smu", NULL);
|
||||
of_node_put(npp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -84,7 +84,7 @@ void pmac_get_rtc_time(struct rtc_time *tm)
|
|||
|
||||
#ifdef CONFIG_PMAC_SMU
|
||||
case SYS_CTRLER_SMU:
|
||||
smu_get_rtc_time(tm);
|
||||
smu_get_rtc_time(tm, 1);
|
||||
break;
|
||||
#endif /* CONFIG_PMAC_SMU */
|
||||
default:
|
||||
|
@ -128,7 +128,7 @@ int pmac_set_rtc_time(struct rtc_time *tm)
|
|||
|
||||
#ifdef CONFIG_PMAC_SMU
|
||||
case SYS_CTRLER_SMU:
|
||||
return smu_set_rtc_time(tm);
|
||||
return smu_set_rtc_time(tm, 1);
|
||||
#endif /* CONFIG_PMAC_SMU */
|
||||
default:
|
||||
return -ENODEV;
|
||||
|
|
|
@ -1711,6 +1711,7 @@ static void __init flatten_device_tree(void)
|
|||
unsigned long offset = reloc_offset();
|
||||
unsigned long mem_start, mem_end, room;
|
||||
struct boot_param_header *hdr;
|
||||
struct prom_t *_prom = PTRRELOC(&prom);
|
||||
char *namep;
|
||||
u64 *rsvmap;
|
||||
|
||||
|
@ -1765,6 +1766,7 @@ static void __init flatten_device_tree(void)
|
|||
RELOC(dt_struct_end) = PAGE_ALIGN(mem_start);
|
||||
|
||||
/* Finish header */
|
||||
hdr->boot_cpuid_phys = _prom->cpu;
|
||||
hdr->magic = OF_DT_HEADER;
|
||||
hdr->totalsize = RELOC(dt_struct_end) - RELOC(dt_header_start);
|
||||
hdr->off_dt_struct = RELOC(dt_struct_start) - RELOC(dt_header_start);
|
||||
|
@ -1854,7 +1856,6 @@ static void __init prom_find_boot_cpu(void)
|
|||
|
||||
cpu_pkg = call_prom("instance-to-package", 1, 1, prom_cpu);
|
||||
|
||||
prom_setprop(cpu_pkg, "linux,boot-cpu", NULL, 0);
|
||||
prom_getprop(cpu_pkg, "reg", &getprop_rval, sizeof(getprop_rval));
|
||||
_prom->cpu = getprop_rval;
|
||||
|
||||
|
|
|
@ -219,6 +219,7 @@ int sys_ptrace(long request, long pid, long addr, long data)
|
|||
|
||||
case PTRACE_SET_DEBUGREG:
|
||||
ret = ptrace_set_debugreg(child, addr, data);
|
||||
break;
|
||||
|
||||
case PTRACE_DETACH:
|
||||
ret = ptrace_detach(child, data);
|
||||
|
|
|
@ -342,15 +342,14 @@ static void native_flush_hash_range(unsigned long number, int local)
|
|||
hpte_t *hptep;
|
||||
unsigned long hpte_v;
|
||||
struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
|
||||
|
||||
/* XXX fix for large ptes */
|
||||
unsigned long large = 0;
|
||||
unsigned long large;
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
j = 0;
|
||||
for (i = 0; i < number; i++) {
|
||||
va = batch->vaddr[j];
|
||||
large = pte_huge(batch->pte[i]);
|
||||
if (large)
|
||||
vpn = va >> HPAGE_SHIFT;
|
||||
else
|
||||
|
|
|
@ -710,10 +710,13 @@ repeat:
|
|||
hpte_group = ((~hash & htab_hash_mask) *
|
||||
HPTES_PER_GROUP) & ~0x7UL;
|
||||
slot = ppc_md.hpte_insert(hpte_group, va, prpn,
|
||||
HPTE_V_LARGE, rflags);
|
||||
HPTE_V_LARGE |
|
||||
HPTE_V_SECONDARY,
|
||||
rflags);
|
||||
if (slot == -1) {
|
||||
if (mftb() & 0x1)
|
||||
hpte_group = ((hash & htab_hash_mask) * HPTES_PER_GROUP) & ~0x7UL;
|
||||
hpte_group = ((hash & htab_hash_mask) *
|
||||
HPTES_PER_GROUP)&~0x7UL;
|
||||
|
||||
ppc_md.hpte_remove(hpte_group);
|
||||
goto repeat;
|
||||
|
|
|
@ -42,19 +42,15 @@
|
|||
* executing (see inherit_locked_prom_mappings() rant).
|
||||
*/
|
||||
sparc64_vpte_nucleus:
|
||||
/* Load 0xf0000000, which is LOW_OBP_ADDRESS. */
|
||||
mov 0xf, %g5
|
||||
sllx %g5, 28, %g5
|
||||
|
||||
/* Is addr >= LOW_OBP_ADDRESS? */
|
||||
/* Note that kvmap below has verified that the address is
|
||||
* in the range MODULES_VADDR --> VMALLOC_END already. So
|
||||
* here we need only check if it is an OBP address or not.
|
||||
*/
|
||||
sethi %hi(LOW_OBP_ADDRESS), %g5
|
||||
cmp %g4, %g5
|
||||
blu,pn %xcc, sparc64_vpte_patchme1
|
||||
mov 0x1, %g5
|
||||
|
||||
/* Load 0x100000000, which is HI_OBP_ADDRESS. */
|
||||
sllx %g5, 32, %g5
|
||||
|
||||
/* Is addr < HI_OBP_ADDRESS? */
|
||||
cmp %g4, %g5
|
||||
blu,pn %xcc, obp_iaddr_patch
|
||||
nop
|
||||
|
@ -156,26 +152,29 @@ obp_daddr_patch:
|
|||
* rather, use information saved during inherit_prom_mappings() using 8k
|
||||
* pagesize.
|
||||
*/
|
||||
.align 32
|
||||
kvmap:
|
||||
/* Load 0xf0000000, which is LOW_OBP_ADDRESS. */
|
||||
mov 0xf, %g5
|
||||
sllx %g5, 28, %g5
|
||||
|
||||
/* Is addr >= LOW_OBP_ADDRESS? */
|
||||
sethi %hi(MODULES_VADDR), %g5
|
||||
cmp %g4, %g5
|
||||
blu,pn %xcc, vmalloc_addr
|
||||
blu,pn %xcc, longpath
|
||||
mov (VMALLOC_END >> 24), %g5
|
||||
sllx %g5, 24, %g5
|
||||
cmp %g4, %g5
|
||||
bgeu,pn %xcc, longpath
|
||||
nop
|
||||
|
||||
kvmap_check_obp:
|
||||
sethi %hi(LOW_OBP_ADDRESS), %g5
|
||||
cmp %g4, %g5
|
||||
blu,pn %xcc, kvmap_vmalloc_addr
|
||||
mov 0x1, %g5
|
||||
|
||||
/* Load 0x100000000, which is HI_OBP_ADDRESS. */
|
||||
sllx %g5, 32, %g5
|
||||
|
||||
/* Is addr < HI_OBP_ADDRESS? */
|
||||
cmp %g4, %g5
|
||||
blu,pn %xcc, obp_daddr_patch
|
||||
nop
|
||||
|
||||
vmalloc_addr:
|
||||
/* If we get here, a vmalloc addr accessed, load kernel VPTE. */
|
||||
kvmap_vmalloc_addr:
|
||||
/* If we get here, a vmalloc addr was accessed, load kernel VPTE. */
|
||||
ldxa [%g3 + %g6] ASI_N, %g5
|
||||
brgez,pn %g5, longpath
|
||||
nop
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <asm/psrcompat.h>
|
||||
#include <asm/visasm.h>
|
||||
#include <asm/spitfire.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
/* Returning from ptrace is a bit tricky because the syscall return
|
||||
* low level code assumes any value returned which is negative and
|
||||
|
@ -128,20 +129,20 @@ void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
|
|||
* is mapped to in the user's address space, we can skip the
|
||||
* D-cache flush.
|
||||
*/
|
||||
if ((uaddr ^ kaddr) & (1UL << 13)) {
|
||||
if ((uaddr ^ (unsigned long) kaddr) & (1UL << 13)) {
|
||||
unsigned long start = __pa(kaddr);
|
||||
unsigned long end = start + len;
|
||||
|
||||
if (tlb_type == spitfire) {
|
||||
for (; start < end; start += 32)
|
||||
spitfire_put_dcache_tag(va & 0x3fe0, 0x0);
|
||||
spitfire_put_dcache_tag(start & 0x3fe0, 0x0);
|
||||
} else {
|
||||
for (; start < end; start += 32)
|
||||
__asm__ __volatile__(
|
||||
"stxa %%g0, [%0] %1\n\t"
|
||||
"membar #Sync"
|
||||
: /* no outputs */
|
||||
: "r" (va),
|
||||
: "r" (start),
|
||||
"i" (ASI_DCACHE_INVALIDATE));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ kernel_unaligned_trap_fault:
|
|||
__do_int_store:
|
||||
rd %asi, %o4
|
||||
wr %o3, 0, %asi
|
||||
ldx [%o2], %g3
|
||||
mov %o2, %g3
|
||||
cmp %o1, 2
|
||||
be,pn %icc, 2f
|
||||
cmp %o1, 4
|
||||
|
|
|
@ -184,13 +184,14 @@ extern void do_int_load(unsigned long *dest_reg, int size,
|
|||
unsigned long *saddr, int is_signed, int asi);
|
||||
|
||||
extern void __do_int_store(unsigned long *dst_addr, int size,
|
||||
unsigned long *src_val, int asi);
|
||||
unsigned long src_val, int asi);
|
||||
|
||||
static inline void do_int_store(int reg_num, int size, unsigned long *dst_addr,
|
||||
struct pt_regs *regs, int asi)
|
||||
struct pt_regs *regs, int asi, int orig_asi)
|
||||
{
|
||||
unsigned long zero = 0;
|
||||
unsigned long *src_val = &zero;
|
||||
unsigned long *src_val_p = &zero;
|
||||
unsigned long src_val;
|
||||
|
||||
if (size == 16) {
|
||||
size = 8;
|
||||
|
@ -198,7 +199,25 @@ static inline void do_int_store(int reg_num, int size, unsigned long *dst_addr,
|
|||
(unsigned)fetch_reg(reg_num, regs) : 0)) << 32) |
|
||||
(unsigned)fetch_reg(reg_num + 1, regs);
|
||||
} else if (reg_num) {
|
||||
src_val = fetch_reg_addr(reg_num, regs);
|
||||
src_val_p = fetch_reg_addr(reg_num, regs);
|
||||
}
|
||||
src_val = *src_val_p;
|
||||
if (unlikely(asi != orig_asi)) {
|
||||
switch (size) {
|
||||
case 2:
|
||||
src_val = swab16(src_val);
|
||||
break;
|
||||
case 4:
|
||||
src_val = swab32(src_val);
|
||||
break;
|
||||
case 8:
|
||||
src_val = swab64(src_val);
|
||||
break;
|
||||
case 16:
|
||||
default:
|
||||
BUG();
|
||||
break;
|
||||
};
|
||||
}
|
||||
__do_int_store(dst_addr, size, src_val, asi);
|
||||
}
|
||||
|
@ -276,6 +295,7 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn, u
|
|||
kernel_mna_trap_fault();
|
||||
} else {
|
||||
unsigned long addr;
|
||||
int orig_asi, asi;
|
||||
|
||||
addr = compute_effective_address(regs, insn,
|
||||
((insn >> 25) & 0x1f));
|
||||
|
@ -285,18 +305,48 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn, u
|
|||
regs->tpc, dirstrings[dir], addr, size,
|
||||
regs->u_regs[UREG_RETPC]);
|
||||
#endif
|
||||
orig_asi = asi = decode_asi(insn, regs);
|
||||
switch (asi) {
|
||||
case ASI_NL:
|
||||
case ASI_AIUPL:
|
||||
case ASI_AIUSL:
|
||||
case ASI_PL:
|
||||
case ASI_SL:
|
||||
case ASI_PNFL:
|
||||
case ASI_SNFL:
|
||||
asi &= ~0x08;
|
||||
break;
|
||||
};
|
||||
switch (dir) {
|
||||
case load:
|
||||
do_int_load(fetch_reg_addr(((insn>>25)&0x1f), regs),
|
||||
size, (unsigned long *) addr,
|
||||
decode_signedness(insn),
|
||||
decode_asi(insn, regs));
|
||||
decode_signedness(insn), asi);
|
||||
if (unlikely(asi != orig_asi)) {
|
||||
unsigned long val_in = *(unsigned long *) addr;
|
||||
switch (size) {
|
||||
case 2:
|
||||
val_in = swab16(val_in);
|
||||
break;
|
||||
case 4:
|
||||
val_in = swab32(val_in);
|
||||
break;
|
||||
case 8:
|
||||
val_in = swab64(val_in);
|
||||
break;
|
||||
case 16:
|
||||
default:
|
||||
BUG();
|
||||
break;
|
||||
};
|
||||
*(unsigned long *) addr = val_in;
|
||||
}
|
||||
break;
|
||||
|
||||
case store:
|
||||
do_int_store(((insn>>25)&0x1f), size,
|
||||
(unsigned long *) addr, regs,
|
||||
decode_asi(insn, regs));
|
||||
asi, orig_asi);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -53,9 +53,13 @@ SYS_DIR := $(ARCH_DIR)/include/sysdep-$(SUBARCH)
|
|||
|
||||
# -Dvmap=kernel_vmap affects everything, and prevents anything from
|
||||
# referencing the libpcap.o symbol so named.
|
||||
#
|
||||
# Same things for in6addr_loopback - found in libc.
|
||||
|
||||
CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
|
||||
$(ARCH_INCLUDE) $(MODE_INCLUDE) -Dvmap=kernel_vmap
|
||||
$(ARCH_INCLUDE) $(MODE_INCLUDE) -Dvmap=kernel_vmap \
|
||||
-Din6addr_loopback=kernel_in6addr_loopback
|
||||
|
||||
AFLAGS += $(ARCH_INCLUDE)
|
||||
|
||||
USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))
|
||||
|
|
|
@ -19,18 +19,44 @@
|
|||
#include "line.h"
|
||||
#include "os.h"
|
||||
|
||||
#ifdef CONFIG_NOCONFIG_CHAN
|
||||
/* XXX: could well be moved to somewhere else, if needed. */
|
||||
static int my_printf(const char * fmt, ...)
|
||||
__attribute__ ((format (printf, 1, 2)));
|
||||
|
||||
/* The printk's here are wrong because we are complaining that there is no
|
||||
* output device, but printk is printing to that output device. The user will
|
||||
* never see the error. printf would be better, except it can't run on a
|
||||
* kernel stack because it will overflow it.
|
||||
* Use printk for now since that will avoid crashing.
|
||||
*/
|
||||
static int my_printf(const char * fmt, ...)
|
||||
{
|
||||
/* Yes, can be called on atomic context.*/
|
||||
char *buf = kmalloc(4096, GFP_ATOMIC);
|
||||
va_list args;
|
||||
int r;
|
||||
|
||||
if (!buf) {
|
||||
/* We print directly fmt.
|
||||
* Yes, yes, yes, feel free to complain. */
|
||||
r = strlen(fmt);
|
||||
} else {
|
||||
va_start(args, fmt);
|
||||
r = vsprintf(buf, fmt, args);
|
||||
va_end(args);
|
||||
fmt = buf;
|
||||
}
|
||||
|
||||
if (r)
|
||||
r = os_write_file(1, fmt, r);
|
||||
return r;
|
||||
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NOCONFIG_CHAN
|
||||
/* Despite its name, there's no added trailing newline. */
|
||||
static int my_puts(const char * buf)
|
||||
{
|
||||
return os_write_file(1, buf, strlen(buf));
|
||||
}
|
||||
|
||||
static void *not_configged_init(char *str, int device, struct chan_opts *opts)
|
||||
{
|
||||
printk(KERN_ERR "Using a channel type which is configured out of "
|
||||
my_puts("Using a channel type which is configured out of "
|
||||
"UML\n");
|
||||
return(NULL);
|
||||
}
|
||||
|
@ -38,27 +64,27 @@ static void *not_configged_init(char *str, int device, struct chan_opts *opts)
|
|||
static int not_configged_open(int input, int output, int primary, void *data,
|
||||
char **dev_out)
|
||||
{
|
||||
printk(KERN_ERR "Using a channel type which is configured out of "
|
||||
my_puts("Using a channel type which is configured out of "
|
||||
"UML\n");
|
||||
return(-ENODEV);
|
||||
}
|
||||
|
||||
static void not_configged_close(int fd, void *data)
|
||||
{
|
||||
printk(KERN_ERR "Using a channel type which is configured out of "
|
||||
my_puts("Using a channel type which is configured out of "
|
||||
"UML\n");
|
||||
}
|
||||
|
||||
static int not_configged_read(int fd, char *c_out, void *data)
|
||||
{
|
||||
printk(KERN_ERR "Using a channel type which is configured out of "
|
||||
my_puts("Using a channel type which is configured out of "
|
||||
"UML\n");
|
||||
return(-EIO);
|
||||
}
|
||||
|
||||
static int not_configged_write(int fd, const char *buf, int len, void *data)
|
||||
{
|
||||
printk(KERN_ERR "Using a channel type which is configured out of "
|
||||
my_puts("Using a channel type which is configured out of "
|
||||
"UML\n");
|
||||
return(-EIO);
|
||||
}
|
||||
|
@ -66,7 +92,7 @@ static int not_configged_write(int fd, const char *buf, int len, void *data)
|
|||
static int not_configged_console_write(int fd, const char *buf, int len,
|
||||
void *data)
|
||||
{
|
||||
printk(KERN_ERR "Using a channel type which is configured out of "
|
||||
my_puts("Using a channel type which is configured out of "
|
||||
"UML\n");
|
||||
return(-EIO);
|
||||
}
|
||||
|
@ -74,14 +100,14 @@ static int not_configged_console_write(int fd, const char *buf, int len,
|
|||
static int not_configged_window_size(int fd, void *data, unsigned short *rows,
|
||||
unsigned short *cols)
|
||||
{
|
||||
printk(KERN_ERR "Using a channel type which is configured out of "
|
||||
my_puts("Using a channel type which is configured out of "
|
||||
"UML\n");
|
||||
return(-ENODEV);
|
||||
}
|
||||
|
||||
static void not_configged_free(void *data)
|
||||
{
|
||||
printf(KERN_ERR "Using a channel type which is configured out of "
|
||||
my_puts("Using a channel type which is configured out of "
|
||||
"UML\n");
|
||||
}
|
||||
|
||||
|
@ -457,7 +483,7 @@ static struct chan *parse_chan(char *str, int pri, int device,
|
|||
}
|
||||
}
|
||||
if(ops == NULL){
|
||||
printk(KERN_ERR "parse_chan couldn't parse \"%s\"\n",
|
||||
my_printf("parse_chan couldn't parse \"%s\"\n",
|
||||
str);
|
||||
return(NULL);
|
||||
}
|
||||
|
@ -465,7 +491,7 @@ static struct chan *parse_chan(char *str, int pri, int device,
|
|||
data = (*ops->init)(str, device, opts);
|
||||
if(data == NULL) return(NULL);
|
||||
|
||||
chan = kmalloc(sizeof(*chan), GFP_KERNEL);
|
||||
chan = kmalloc(sizeof(*chan), GFP_ATOMIC);
|
||||
if(chan == NULL) return(NULL);
|
||||
*chan = ((struct chan) { .list = LIST_HEAD_INIT(chan->list),
|
||||
.primary = 1,
|
||||
|
|
|
@ -23,7 +23,7 @@ static struct mconsole_command commands[] = {
|
|||
{ "reboot", mconsole_reboot, MCONSOLE_PROC },
|
||||
{ "config", mconsole_config, MCONSOLE_PROC },
|
||||
{ "remove", mconsole_remove, MCONSOLE_PROC },
|
||||
{ "sysrq", mconsole_sysrq, MCONSOLE_INTR },
|
||||
{ "sysrq", mconsole_sysrq, MCONSOLE_PROC },
|
||||
{ "help", mconsole_help, MCONSOLE_INTR },
|
||||
{ "cad", mconsole_cad, MCONSOLE_INTR },
|
||||
{ "stop", mconsole_stop, MCONSOLE_PROC },
|
||||
|
|
|
@ -12,4 +12,6 @@ DEFINE_STR(UM_KERN_WARNING, KERN_WARNING);
|
|||
DEFINE_STR(UM_KERN_NOTICE, KERN_NOTICE);
|
||||
DEFINE_STR(UM_KERN_INFO, KERN_INFO);
|
||||
DEFINE_STR(UM_KERN_DEBUG, KERN_DEBUG);
|
||||
DEFINE(HOST_ELF_CLASS, ELF_CLASS);
|
||||
DEFINE(UM_ELF_CLASS, ELF_CLASS);
|
||||
DEFINE(UM_ELFCLASS32, ELFCLASS32);
|
||||
DEFINE(UM_ELFCLASS64, ELFCLASS64);
|
||||
|
|
|
@ -14,7 +14,9 @@ extern void *um_kmalloc_atomic(int size);
|
|||
extern void kfree(void *ptr);
|
||||
extern int in_aton(char *str);
|
||||
extern int open_gdb_chan(void);
|
||||
extern int strlcpy(char *, const char *, int);
|
||||
/* These use size_t, however unsigned long is correct on both i386 and x86_64. */
|
||||
extern unsigned long strlcpy(char *, const char *, unsigned long);
|
||||
extern unsigned long strlcat(char *, const char *, unsigned long);
|
||||
extern void *um_vmalloc(int size);
|
||||
extern void vfree(void *ptr);
|
||||
|
||||
|
|
|
@ -82,7 +82,8 @@ unsigned long alloc_stack(int order, int atomic)
|
|||
unsigned long page;
|
||||
int flags = GFP_KERNEL;
|
||||
|
||||
if(atomic) flags |= GFP_ATOMIC;
|
||||
if (atomic)
|
||||
flags = GFP_ATOMIC;
|
||||
page = __get_free_pages(flags, order);
|
||||
if(page == 0)
|
||||
return(0);
|
||||
|
|
|
@ -340,7 +340,7 @@ static int setup_initial_poll(int fd)
|
|||
{
|
||||
struct pollfd *p;
|
||||
|
||||
p = um_kmalloc(sizeof(struct pollfd));
|
||||
p = um_kmalloc_atomic(sizeof(struct pollfd));
|
||||
if(p == NULL){
|
||||
printk("setup_initial_poll : failed to allocate poll\n");
|
||||
return(-1);
|
||||
|
|
|
@ -18,12 +18,6 @@
|
|||
((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \
|
||||
((unsigned long) (addr) + (size) >= (unsigned long)(addr))))
|
||||
|
||||
static inline int verify_area_skas(int type, const void __user * addr,
|
||||
unsigned long size)
|
||||
{
|
||||
return(access_ok_skas(type, addr, size) ? 0 : -EFAULT);
|
||||
}
|
||||
|
||||
extern int copy_from_user_skas(void *to, const void __user *from, int n);
|
||||
extern int copy_to_user_skas(void __user *to, const void *from, int n);
|
||||
extern int strncpy_from_user_skas(char *dst, const char __user *src, int count);
|
||||
|
|
|
@ -193,11 +193,11 @@ void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
|
|||
r = pte_read(*npte);
|
||||
w = pte_write(*npte);
|
||||
x = pte_exec(*npte);
|
||||
if(!pte_dirty(*npte))
|
||||
w = 0;
|
||||
if (!pte_young(*npte)) {
|
||||
r = 0;
|
||||
w = 0;
|
||||
} else if (!pte_dirty(*npte)) {
|
||||
w = 0;
|
||||
}
|
||||
if(force || pte_newpage(*npte)){
|
||||
if(pte_present(*npte))
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "asm/a.out.h"
|
||||
#include "asm/current.h"
|
||||
#include "asm/irq.h"
|
||||
#include "sysdep/sigcontext.h"
|
||||
#include "user_util.h"
|
||||
#include "kern_util.h"
|
||||
#include "kern.h"
|
||||
|
@ -39,6 +40,12 @@ int handle_page_fault(unsigned long address, unsigned long ip,
|
|||
int err = -EFAULT;
|
||||
|
||||
*code_out = SEGV_MAPERR;
|
||||
|
||||
/* If the fault was during atomic operation, don't take the fault, just
|
||||
* fail. */
|
||||
if (in_atomic())
|
||||
goto out_nosemaphore;
|
||||
|
||||
down_read(&mm->mmap_sem);
|
||||
vma = find_vma(mm, address);
|
||||
if(!vma)
|
||||
|
@ -89,6 +96,7 @@ survive:
|
|||
flush_tlb_page(vma, address);
|
||||
out:
|
||||
up_read(&mm->mmap_sem);
|
||||
out_nosemaphore:
|
||||
return(err);
|
||||
|
||||
/*
|
||||
|
@ -125,7 +133,15 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc)
|
|||
}
|
||||
else if(current->mm == NULL)
|
||||
panic("Segfault with no mm");
|
||||
|
||||
if (SEGV_IS_FIXABLE(&fi))
|
||||
err = handle_page_fault(address, ip, is_write, is_user, &si.si_code);
|
||||
else {
|
||||
err = -EFAULT;
|
||||
/* A thread accessed NULL, we get a fault, but CR2 is invalid.
|
||||
* This code is used in __do_copy_from_user() of TT mode. */
|
||||
address = 0;
|
||||
}
|
||||
|
||||
catcher = current->thread.fault_catcher;
|
||||
if(!err)
|
||||
|
|
|
@ -33,12 +33,6 @@ extern unsigned long uml_physmem;
|
|||
(((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \
|
||||
(under_task_size(addr, size) || is_stack(addr, size))))
|
||||
|
||||
static inline int verify_area_tt(int type, const void __user * addr,
|
||||
unsigned long size)
|
||||
{
|
||||
return(access_ok_tt(type, addr, size) ? 0 : -EFAULT);
|
||||
}
|
||||
|
||||
extern unsigned long get_fault_addr(void);
|
||||
|
||||
extern int __do_copy_from_user(void *to, const void *from, int n,
|
||||
|
|
|
@ -23,10 +23,11 @@
|
|||
#include "mem_user.h"
|
||||
#include "tlb.h"
|
||||
#include "mode.h"
|
||||
#include "mode_kern.h"
|
||||
#include "init.h"
|
||||
#include "tt.h"
|
||||
|
||||
int switch_to_tt(void *prev, void *next, void *last)
|
||||
void switch_to_tt(void *prev, void *next)
|
||||
{
|
||||
struct task_struct *from, *to, *prev_sched;
|
||||
unsigned long flags;
|
||||
|
|
|
@ -22,8 +22,15 @@ int __do_copy_from_user(void *to, const void *from, int n,
|
|||
__do_copy, &faulted);
|
||||
TASK_REGS(get_current())->tt = save;
|
||||
|
||||
if(!faulted) return(0);
|
||||
else return(n - (fault - (unsigned long) from));
|
||||
if(!faulted)
|
||||
return 0;
|
||||
else if (fault)
|
||||
return n - (fault - (unsigned long) from);
|
||||
else
|
||||
/* In case of a general protection fault, we don't have the
|
||||
* fault address, so NULL is used instead. Pretend we didn't
|
||||
* copy anything. */
|
||||
return n;
|
||||
}
|
||||
|
||||
static void __do_strncpy(void *dst, const void *src, int count)
|
||||
|
|
|
@ -31,6 +31,8 @@ static char *uml_dir = UML_DIR;
|
|||
/* Changed by set_umid */
|
||||
static int umid_is_random = 1;
|
||||
static int umid_inited = 0;
|
||||
/* Have we created the files? Should we remove them? */
|
||||
static int umid_owned = 0;
|
||||
|
||||
static int make_umid(int (*printer)(const char *fmt, ...));
|
||||
|
||||
|
@ -82,20 +84,21 @@ int __init umid_file_name(char *name, char *buf, int len)
|
|||
|
||||
extern int tracing_pid;
|
||||
|
||||
static int __init create_pid_file(void)
|
||||
static void __init create_pid_file(void)
|
||||
{
|
||||
char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
|
||||
char pid[sizeof("nnnnn\0")];
|
||||
int fd, n;
|
||||
|
||||
if(umid_file_name("pid", file, sizeof(file))) return 0;
|
||||
if(umid_file_name("pid", file, sizeof(file)))
|
||||
return;
|
||||
|
||||
fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))),
|
||||
0644);
|
||||
if(fd < 0){
|
||||
printf("Open of machine pid file \"%s\" failed: %s\n",
|
||||
file, strerror(-fd));
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
sprintf(pid, "%d\n", os_getpid());
|
||||
|
@ -103,7 +106,6 @@ static int __init create_pid_file(void)
|
|||
if(n != strlen(pid))
|
||||
printf("Write of pid file failed - err = %d\n", -n);
|
||||
os_close_file(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int actually_do_remove(char *dir)
|
||||
|
@ -147,7 +149,8 @@ static int actually_do_remove(char *dir)
|
|||
void remove_umid_dir(void)
|
||||
{
|
||||
char dir[strlen(uml_dir) + UMID_LEN + 1];
|
||||
if(!umid_inited) return;
|
||||
if (!umid_owned)
|
||||
return;
|
||||
|
||||
sprintf(dir, "%s%s", uml_dir, umid);
|
||||
actually_do_remove(dir);
|
||||
|
@ -155,11 +158,12 @@ void remove_umid_dir(void)
|
|||
|
||||
char *get_umid(int only_if_set)
|
||||
{
|
||||
if(only_if_set && umid_is_random) return(NULL);
|
||||
return(umid);
|
||||
if(only_if_set && umid_is_random)
|
||||
return NULL;
|
||||
return umid;
|
||||
}
|
||||
|
||||
int not_dead_yet(char *dir)
|
||||
static int not_dead_yet(char *dir)
|
||||
{
|
||||
char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
|
||||
char pid[sizeof("nnnnn\0")], *end;
|
||||
|
@ -193,7 +197,8 @@ int not_dead_yet(char *dir)
|
|||
(p == CHOOSE_MODE(tracing_pid, os_getpid())))
|
||||
dead = 1;
|
||||
}
|
||||
if(!dead) return(1);
|
||||
if(!dead)
|
||||
return(1);
|
||||
return(actually_do_remove(dir));
|
||||
}
|
||||
|
||||
|
@ -232,13 +237,10 @@ static int __init make_uml_dir(void)
|
|||
strlcpy(dir, home, sizeof(dir));
|
||||
uml_dir++;
|
||||
}
|
||||
strlcat(dir, uml_dir, sizeof(dir));
|
||||
len = strlen(dir);
|
||||
strncat(dir, uml_dir, sizeof(dir) - len);
|
||||
len = strlen(dir);
|
||||
if((len > 0) && (len < sizeof(dir) - 1) && (dir[len - 1] != '/')){
|
||||
dir[len] = '/';
|
||||
dir[len + 1] = '\0';
|
||||
}
|
||||
if (len > 0 && dir[len - 1] != '/')
|
||||
strlcat(dir, "/", sizeof(dir));
|
||||
|
||||
uml_dir = malloc(strlen(dir) + 1);
|
||||
if (uml_dir == NULL) {
|
||||
|
@ -286,6 +288,7 @@ static int __init make_umid(int (*printer)(const char *fmt, ...))
|
|||
if(errno == EEXIST){
|
||||
if(not_dead_yet(tmp)){
|
||||
(*printer)("umid '%s' is in use\n", umid);
|
||||
umid_owned = 0;
|
||||
return(-1);
|
||||
}
|
||||
err = mkdir(tmp, 0777);
|
||||
|
@ -296,7 +299,8 @@ static int __init make_umid(int (*printer)(const char *fmt, ...))
|
|||
return(-1);
|
||||
}
|
||||
|
||||
return(0);
|
||||
umid_owned = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
__uml_setup("uml_dir=", set_uml_dir,
|
||||
|
@ -309,7 +313,8 @@ static int __init make_umid_setup(void)
|
|||
/* one function with the ordering we need ... */
|
||||
make_uml_dir();
|
||||
make_umid(printf);
|
||||
return create_pid_file();
|
||||
create_pid_file();
|
||||
return 0;
|
||||
}
|
||||
__uml_postsetup(make_umid_setup);
|
||||
|
||||
|
|
|
@ -128,6 +128,12 @@ void setup_machinename(char *machine_out)
|
|||
struct utsname host;
|
||||
|
||||
uname(&host);
|
||||
#if defined(UML_CONFIG_UML_X86) && !defined(UML_CONFIG_64BIT)
|
||||
if (!strcmp(host.machine, "x86_64")) {
|
||||
strcpy(machine_out, "i686");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
strcpy(machine_out, host.machine);
|
||||
}
|
||||
|
||||
|
|
|
@ -144,6 +144,7 @@ static int aio_thread(void *arg)
|
|||
"errno = %d\n", errno);
|
||||
}
|
||||
else {
|
||||
/* This is safe as we've just a pointer here. */
|
||||
aio = (struct aio_context *) (long) event.data;
|
||||
if(update_aio(aio, event.res)){
|
||||
do_aio(ctx, aio);
|
||||
|
|
|
@ -14,7 +14,8 @@
|
|||
#include "mem_user.h"
|
||||
#include <kernel-offsets.h>
|
||||
|
||||
#if HOST_ELF_CLASS == ELFCLASS32
|
||||
/* Use the one from the kernel - the host may miss it, if having old headers. */
|
||||
#if UM_ELF_CLASS == UM_ELFCLASS32
|
||||
typedef Elf32_auxv_t elf_auxv_t;
|
||||
#else
|
||||
typedef Elf64_auxv_t elf_auxv_t;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
|
|
|
@ -83,6 +83,7 @@ int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
|
|||
goto out;
|
||||
}
|
||||
p = buf;
|
||||
break;
|
||||
default:
|
||||
res = -ENOSYS;
|
||||
goto out;
|
||||
|
|
|
@ -308,7 +308,7 @@ config HPET_TIMER
|
|||
present. The HPET provides a stable time base on SMP
|
||||
systems, unlike the TSC, but it is more expensive to access,
|
||||
as it is off-chip. You can find the HPET spec at
|
||||
<http://www.intel.com/labs/platcomp/hpet/hpetspec.htm>.
|
||||
<http://www.intel.com/hardwaredesign/hpetspec.htm>.
|
||||
|
||||
config X86_PM_TIMER
|
||||
bool "PM timer"
|
||||
|
|
|
@ -402,7 +402,7 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
|
|||
__pci_mmap_set_flags(dev, vma, mmap_state);
|
||||
__pci_mmap_set_pgprot(dev, vma, mmap_state, write_combine);
|
||||
|
||||
ret = io_remap_page_range(vma, vma->vm_start, vma->vm_pgoff<<PAGE_SHIFT,
|
||||
ret = io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
|
||||
vma->vm_end - vma->vm_start,vma->vm_page_prot);
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -39,7 +39,7 @@ _F(int, pcibios_fixup, (void), { return 0; });
|
|||
_F(int, get_rtc_time, (time_t* t), { return 0; });
|
||||
_F(int, set_rtc_time, (time_t t), { return 0; });
|
||||
|
||||
#if CONFIG_XTENSA_CALIBRATE_CCOUNT
|
||||
#ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
|
||||
_F(void, calibrate_ccount, (void),
|
||||
{
|
||||
printk ("ERROR: Cannot calibrate cpu frequency! Assuming 100MHz.\n");
|
||||
|
|
|
@ -457,7 +457,7 @@ int
|
|||
dump_task_fpu(struct pt_regs *regs, struct task_struct *task, elf_fpregset_t *r)
|
||||
{
|
||||
/* see asm/coprocessor.h for this magic number 16 */
|
||||
#if TOTAL_CPEXTRA_SIZE > 16
|
||||
#if XTENSA_CP_EXTRA_SIZE > 16
|
||||
do_save_fpregs (r, regs, task);
|
||||
|
||||
/* For now, bit 16 means some extra state may be present: */
|
||||
|
|
|
@ -304,7 +304,7 @@ void __init setup_arch(char **cmdline_p)
|
|||
# endif
|
||||
#endif
|
||||
|
||||
#if CONFIG_PCI
|
||||
#ifdef CONFIG_PCI
|
||||
platform_pcibios_init();
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -182,7 +182,7 @@ restore_cpextra (struct _cpstate *buf)
|
|||
|
||||
struct task_struct *tsk = current;
|
||||
release_all_cp(tsk);
|
||||
return __copy_from_user(tsk->thread.cpextra, buf, TOTAL_CPEXTRA_SIZE);
|
||||
return __copy_from_user(tsk->thread.cpextra, buf, XTENSA_CP_EXTRA_SIZE);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ void __init time_init(void)
|
|||
* speed for the CALIBRATE.
|
||||
*/
|
||||
|
||||
#if CONFIG_XTENSA_CALIBRATE_CCOUNT
|
||||
#ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
|
||||
printk("Calibrating CPU frequency ");
|
||||
platform_calibrate_ccount();
|
||||
printk("%d.%02d MHz\n", (int)ccount_per_jiffy/(1000000/HZ),
|
||||
|
|
|
@ -239,7 +239,7 @@ void __init mem_init(void)
|
|||
high_memory = (void *) __va(max_mapnr << PAGE_SHIFT);
|
||||
highmemsize = 0;
|
||||
|
||||
#if CONFIG_HIGHMEM
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
#error HIGHGMEM not implemented in init.c
|
||||
#endif
|
||||
|
||||
|
|
|
@ -23,12 +23,13 @@ static struct i2c_driver pcf8583_driver;
|
|||
|
||||
static unsigned short ignore[] = { I2C_CLIENT_END };
|
||||
static unsigned short normal_addr[] = { 0x50, I2C_CLIENT_END };
|
||||
static unsigned short *forces[] = { NULL };
|
||||
|
||||
static struct i2c_client_address_data addr_data = {
|
||||
.normal_i2c = normal_addr,
|
||||
.probe = ignore,
|
||||
.ignore = ignore,
|
||||
.force = ignore,
|
||||
.forces = forces,
|
||||
};
|
||||
|
||||
#define DAT(x) ((unsigned int)(x->dev.driver_data))
|
||||
|
|
|
@ -669,6 +669,7 @@ void class_device_destroy(struct class *cls, dev_t devt)
|
|||
int class_device_rename(struct class_device *class_dev, char *new_name)
|
||||
{
|
||||
int error = 0;
|
||||
char *old_class_name = NULL, *new_class_name = NULL;
|
||||
|
||||
class_dev = class_device_get(class_dev);
|
||||
if (!class_dev)
|
||||
|
@ -677,12 +678,24 @@ int class_device_rename(struct class_device *class_dev, char *new_name)
|
|||
pr_debug("CLASS: renaming '%s' to '%s'\n", class_dev->class_id,
|
||||
new_name);
|
||||
|
||||
if (class_dev->dev)
|
||||
old_class_name = make_class_name(class_dev);
|
||||
|
||||
strlcpy(class_dev->class_id, new_name, KOBJ_NAME_LEN);
|
||||
|
||||
error = kobject_rename(&class_dev->kobj, new_name);
|
||||
|
||||
if (class_dev->dev) {
|
||||
new_class_name = make_class_name(class_dev);
|
||||
sysfs_create_link(&class_dev->dev->kobj, &class_dev->kobj,
|
||||
new_class_name);
|
||||
sysfs_remove_link(&class_dev->dev->kobj, old_class_name);
|
||||
}
|
||||
class_device_put(class_dev);
|
||||
|
||||
kfree(old_class_name);
|
||||
kfree(new_class_name);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,9 @@
|
|||
*/
|
||||
void device_bind_driver(struct device * dev)
|
||||
{
|
||||
if (klist_node_attached(&dev->knode_driver))
|
||||
return;
|
||||
|
||||
pr_debug("bound device '%s' to driver '%s'\n",
|
||||
dev->bus_id, dev->driver->name);
|
||||
klist_add_tail(&dev->knode_driver, &dev->driver->klist_devices);
|
||||
|
|
|
@ -483,9 +483,6 @@ static int cciss_open(struct inode *inode, struct file *filep)
|
|||
printk(KERN_DEBUG "cciss_open %s\n", inode->i_bdev->bd_disk->disk_name);
|
||||
#endif /* CCISS_DEBUG */
|
||||
|
||||
if (host->busy_initializing)
|
||||
return -EBUSY;
|
||||
|
||||
if (host->busy_initializing || drv->busy_configuring)
|
||||
return -EBUSY;
|
||||
/*
|
||||
|
@ -2991,6 +2988,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
|
|||
hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_ON);
|
||||
|
||||
cciss_procinit(i);
|
||||
hba[i]->busy_initializing = 0;
|
||||
|
||||
for(j=0; j < NWD; j++) { /* mfm */
|
||||
drive_info_struct *drv = &(hba[i]->drv[j]);
|
||||
|
@ -3033,7 +3031,6 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
|
|||
add_disk(disk);
|
||||
}
|
||||
|
||||
hba[i]->busy_initializing = 0;
|
||||
return(1);
|
||||
|
||||
clean4:
|
||||
|
|
|
@ -2373,44 +2373,6 @@ int blkdev_issue_flush(struct block_device *bdev, sector_t *error_sector)
|
|||
|
||||
EXPORT_SYMBOL(blkdev_issue_flush);
|
||||
|
||||
/**
|
||||
* blkdev_scsi_issue_flush_fn - issue flush for SCSI devices
|
||||
* @q: device queue
|
||||
* @disk: gendisk
|
||||
* @error_sector: error offset
|
||||
*
|
||||
* Description:
|
||||
* Devices understanding the SCSI command set, can use this function as
|
||||
* a helper for issuing a cache flush. Note: driver is required to store
|
||||
* the error offset (in case of error flushing) in ->sector of struct
|
||||
* request.
|
||||
*/
|
||||
int blkdev_scsi_issue_flush_fn(request_queue_t *q, struct gendisk *disk,
|
||||
sector_t *error_sector)
|
||||
{
|
||||
struct request *rq = blk_get_request(q, WRITE, __GFP_WAIT);
|
||||
int ret;
|
||||
|
||||
rq->flags |= REQ_BLOCK_PC | REQ_SOFTBARRIER;
|
||||
rq->sector = 0;
|
||||
memset(rq->cmd, 0, sizeof(rq->cmd));
|
||||
rq->cmd[0] = 0x35;
|
||||
rq->cmd_len = 12;
|
||||
rq->data = NULL;
|
||||
rq->data_len = 0;
|
||||
rq->timeout = 60 * HZ;
|
||||
|
||||
ret = blk_execute_rq(q, disk, rq, 0);
|
||||
|
||||
if (ret && error_sector)
|
||||
*error_sector = rq->sector;
|
||||
|
||||
blk_put_request(rq);
|
||||
return ret;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(blkdev_scsi_issue_flush_fn);
|
||||
|
||||
static void drive_stat_acct(struct request *rq, int nr_sectors, int new_io)
|
||||
{
|
||||
int rw = rq_data_dir(rq);
|
||||
|
|
|
@ -172,7 +172,7 @@ struct bulk_cs_wrap {
|
|||
*/
|
||||
struct ub_dev;
|
||||
|
||||
#define UB_MAX_REQ_SG 4
|
||||
#define UB_MAX_REQ_SG 9 /* cdrecord requires 32KB and maybe a header */
|
||||
#define UB_MAX_SECTORS 64
|
||||
|
||||
/*
|
||||
|
@ -387,7 +387,7 @@ struct ub_dev {
|
|||
struct bulk_cs_wrap work_bcs;
|
||||
struct usb_ctrlrequest work_cr;
|
||||
|
||||
int sg_stat[UB_MAX_REQ_SG+1];
|
||||
int sg_stat[6];
|
||||
struct ub_scsi_trace tr;
|
||||
};
|
||||
|
||||
|
@ -525,12 +525,13 @@ static ssize_t ub_diag_show(struct device *dev, struct device_attribute *attr,
|
|||
"qlen %d qmax %d\n",
|
||||
sc->cmd_queue.qlen, sc->cmd_queue.qmax);
|
||||
cnt += sprintf(page + cnt,
|
||||
"sg %d %d %d %d %d\n",
|
||||
"sg %d %d %d %d %d .. %d\n",
|
||||
sc->sg_stat[0],
|
||||
sc->sg_stat[1],
|
||||
sc->sg_stat[2],
|
||||
sc->sg_stat[3],
|
||||
sc->sg_stat[4]);
|
||||
sc->sg_stat[4],
|
||||
sc->sg_stat[5]);
|
||||
|
||||
list_for_each (p, &sc->luns) {
|
||||
lun = list_entry(p, struct ub_lun, link);
|
||||
|
@ -835,7 +836,7 @@ static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
|
|||
return -1;
|
||||
}
|
||||
cmd->nsg = n_elem;
|
||||
sc->sg_stat[n_elem]++;
|
||||
sc->sg_stat[n_elem < 5 ? n_elem : 5]++;
|
||||
|
||||
/*
|
||||
* build the command
|
||||
|
@ -891,7 +892,7 @@ static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun,
|
|||
return -1;
|
||||
}
|
||||
cmd->nsg = n_elem;
|
||||
sc->sg_stat[n_elem]++;
|
||||
sc->sg_stat[n_elem < 5 ? n_elem : 5]++;
|
||||
|
||||
memcpy(&cmd->cdb, rq->cmd, rq->cmd_len);
|
||||
cmd->cdb_len = rq->cmd_len;
|
||||
|
@ -1010,7 +1011,6 @@ static int ub_scsi_cmd_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
|
|||
sc->last_pipe = sc->send_bulk_pipe;
|
||||
usb_fill_bulk_urb(&sc->work_urb, sc->dev, sc->send_bulk_pipe,
|
||||
bcb, US_BULK_CB_WRAP_LEN, ub_urb_complete, sc);
|
||||
sc->work_urb.transfer_flags = 0;
|
||||
|
||||
/* Fill what we shouldn't be filling, because usb-storage did so. */
|
||||
sc->work_urb.actual_length = 0;
|
||||
|
@ -1019,7 +1019,6 @@ static int ub_scsi_cmd_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
|
|||
|
||||
if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) {
|
||||
/* XXX Clear stalls */
|
||||
printk("ub: cmd #%d start failed (%d)\n", cmd->tag, rc); /* P3 */
|
||||
ub_complete(&sc->work_done);
|
||||
return rc;
|
||||
}
|
||||
|
@ -1190,11 +1189,9 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
|
|||
return;
|
||||
}
|
||||
if (urb->status != 0) {
|
||||
printk("ub: cmd #%d cmd status (%d)\n", cmd->tag, urb->status); /* P3 */
|
||||
goto Bad_End;
|
||||
}
|
||||
if (urb->actual_length != US_BULK_CB_WRAP_LEN) {
|
||||
printk("ub: cmd #%d xferred %d\n", cmd->tag, urb->actual_length); /* P3 */
|
||||
/* XXX Must do reset here to unconfuse the device */
|
||||
goto Bad_End;
|
||||
}
|
||||
|
@ -1395,14 +1392,12 @@ static void ub_data_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
|
|||
usb_fill_bulk_urb(&sc->work_urb, sc->dev, pipe,
|
||||
page_address(sg->page) + sg->offset, sg->length,
|
||||
ub_urb_complete, sc);
|
||||
sc->work_urb.transfer_flags = 0;
|
||||
sc->work_urb.actual_length = 0;
|
||||
sc->work_urb.error_count = 0;
|
||||
sc->work_urb.status = 0;
|
||||
|
||||
if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) {
|
||||
/* XXX Clear stalls */
|
||||
printk("ub: data #%d submit failed (%d)\n", cmd->tag, rc); /* P3 */
|
||||
ub_complete(&sc->work_done);
|
||||
ub_state_done(sc, cmd, rc);
|
||||
return;
|
||||
|
@ -1442,7 +1437,6 @@ static int __ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
|
|||
sc->last_pipe = sc->recv_bulk_pipe;
|
||||
usb_fill_bulk_urb(&sc->work_urb, sc->dev, sc->recv_bulk_pipe,
|
||||
&sc->work_bcs, US_BULK_CS_WRAP_LEN, ub_urb_complete, sc);
|
||||
sc->work_urb.transfer_flags = 0;
|
||||
sc->work_urb.actual_length = 0;
|
||||
sc->work_urb.error_count = 0;
|
||||
sc->work_urb.status = 0;
|
||||
|
@ -1563,7 +1557,6 @@ static int ub_submit_clear_stall(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
|
|||
|
||||
usb_fill_control_urb(&sc->work_urb, sc->dev, sc->send_ctrl_pipe,
|
||||
(unsigned char*) cr, NULL, 0, ub_urb_complete, sc);
|
||||
sc->work_urb.transfer_flags = 0;
|
||||
sc->work_urb.actual_length = 0;
|
||||
sc->work_urb.error_count = 0;
|
||||
sc->work_urb.status = 0;
|
||||
|
@ -2000,17 +1993,16 @@ static int ub_sync_getmaxlun(struct ub_dev *sc)
|
|||
|
||||
usb_fill_control_urb(&sc->work_urb, sc->dev, sc->recv_ctrl_pipe,
|
||||
(unsigned char*) cr, p, 1, ub_probe_urb_complete, &compl);
|
||||
sc->work_urb.transfer_flags = 0;
|
||||
sc->work_urb.actual_length = 0;
|
||||
sc->work_urb.error_count = 0;
|
||||
sc->work_urb.status = 0;
|
||||
|
||||
if ((rc = usb_submit_urb(&sc->work_urb, GFP_KERNEL)) != 0) {
|
||||
if (rc == -EPIPE) {
|
||||
printk("%s: Stall at GetMaxLUN, using 1 LUN\n",
|
||||
printk("%s: Stall submitting GetMaxLUN, using 1 LUN\n",
|
||||
sc->name); /* P3 */
|
||||
} else {
|
||||
printk(KERN_WARNING
|
||||
printk(KERN_NOTICE
|
||||
"%s: Unable to submit GetMaxLUN (%d)\n",
|
||||
sc->name, rc);
|
||||
}
|
||||
|
@ -2028,6 +2020,18 @@ static int ub_sync_getmaxlun(struct ub_dev *sc)
|
|||
del_timer_sync(&timer);
|
||||
usb_kill_urb(&sc->work_urb);
|
||||
|
||||
if ((rc = sc->work_urb.status) < 0) {
|
||||
if (rc == -EPIPE) {
|
||||
printk("%s: Stall at GetMaxLUN, using 1 LUN\n",
|
||||
sc->name); /* P3 */
|
||||
} else {
|
||||
printk(KERN_NOTICE
|
||||
"%s: Error at GetMaxLUN (%d)\n",
|
||||
sc->name, rc);
|
||||
}
|
||||
goto err_io;
|
||||
}
|
||||
|
||||
if (sc->work_urb.actual_length != 1) {
|
||||
printk("%s: GetMaxLUN returned %d bytes\n", sc->name,
|
||||
sc->work_urb.actual_length); /* P3 */
|
||||
|
@ -2048,6 +2052,7 @@ static int ub_sync_getmaxlun(struct ub_dev *sc)
|
|||
kfree(p);
|
||||
return nluns;
|
||||
|
||||
err_io:
|
||||
err_submit:
|
||||
kfree(p);
|
||||
err_alloc:
|
||||
|
@ -2080,7 +2085,6 @@ static int ub_probe_clear_stall(struct ub_dev *sc, int stalled_pipe)
|
|||
|
||||
usb_fill_control_urb(&sc->work_urb, sc->dev, sc->send_ctrl_pipe,
|
||||
(unsigned char*) cr, NULL, 0, ub_probe_urb_complete, &compl);
|
||||
sc->work_urb.transfer_flags = 0;
|
||||
sc->work_urb.actual_length = 0;
|
||||
sc->work_urb.error_count = 0;
|
||||
sc->work_urb.status = 0;
|
||||
|
@ -2213,8 +2217,10 @@ static int ub_probe(struct usb_interface *intf,
|
|||
* This is needed to clear toggles. It is a problem only if we do
|
||||
* `rmmod ub && modprobe ub` without disconnects, but we like that.
|
||||
*/
|
||||
#if 0 /* iPod Mini fails if we do this (big white iPod works) */
|
||||
ub_probe_clear_stall(sc, sc->recv_bulk_pipe);
|
||||
ub_probe_clear_stall(sc, sc->send_bulk_pipe);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The way this is used by the startup code is a little specific.
|
||||
|
@ -2241,10 +2247,10 @@ static int ub_probe(struct usb_interface *intf,
|
|||
for (i = 0; i < 3; i++) {
|
||||
if ((rc = ub_sync_getmaxlun(sc)) < 0) {
|
||||
/*
|
||||
* Some devices (i.e. Iomega Zip100) need this --
|
||||
* apparently the bulk pipes get STALLed when the
|
||||
* GetMaxLUN request is processed.
|
||||
* XXX I have a ZIP-100, verify it does this.
|
||||
* This segment is taken from usb-storage. They say
|
||||
* that ZIP-100 needs this, but my own ZIP-100 works
|
||||
* fine without this.
|
||||
* Still, it does not seem to hurt anything.
|
||||
*/
|
||||
if (rc == -EPIPE) {
|
||||
ub_probe_clear_stall(sc, sc->recv_bulk_pipe);
|
||||
|
@ -2313,7 +2319,7 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum)
|
|||
disk->first_minor = lun->id * UB_MINORS_PER_MAJOR;
|
||||
disk->fops = &ub_bd_fops;
|
||||
disk->private_data = lun;
|
||||
disk->driverfs_dev = &sc->intf->dev; /* XXX Many to one ok? */
|
||||
disk->driverfs_dev = &sc->intf->dev;
|
||||
|
||||
rc = -ENOMEM;
|
||||
if ((q = blk_init_queue(ub_request_fn, &sc->lock)) == NULL)
|
||||
|
@ -2466,9 +2472,6 @@ static int __init ub_init(void)
|
|||
{
|
||||
int rc;
|
||||
|
||||
/* P3 */ printk("ub: sizeof ub_scsi_cmd %zu ub_dev %zu ub_lun %zu\n",
|
||||
sizeof(struct ub_scsi_cmd), sizeof(struct ub_dev), sizeof(struct ub_lun));
|
||||
|
||||
if ((rc = register_blkdev(UB_MAJOR, DRV_NAME)) != 0)
|
||||
goto err_regblkdev;
|
||||
devfs_mk_dir(DEVFS_NAME);
|
||||
|
|
|
@ -273,7 +273,6 @@ static int hpet_mmap(struct file *file, struct vm_area_struct *vma)
|
|||
|
||||
vma->vm_flags |= VM_IO;
|
||||
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
|
||||
addr = __pa(addr);
|
||||
|
||||
if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT,
|
||||
PAGE_SIZE, vma->vm_page_prot)) {
|
||||
|
|
|
@ -2620,7 +2620,7 @@ void ipmi_smi_msg_received(ipmi_smi_t intf,
|
|||
spin_lock_irqsave(&(intf->waiting_msgs_lock), flags);
|
||||
if (!list_empty(&(intf->waiting_msgs))) {
|
||||
list_add_tail(&(msg->link), &(intf->waiting_msgs));
|
||||
spin_unlock(&(intf->waiting_msgs_lock));
|
||||
spin_unlock_irqrestore(&(intf->waiting_msgs_lock), flags);
|
||||
goto out_unlock;
|
||||
}
|
||||
spin_unlock_irqrestore(&(intf->waiting_msgs_lock), flags);
|
||||
|
@ -2629,9 +2629,9 @@ void ipmi_smi_msg_received(ipmi_smi_t intf,
|
|||
if (rv > 0) {
|
||||
/* Could not handle the message now, just add it to a
|
||||
list to handle later. */
|
||||
spin_lock(&(intf->waiting_msgs_lock));
|
||||
spin_lock_irqsave(&(intf->waiting_msgs_lock), flags);
|
||||
list_add_tail(&(msg->link), &(intf->waiting_msgs));
|
||||
spin_unlock(&(intf->waiting_msgs_lock));
|
||||
spin_unlock_irqrestore(&(intf->waiting_msgs_lock), flags);
|
||||
} else if (rv == 0) {
|
||||
ipmi_free_smi_msg(msg);
|
||||
}
|
||||
|
|
|
@ -418,12 +418,11 @@ config SENSORS_HDAPS
|
|||
help
|
||||
This driver provides support for the IBM Hard Drive Active Protection
|
||||
System (hdaps), which provides an accelerometer and other misc. data.
|
||||
Supported laptops include the IBM ThinkPad T41, T42, T43, and R51.
|
||||
The accelerometer data is readable via sysfs.
|
||||
ThinkPads starting with the R50, T41, and X40 are supported. The
|
||||
accelerometer data is readable via sysfs.
|
||||
|
||||
This driver also provides an input class device, allowing the
|
||||
laptop to act as a pinball machine-esque mouse. This is off by
|
||||
default but enabled via sysfs or the module parameter "mousedev".
|
||||
This driver also provides an absolute input class device, allowing
|
||||
the laptop to act as a pinball machine-esque joystick.
|
||||
|
||||
Say Y here if you have an applicable laptop and want to experience
|
||||
the awesome power of hdaps.
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue