提交 7946ada3 编写于 作者: A Anton Altaparmakov

Merge branch 'master' of /usr/src/ntfs-2.6/

...@@ -131,3 +131,47 @@ Netlink itself is not reliable protocol, that means that messages can ...@@ -131,3 +131,47 @@ Netlink itself is not reliable protocol, that means that messages can
be lost due to memory pressure or process' receiving queue overflowed, be lost due to memory pressure or process' receiving queue overflowed,
so caller is warned must be prepared. That is why struct cn_msg [main so caller is warned must be prepared. That is why struct cn_msg [main
connector's message header] contains u32 seq and u32 ack fields. connector's message header] contains u32 seq and u32 ack fields.
/*****************************************/
Userspace usage.
/*****************************************/
2.6.14 has a new netlink socket implementation, which by default does not
allow to send data to netlink groups other than 1.
So, if to use netlink socket (for example using connector)
with different group number userspace application must subscribe to
that group. It can be achieved by following pseudocode:
s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
l_local.nl_family = AF_NETLINK;
l_local.nl_groups = 12345;
l_local.nl_pid = 0;
if (bind(s, (struct sockaddr *)&l_local, sizeof(struct sockaddr_nl)) == -1) {
perror("bind");
close(s);
return -1;
}
{
int on = l_local.nl_groups;
setsockopt(s, 270, 1, &on, sizeof(on));
}
Where 270 above is SOL_NETLINK, and 1 is a NETLINK_ADD_MEMBERSHIP socket
option. To drop multicast subscription one should call above socket option
with NETLINK_DROP_MEMBERSHIP parameter which is defined as 0.
2.6.14 netlink code only allows to select a group which is less or equal to
the maximum group number, which is used at netlink_kernel_create() time.
In case of connector it is CN_NETLINK_USERS + 0xf, so if you want to use
group number 12345, you must increment CN_NETLINK_USERS to that number.
Additional 0xf numbers are allocated to be used by non-in-kernel users.
Due to this limitation, group 0xffffffff does not work now, so one can
not use add/remove connector's group notifications, but as far as I know,
only cn_test.c test module used it.
Some work in netlink area is still being done, so things can be changed in
2.6.15 timeframe, if it will happen, documentation will be updated for that
kernel.
...@@ -35,6 +35,7 @@ The driver load creates the following directories under the /sys file system. ...@@ -35,6 +35,7 @@ The driver load creates the following directories under the /sys file system.
/sys/class/firmware/dell_rbu/data /sys/class/firmware/dell_rbu/data
/sys/devices/platform/dell_rbu/image_type /sys/devices/platform/dell_rbu/image_type
/sys/devices/platform/dell_rbu/data /sys/devices/platform/dell_rbu/data
/sys/devices/platform/dell_rbu/packet_size
The driver supports two types of update mechanism; monolithic and packetized. The driver supports two types of update mechanism; monolithic and packetized.
These update mechanism depends upon the BIOS currently running on the system. These update mechanism depends upon the BIOS currently running on the system.
...@@ -47,8 +48,26 @@ By default the driver uses monolithic memory for the update type. This can be ...@@ -47,8 +48,26 @@ By default the driver uses monolithic memory for the update type. This can be
changed to packets during the driver load time by specifying the load changed to packets during the driver load time by specifying the load
parameter image_type=packet. This can also be changed later as below parameter image_type=packet. This can also be changed later as below
echo packet > /sys/devices/platform/dell_rbu/image_type echo packet > /sys/devices/platform/dell_rbu/image_type
Also echoing either mono ,packet or init in to image_type will free up the
memory allocated by the driver. In packet update mode the packet size has to be given before any packets can
be downloaded. It is done as below
echo XXXX > /sys/devices/platform/dell_rbu/packet_size
In the packet update mechanism, the user neesd to create a new file having
packets of data arranged back to back. It can be done as follows
The user creates packets header, gets the chunk of the BIOS image and
placs it next to the packetheader; now, the packetheader + BIOS image chunk
added to geather should match the specified packet_size. This makes one
packet, the user needs to create more such packets out of the entire BIOS
image file and then arrange all these packets back to back in to one single
file.
This file is then copied to /sys/class/firmware/dell_rbu/data.
Once this file gets to the driver, the driver extracts packet_size data from
the file and spreads it accross the physical memory in contiguous packet_sized
space.
This method makes sure that all the packets get to the driver in a single operation.
In monolithic update the user simply get the BIOS image (.hdr file) and copies
to the data file as is without any change to the BIOS image itself.
Do the steps below to download the BIOS image. Do the steps below to download the BIOS image.
1) echo 1 > /sys/class/firmware/dell_rbu/loading 1) echo 1 > /sys/class/firmware/dell_rbu/loading
...@@ -58,7 +77,10 @@ Do the steps below to download the BIOS image. ...@@ -58,7 +77,10 @@ Do the steps below to download the BIOS image.
The /sys/class/firmware/dell_rbu/ entries will remain till the following is The /sys/class/firmware/dell_rbu/ entries will remain till the following is
done. done.
echo -1 > /sys/class/firmware/dell_rbu/loading. echo -1 > /sys/class/firmware/dell_rbu/loading.
Until this step is completed the drivr cannot be unloaded. Until this step is completed the driver cannot be unloaded.
Also echoing either mono ,packet or init in to image_type will free up the
memory allocated by the driver.
If an user by accident executes steps 1 and 3 above without executing step 2; If an user by accident executes steps 1 and 3 above without executing step 2;
it will make the /sys/class/firmware/dell_rbu/ entries to disappear. it will make the /sys/class/firmware/dell_rbu/ entries to disappear.
The entries can be recreated by doing the following The entries can be recreated by doing the following
...@@ -66,15 +88,11 @@ echo init > /sys/devices/platform/dell_rbu/image_type ...@@ -66,15 +88,11 @@ echo init > /sys/devices/platform/dell_rbu/image_type
NOTE: echoing init in image_type does not change it original value. NOTE: echoing init in image_type does not change it original value.
Also the driver provides /sys/devices/platform/dell_rbu/data readonly file to Also the driver provides /sys/devices/platform/dell_rbu/data readonly file to
read back the image downloaded. This is useful in case of packet update read back the image downloaded.
mechanism where the above steps 1,2,3 will repeated for every packet.
By reading the /sys/devices/platform/dell_rbu/data file all packet data
downloaded can be verified in a single file.
The packets are arranged in this file one after the other in a FIFO order.
NOTE: NOTE:
This driver requires a patch for firmware_class.c which has the addition This driver requires a patch for firmware_class.c which has the modified
of request_firmware_nowait_nohotplug function to wortk request_firmware_nowait function.
Also after updating the BIOS image an user mdoe application neeeds to execute Also after updating the BIOS image an user mdoe application neeeds to execute
code which message the BIOS update request to the BIOS. So on the next reboot code which message the BIOS update request to the BIOS. So on the next reboot
the BIOS knows about the new image downloaded and it updates it self. the BIOS knows about the new image downloaded and it updates it self.
......
...@@ -1618,6 +1618,13 @@ M: vandrove@vc.cvut.cz ...@@ -1618,6 +1618,13 @@ M: vandrove@vc.cvut.cz
L: linux-fbdev-devel@lists.sourceforge.net L: linux-fbdev-devel@lists.sourceforge.net
S: Maintained S: Maintained
MEGARAID SCSI DRIVERS
P: Neela Syam Kolli
M: Neela.Kolli@engenio.com
S: linux-scsi@vger.kernel.org
W: http://megaraid.lsilogic.com
S: Maintained
MEMORY TECHNOLOGY DEVICES MEMORY TECHNOLOGY DEVICES
P: David Woodhouse P: David Woodhouse
M: dwmw2@infradead.org M: dwmw2@infradead.org
......
...@@ -53,7 +53,7 @@ tune-$(CONFIG_CPU_ARM926T) :=-mtune=arm9tdmi ...@@ -53,7 +53,7 @@ tune-$(CONFIG_CPU_ARM926T) :=-mtune=arm9tdmi
tune-$(CONFIG_CPU_SA110) :=-mtune=strongarm110 tune-$(CONFIG_CPU_SA110) :=-mtune=strongarm110
tune-$(CONFIG_CPU_SA1100) :=-mtune=strongarm1100 tune-$(CONFIG_CPU_SA1100) :=-mtune=strongarm1100
tune-$(CONFIG_CPU_XSCALE) :=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale tune-$(CONFIG_CPU_XSCALE) :=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale
tune-$(CONFIG_CPU_V6) :=-mtune=strongarm tune-$(CONFIG_CPU_V6) :=$(call cc-option,-mtune=arm1136j-s,-mtune=strongarm)
# Need -Uarm for gcc < 3.x # Need -Uarm for gcc < 3.x
CFLAGS_ABI :=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) $(call cc-option,-mno-thumb-interwork,) CFLAGS_ABI :=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) $(call cc-option,-mno-thumb-interwork,)
......
...@@ -45,8 +45,8 @@ extern void fp_enter(void); ...@@ -45,8 +45,8 @@ extern void fp_enter(void);
#define EXPORT_SYMBOL_ALIAS(sym,orig) \ #define EXPORT_SYMBOL_ALIAS(sym,orig) \
EXPORT_CRC_ALIAS(sym) \ EXPORT_CRC_ALIAS(sym) \
const struct kernel_symbol __ksymtab_##sym \ static const struct kernel_symbol __ksymtab_##sym \
__attribute__((section("__ksymtab"))) = \ __attribute_used__ __attribute__((section("__ksymtab"))) = \
{ (unsigned long)&orig, #sym }; { (unsigned long)&orig, #sym };
/* /*
......
...@@ -106,15 +106,10 @@ ENTRY(ret_from_fork) ...@@ -106,15 +106,10 @@ ENTRY(ret_from_fork)
.endm .endm
.Larm700bug: .Larm700bug:
ldr r0, [sp, #S_PSR] @ Get calling cpsr
sub lr, lr, #4
str lr, [r8]
msr spsr_cxsf, r0
ldmia sp, {r0 - lr}^ @ Get calling r0 - lr ldmia sp, {r0 - lr}^ @ Get calling r0 - lr
mov r0, r0 mov r0, r0
ldr lr, [sp, #S_PC] @ Get PC
add sp, sp, #S_FRAME_SIZE add sp, sp, #S_FRAME_SIZE
movs pc, lr subs pc, lr, #4
#else #else
.macro arm710_bug_check, instr, temp .macro arm710_bug_check, instr, temp
.endm .endm
......
...@@ -89,13 +89,6 @@ SECTIONS ...@@ -89,13 +89,6 @@ SECTIONS
*(.got) /* Global offset table */ *(.got) /* Global offset table */
} }
. = ALIGN(16);
__ex_table : { /* Exception table */
__start___ex_table = .;
*(__ex_table)
__stop___ex_table = .;
}
RODATA RODATA
_etext = .; /* End of text and rodata section */ _etext = .; /* End of text and rodata section */
...@@ -137,6 +130,14 @@ SECTIONS ...@@ -137,6 +130,14 @@ SECTIONS
. = ALIGN(32); . = ALIGN(32);
*(.data.cacheline_aligned) *(.data.cacheline_aligned)
/*
* The exception fixup table (might need resorting at runtime)
*/
. = ALIGN(32);
__start___ex_table = .;
*(__ex_table)
__stop___ex_table = .;
/* /*
* and the usual data section * and the usual data section
*/ */
......
...@@ -7,11 +7,17 @@ ...@@ -7,11 +7,17 @@
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/device.h>
#include <asm/types.h>
#include <asm/irq.h>
#include <asm/mach-types.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h> #include <asm/mach/map.h>
#include <asm/mach/irq.h>
/* /*
* IRQ base register * IRQ base register
...@@ -47,6 +53,12 @@ static void l7200_unmask_irq(unsigned int irq) ...@@ -47,6 +53,12 @@ static void l7200_unmask_irq(unsigned int irq)
{ {
IRQ_ENABLE = 1 << irq; IRQ_ENABLE = 1 << irq;
} }
static struct irqchip l7200_irq_chip = {
.ack = l7200_mask_irq,
.mask = l7200_mask_irq,
.unmask = l7200_unmask_irq
};
static void __init l7200_init_irq(void) static void __init l7200_init_irq(void)
{ {
...@@ -56,11 +68,9 @@ static void __init l7200_init_irq(void) ...@@ -56,11 +68,9 @@ static void __init l7200_init_irq(void)
FIQ_ENABLECLEAR = 0xffffffff; /* clear all fast interrupt enables */ FIQ_ENABLECLEAR = 0xffffffff; /* clear all fast interrupt enables */
for (irq = 0; irq < NR_IRQS; irq++) { for (irq = 0; irq < NR_IRQS; irq++) {
irq_desc[irq].valid = 1; set_irq_chip(irq, &l7200_irq_chip);
irq_desc[irq].probe_ok = 1; set_irq_flags(irq, IRQF_VALID);
irq_desc[irq].mask_ack = l7200_mask_irq; set_irq_handler(irq, do_level_IRQ);
irq_desc[irq].mask = l7200_mask_irq;
irq_desc[irq].unmask = l7200_unmask_irq;
} }
init_FIQ(); init_FIQ();
......
...@@ -467,6 +467,7 @@ void corgi_put_hsync(void) ...@@ -467,6 +467,7 @@ void corgi_put_hsync(void)
{ {
if (get_hsync_time) if (get_hsync_time)
symbol_put(w100fb_get_hsynclen); symbol_put(w100fb_get_hsynclen);
get_hsync_time = NULL;
} }
void corgi_wait_hsync(void) void corgi_wait_hsync(void)
...@@ -476,20 +477,37 @@ void corgi_wait_hsync(void) ...@@ -476,20 +477,37 @@ void corgi_wait_hsync(void)
#endif #endif
#ifdef CONFIG_PXA_SHARP_Cxx00 #ifdef CONFIG_PXA_SHARP_Cxx00
static struct device *spitz_pxafb_dev;
static int is_pxafb_device(struct device * dev, void * data)
{
struct platform_device *pdev = container_of(dev, struct platform_device, dev);
return (strncmp(pdev->name, "pxa2xx-fb", 9) == 0);
}
unsigned long spitz_get_hsync_len(void) unsigned long spitz_get_hsync_len(void)
{ {
if (!spitz_pxafb_dev) {
spitz_pxafb_dev = bus_find_device(&platform_bus_type, NULL, NULL, is_pxafb_device);
if (!spitz_pxafb_dev)
return 0;
}
if (!get_hsync_time) if (!get_hsync_time)
get_hsync_time = symbol_get(pxafb_get_hsync_time); get_hsync_time = symbol_get(pxafb_get_hsync_time);
if (!get_hsync_time) if (!get_hsync_time)
return 0; return 0;
return pxafb_get_hsync_time(&pxafb_device.dev); return pxafb_get_hsync_time(spitz_pxafb_dev);
} }
void spitz_put_hsync(void) void spitz_put_hsync(void)
{ {
put_device(spitz_pxafb_dev);
if (get_hsync_time) if (get_hsync_time)
symbol_put(pxafb_get_hsync_time); symbol_put(pxafb_get_hsync_time);
spitz_pxafb_dev = NULL;
get_hsync_time = NULL;
} }
void spitz_wait_hsync(void) void spitz_wait_hsync(void)
......
...@@ -208,6 +208,11 @@ static struct platform_device pxafb_device = { ...@@ -208,6 +208,11 @@ static struct platform_device pxafb_device = {
.resource = pxafb_resources, .resource = pxafb_resources,
}; };
void __init set_pxa_fb_parent(struct device *parent_dev)
{
pxafb_device.dev.parent = parent_dev;
}
static struct platform_device ffuart_device = { static struct platform_device ffuart_device = {
.name = "pxa2xx-uart", .name = "pxa2xx-uart",
.id = 0, .id = 0,
......
...@@ -36,7 +36,6 @@ ...@@ -36,7 +36,6 @@
#include <asm/arch/irq.h> #include <asm/arch/irq.h>
#include <asm/arch/mmc.h> #include <asm/arch/mmc.h>
#include <asm/arch/udc.h> #include <asm/arch/udc.h>
#include <asm/arch/ohci.h>
#include <asm/arch/pxafb.h> #include <asm/arch/pxafb.h>
#include <asm/arch/akita.h> #include <asm/arch/akita.h>
#include <asm/arch/spitz.h> #include <asm/arch/spitz.h>
...@@ -304,7 +303,6 @@ static struct platform_device *devices[] __initdata = { ...@@ -304,7 +303,6 @@ static struct platform_device *devices[] __initdata = {
&spitzkbd_device, &spitzkbd_device,
&spitzts_device, &spitzts_device,
&spitzbl_device, &spitzbl_device,
&spitzbattery_device,
}; };
static void __init common_init(void) static void __init common_init(void)
...@@ -328,7 +326,7 @@ static void __init common_init(void) ...@@ -328,7 +326,7 @@ static void __init common_init(void)
platform_add_devices(devices, ARRAY_SIZE(devices)); platform_add_devices(devices, ARRAY_SIZE(devices));
pxa_set_mci_info(&spitz_mci_platform_data); pxa_set_mci_info(&spitz_mci_platform_data);
pxafb_device.dev.parent = &spitzssp_device.dev; set_pxa_fb_parent(&spitzssp_device.dev);
set_pxa_fb_info(&spitz_pxafb_info); set_pxa_fb_info(&spitz_pxafb_info);
} }
......
...@@ -12,6 +12,7 @@ config MACH_ANUBIS ...@@ -12,6 +12,7 @@ config MACH_ANUBIS
config ARCH_BAST config ARCH_BAST
bool "Simtec Electronics BAST (EB2410ITX)" bool "Simtec Electronics BAST (EB2410ITX)"
select CPU_S3C2410 select CPU_S3C2410
select ISA
help help
Say Y here if you are using the Simtec Electronics EB2410ITX Say Y here if you are using the Simtec Electronics EB2410ITX
development board (also known as BAST) development board (also known as BAST)
......
...@@ -125,7 +125,7 @@ static int external_map[] = { 2 }; ...@@ -125,7 +125,7 @@ static int external_map[] = { 2 };
static int chip0_map[] = { 0 }; static int chip0_map[] = { 0 };
static int chip1_map[] = { 1 }; static int chip1_map[] = { 1 };
struct mtd_partition anubis_default_nand_part[] = { static struct mtd_partition anubis_default_nand_part[] = {
[0] = { [0] = {
.name = "Boot Agent", .name = "Boot Agent",
.size = SZ_16K, .size = SZ_16K,
......
...@@ -230,7 +230,7 @@ static int chip0_map[] = { 1 }; ...@@ -230,7 +230,7 @@ static int chip0_map[] = { 1 };
static int chip1_map[] = { 2 }; static int chip1_map[] = { 2 };
static int chip2_map[] = { 3 }; static int chip2_map[] = { 3 };
struct mtd_partition bast_default_nand_part[] = { static struct mtd_partition bast_default_nand_part[] = {
[0] = { [0] = {
.name = "Boot Agent", .name = "Boot Agent",
.size = SZ_16K, .size = SZ_16K,
...@@ -340,7 +340,7 @@ static struct resource bast_dm9k_resource[] = { ...@@ -340,7 +340,7 @@ static struct resource bast_dm9k_resource[] = {
* better IO routines can be written and tested * better IO routines can be written and tested
*/ */
struct dm9000_plat_data bast_dm9k_platdata = { static struct dm9000_plat_data bast_dm9k_platdata = {
.flags = DM9000_PLATF_16BITONLY .flags = DM9000_PLATF_16BITONLY
}; };
......
...@@ -288,7 +288,7 @@ static struct resource vr1000_dm9k1_resource[] = { ...@@ -288,7 +288,7 @@ static struct resource vr1000_dm9k1_resource[] = {
* better IO routines can be written and tested * better IO routines can be written and tested
*/ */
struct dm9000_plat_data vr1000_dm9k_platdata = { static struct dm9000_plat_data vr1000_dm9k_platdata = {
.flags = DM9000_PLATF_16BITONLY, .flags = DM9000_PLATF_16BITONLY,
}; };
......
...@@ -125,9 +125,6 @@ static struct platform_device *uart_devices[] __initdata = { ...@@ -125,9 +125,6 @@ static struct platform_device *uart_devices[] __initdata = {
&s3c_uart2 &s3c_uart2
}; };
/* store our uart devices for the serial driver console */
struct platform_device *s3c2410_uart_devices[3];
static int s3c2410_uart_count = 0; static int s3c2410_uart_count = 0;
/* uart registration process */ /* uart registration process */
......
...@@ -151,7 +151,7 @@ void __init s3c2440_init_uarts(struct s3c2410_uartcfg *cfg, int no) ...@@ -151,7 +151,7 @@ void __init s3c2440_init_uarts(struct s3c2410_uartcfg *cfg, int no)
#ifdef CONFIG_PM #ifdef CONFIG_PM
struct sleep_save s3c2440_sleep[] = { static struct sleep_save s3c2440_sleep[] = {
SAVE_ITEM(S3C2440_DSC0), SAVE_ITEM(S3C2440_DSC0),
SAVE_ITEM(S3C2440_DSC1), SAVE_ITEM(S3C2440_DSC1),
SAVE_ITEM(S3C2440_GPJDAT), SAVE_ITEM(S3C2440_GPJDAT),
...@@ -260,7 +260,7 @@ void __init s3c2440_init_clocks(int xtal) ...@@ -260,7 +260,7 @@ void __init s3c2440_init_clocks(int xtal)
* as a driver which may support both 2410 and 2440 may try and use it. * as a driver which may support both 2410 and 2440 may try and use it.
*/ */
int __init s3c2440_core_init(void) static int __init s3c2440_core_init(void)
{ {
return sysdev_class_register(&s3c2440_sysclass); return sysdev_class_register(&s3c2440_sysclass);
} }
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include <asm/hardware/clock.h> #include <asm/hardware/clock.h>
#include "clock.h" #include "clock.h"
#include "cpu.h"
static unsigned long timer_startval; static unsigned long timer_startval;
static unsigned long timer_usec_ticks; static unsigned long timer_usec_ticks;
......
...@@ -111,7 +111,7 @@ proc_alignment_read(char *page, char **start, off_t off, int count, int *eof, ...@@ -111,7 +111,7 @@ proc_alignment_read(char *page, char **start, off_t off, int count, int *eof,
} }
static int proc_alignment_write(struct file *file, const char __user *buffer, static int proc_alignment_write(struct file *file, const char __user *buffer,
unsigned long count, void *data) unsigned long count, void *data)
{ {
char mode; char mode;
...@@ -119,7 +119,7 @@ static int proc_alignment_write(struct file *file, const char __user *buffer, ...@@ -119,7 +119,7 @@ static int proc_alignment_write(struct file *file, const char __user *buffer,
if (get_user(mode, buffer)) if (get_user(mode, buffer))
return -EFAULT; return -EFAULT;
if (mode >= '0' && mode <= '5') if (mode >= '0' && mode <= '5')
ai_usermode = mode - '0'; ai_usermode = mode - '0';
} }
return count; return count;
} }
...@@ -262,7 +262,7 @@ union offset_union { ...@@ -262,7 +262,7 @@ union offset_union {
goto fault; \ goto fault; \
} while (0) } while (0)
#define put32_unaligned_check(val,addr) \ #define put32_unaligned_check(val,addr) \
__put32_unaligned_check("strb", val, addr) __put32_unaligned_check("strb", val, addr)
#define put32t_unaligned_check(val,addr) \ #define put32t_unaligned_check(val,addr) \
...@@ -306,19 +306,19 @@ do_alignment_ldrhstrh(unsigned long addr, unsigned long instr, struct pt_regs *r ...@@ -306,19 +306,19 @@ do_alignment_ldrhstrh(unsigned long addr, unsigned long instr, struct pt_regs *r
return TYPE_LDST; return TYPE_LDST;
user: user:
if (LDST_L_BIT(instr)) { if (LDST_L_BIT(instr)) {
unsigned long val; unsigned long val;
get16t_unaligned_check(val, addr); get16t_unaligned_check(val, addr);
/* signed half-word? */ /* signed half-word? */
if (instr & 0x40) if (instr & 0x40)
val = (signed long)((signed short) val); val = (signed long)((signed short) val);
regs->uregs[rd] = val; regs->uregs[rd] = val;
} else } else
put16t_unaligned_check(regs->uregs[rd], addr); put16t_unaligned_check(regs->uregs[rd], addr);
return TYPE_LDST; return TYPE_LDST;
fault: fault:
return TYPE_FAULT; return TYPE_FAULT;
...@@ -342,11 +342,11 @@ do_alignment_ldrdstrd(unsigned long addr, unsigned long instr, ...@@ -342,11 +342,11 @@ do_alignment_ldrdstrd(unsigned long addr, unsigned long instr,
unsigned long val; unsigned long val;
get32_unaligned_check(val, addr); get32_unaligned_check(val, addr);
regs->uregs[rd] = val; regs->uregs[rd] = val;
get32_unaligned_check(val, addr+4); get32_unaligned_check(val, addr + 4);
regs->uregs[rd+1] = val; regs->uregs[rd + 1] = val;
} else { } else {
put32_unaligned_check(regs->uregs[rd], addr); put32_unaligned_check(regs->uregs[rd], addr);
put32_unaligned_check(regs->uregs[rd+1], addr+4); put32_unaligned_check(regs->uregs[rd + 1], addr + 4);
} }
return TYPE_LDST; return TYPE_LDST;
...@@ -356,11 +356,11 @@ do_alignment_ldrdstrd(unsigned long addr, unsigned long instr, ...@@ -356,11 +356,11 @@ do_alignment_ldrdstrd(unsigned long addr, unsigned long instr,
unsigned long val; unsigned long val;
get32t_unaligned_check(val, addr); get32t_unaligned_check(val, addr);
regs->uregs[rd] = val; regs->uregs[rd] = val;
get32t_unaligned_check(val, addr+4); get32t_unaligned_check(val, addr + 4);
regs->uregs[rd+1] = val; regs->uregs[rd + 1] = val;
} else { } else {
put32t_unaligned_check(regs->uregs[rd], addr); put32t_unaligned_check(regs->uregs[rd], addr);
put32t_unaligned_check(regs->uregs[rd+1], addr+4); put32t_unaligned_check(regs->uregs[rd + 1], addr + 4);
} }
return TYPE_LDST; return TYPE_LDST;
...@@ -443,7 +443,7 @@ do_alignment_ldmstm(unsigned long addr, unsigned long instr, struct pt_regs *reg ...@@ -443,7 +443,7 @@ do_alignment_ldmstm(unsigned long addr, unsigned long instr, struct pt_regs *reg
if (LDST_P_EQ_U(instr)) /* U = P */ if (LDST_P_EQ_U(instr)) /* U = P */
eaddr += 4; eaddr += 4;
/* /*
* For alignment faults on the ARM922T/ARM920T the MMU makes * For alignment faults on the ARM922T/ARM920T the MMU makes
* the FSR (and hence addr) equal to the updated base address * the FSR (and hence addr) equal to the updated base address
* of the multiple access rather than the restored value. * of the multiple access rather than the restored value.
...@@ -570,7 +570,7 @@ thumb2arm(u16 tinstr) ...@@ -570,7 +570,7 @@ thumb2arm(u16 tinstr)
/* 6.5.1 Format 3: */ /* 6.5.1 Format 3: */
case 0x4800 >> 11: /* 7.1.28 LDR(3) */ case 0x4800 >> 11: /* 7.1.28 LDR(3) */
/* NOTE: This case is not technically possible. We're /* NOTE: This case is not technically possible. We're
* loading 32-bit memory data via PC relative * loading 32-bit memory data via PC relative
* addressing mode. So we can and should eliminate * addressing mode. So we can and should eliminate
* this case. But I'll leave it here for now. * this case. But I'll leave it here for now.
*/ */
...@@ -642,7 +642,7 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) ...@@ -642,7 +642,7 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
if (fault) { if (fault) {
type = TYPE_FAULT; type = TYPE_FAULT;
goto bad_or_fault; goto bad_or_fault;
} }
if (user_mode(regs)) if (user_mode(regs))
......
...@@ -31,11 +31,6 @@ ...@@ -31,11 +31,6 @@
#include <linux/string.h> #include <linux/string.h>
#include <asm/system.h> #include <asm/system.h>
/* forward declarations */
unsigned int EmulateCPDO(const unsigned int);
unsigned int EmulateCPDT(const unsigned int);
unsigned int EmulateCPRT(const unsigned int);
/* Reset the FPA11 chip. Called to initialize and reset the emulator. */ /* Reset the FPA11 chip. Called to initialize and reset the emulator. */
static void resetFPA11(void) static void resetFPA11(void)
{ {
......
...@@ -95,4 +95,24 @@ extern int8 SetRoundingMode(const unsigned int); ...@@ -95,4 +95,24 @@ extern int8 SetRoundingMode(const unsigned int);
extern int8 SetRoundingPrecision(const unsigned int); extern int8 SetRoundingPrecision(const unsigned int);
extern void nwfpe_init_fpa(union fp_state *fp); extern void nwfpe_init_fpa(union fp_state *fp);
extern unsigned int EmulateAll(unsigned int opcode);
extern unsigned int EmulateCPDT(const unsigned int opcode);
extern unsigned int EmulateCPDO(const unsigned int opcode);
extern unsigned int EmulateCPRT(const unsigned int opcode);
/* fpa11_cpdt.c */
extern unsigned int PerformLDF(const unsigned int opcode);
extern unsigned int PerformSTF(const unsigned int opcode);
extern unsigned int PerformLFM(const unsigned int opcode);
extern unsigned int PerformSFM(const unsigned int opcode);
/* single_cpdo.c */
extern unsigned int SingleCPDO(struct roundingData *roundData,
const unsigned int opcode, FPREG * rFd);
/* double_cpdo.c */
extern unsigned int DoubleCPDO(struct roundingData *roundData,
const unsigned int opcode, FPREG * rFd);
#endif #endif
...@@ -26,12 +26,11 @@ ...@@ -26,12 +26,11 @@
#include "fpa11.inl" #include "fpa11.inl"
#include "fpmodule.h" #include "fpmodule.h"
#include "fpmodule.inl" #include "fpmodule.inl"
#include "softfloat.h"
#ifdef CONFIG_FPE_NWFPE_XP #ifdef CONFIG_FPE_NWFPE_XP
extern flag floatx80_is_nan(floatx80); extern flag floatx80_is_nan(floatx80);
#endif #endif
extern flag float64_is_nan(float64);
extern flag float32_is_nan(float32);
unsigned int PerformFLT(const unsigned int opcode); unsigned int PerformFLT(const unsigned int opcode);
unsigned int PerformFIX(const unsigned int opcode); unsigned int PerformFIX(const unsigned int opcode);
......
...@@ -476,4 +476,10 @@ static inline unsigned int getDestinationSize(const unsigned int opcode) ...@@ -476,4 +476,10 @@ static inline unsigned int getDestinationSize(const unsigned int opcode)
return (nRc); return (nRc);
} }
extern unsigned int checkCondition(const unsigned int opcode,
const unsigned int ccodes);
extern const float64 float64Constant[];
extern const float32 float32Constant[];
#endif #endif
...@@ -265,4 +265,7 @@ static inline flag float64_lt_nocheck(float64 a, float64 b) ...@@ -265,4 +265,7 @@ static inline flag float64_lt_nocheck(float64 a, float64 b)
return (a != b) && (aSign ^ (a < b)); return (a != b) && (aSign ^ (a < b));
} }
extern flag float32_is_nan( float32 a );
extern flag float64_is_nan( float64 a );
#endif #endif
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/cpumask.h> #include <linux/cpumask.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/module.h>
#define IPI_SCHEDULE 1 #define IPI_SCHEDULE 1
#define IPI_CALL 2 #define IPI_CALL 2
...@@ -28,6 +29,7 @@ spinlock_t cris_atomic_locks[] = { [0 ... LOCK_COUNT - 1] = SPIN_LOCK_UNLOCKED}; ...@@ -28,6 +29,7 @@ spinlock_t cris_atomic_locks[] = { [0 ... LOCK_COUNT - 1] = SPIN_LOCK_UNLOCKED};
/* CPU masks */ /* CPU masks */
cpumask_t cpu_online_map = CPU_MASK_NONE; cpumask_t cpu_online_map = CPU_MASK_NONE;
cpumask_t phys_cpu_present_map = CPU_MASK_NONE; cpumask_t phys_cpu_present_map = CPU_MASK_NONE;
EXPORT_SYMBOL(phys_cpu_present_map);
/* Variables used during SMP boot */ /* Variables used during SMP boot */
volatile int cpu_now_booting = 0; volatile int cpu_now_booting = 0;
......
...@@ -681,6 +681,15 @@ ENTRY(debug_trap) ...@@ -681,6 +681,15 @@ ENTRY(debug_trap)
bl do_debug_trap bl do_debug_trap
bra error_code bra error_code
ENTRY(ill_trap)
/* void ill_trap(void) */
SWITCH_TO_KERNEL_STACK
SAVE_ALL
ldi r1, #0 ; error_code ; FIXME
mv r0, sp ; pt_regs
bl do_ill_trap
bra error_code
/* Cache flushing handler */ /* Cache flushing handler */
ENTRY(cache_flushing_handler) ENTRY(cache_flushing_handler)
......
...@@ -275,12 +275,14 @@ static void flush_tlb_all_ipi(void *info) ...@@ -275,12 +275,14 @@ static void flush_tlb_all_ipi(void *info)
*==========================================================================*/ *==========================================================================*/
void smp_flush_tlb_mm(struct mm_struct *mm) void smp_flush_tlb_mm(struct mm_struct *mm)
{ {
int cpu_id = smp_processor_id(); int cpu_id;
cpumask_t cpu_mask; cpumask_t cpu_mask;
unsigned long *mmc = &mm->context[cpu_id]; unsigned long *mmc;
unsigned long flags; unsigned long flags;
preempt_disable(); preempt_disable();
cpu_id = smp_processor_id();
mmc = &mm->context[cpu_id];
cpu_mask = mm->cpu_vm_mask; cpu_mask = mm->cpu_vm_mask;
cpu_clear(cpu_id, cpu_mask); cpu_clear(cpu_id, cpu_mask);
...@@ -343,12 +345,14 @@ void smp_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, ...@@ -343,12 +345,14 @@ void smp_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
void smp_flush_tlb_page(struct vm_area_struct *vma, unsigned long va) void smp_flush_tlb_page(struct vm_area_struct *vma, unsigned long va)
{ {
struct mm_struct *mm = vma->vm_mm; struct mm_struct *mm = vma->vm_mm;
int cpu_id = smp_processor_id(); int cpu_id;
cpumask_t cpu_mask; cpumask_t cpu_mask;
unsigned long *mmc = &mm->context[cpu_id]; unsigned long *mmc;
unsigned long flags; unsigned long flags;
preempt_disable(); preempt_disable();
cpu_id = smp_processor_id();
mmc = &mm->context[cpu_id];
cpu_mask = mm->cpu_vm_mask; cpu_mask = mm->cpu_vm_mask;
cpu_clear(cpu_id, cpu_mask); cpu_clear(cpu_id, cpu_mask);
......
...@@ -5,8 +5,6 @@ ...@@ -5,8 +5,6 @@
* Hitoshi Yamamoto * Hitoshi Yamamoto
*/ */
/* $Id$ */
/* /*
* 'traps.c' handles hardware traps and faults after we have saved some * 'traps.c' handles hardware traps and faults after we have saved some
* state in 'entry.S'. * state in 'entry.S'.
...@@ -35,6 +33,7 @@ asmlinkage void ei_handler(void); ...@@ -35,6 +33,7 @@ asmlinkage void ei_handler(void);
asmlinkage void rie_handler(void); asmlinkage void rie_handler(void);
asmlinkage void debug_trap(void); asmlinkage void debug_trap(void);
asmlinkage void cache_flushing_handler(void); asmlinkage void cache_flushing_handler(void);
asmlinkage void ill_trap(void);
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
extern void smp_reschedule_interrupt(void); extern void smp_reschedule_interrupt(void);
...@@ -77,22 +76,22 @@ void set_eit_vector_entries(void) ...@@ -77,22 +76,22 @@ void set_eit_vector_entries(void)
eit_vector[5] = BRA_INSN(default_eit_handler, 5); eit_vector[5] = BRA_INSN(default_eit_handler, 5);
eit_vector[8] = BRA_INSN(rie_handler, 8); eit_vector[8] = BRA_INSN(rie_handler, 8);
eit_vector[12] = BRA_INSN(alignment_check, 12); eit_vector[12] = BRA_INSN(alignment_check, 12);
eit_vector[16] = 0xff000000UL; eit_vector[16] = BRA_INSN(ill_trap, 16);
eit_vector[17] = BRA_INSN(debug_trap, 17); eit_vector[17] = BRA_INSN(debug_trap, 17);
eit_vector[18] = BRA_INSN(system_call, 18); eit_vector[18] = BRA_INSN(system_call, 18);
eit_vector[19] = 0xff000000UL; eit_vector[19] = BRA_INSN(ill_trap, 19);
eit_vector[20] = 0xff000000UL; eit_vector[20] = BRA_INSN(ill_trap, 20);
eit_vector[21] = 0xff000000UL; eit_vector[21] = BRA_INSN(ill_trap, 21);
eit_vector[22] = 0xff000000UL; eit_vector[22] = BRA_INSN(ill_trap, 22);
eit_vector[23] = 0xff000000UL; eit_vector[23] = BRA_INSN(ill_trap, 23);
eit_vector[24] = 0xff000000UL; eit_vector[24] = BRA_INSN(ill_trap, 24);
eit_vector[25] = 0xff000000UL; eit_vector[25] = BRA_INSN(ill_trap, 25);
eit_vector[26] = 0xff000000UL; eit_vector[26] = BRA_INSN(ill_trap, 26);
eit_vector[27] = 0xff000000UL; eit_vector[27] = BRA_INSN(ill_trap, 27);
eit_vector[28] = BRA_INSN(cache_flushing_handler, 28); eit_vector[28] = BRA_INSN(cache_flushing_handler, 28);
eit_vector[29] = 0xff000000UL; eit_vector[29] = BRA_INSN(ill_trap, 29);
eit_vector[30] = 0xff000000UL; eit_vector[30] = BRA_INSN(ill_trap, 30);
eit_vector[31] = 0xff000000UL; eit_vector[31] = BRA_INSN(ill_trap, 31);
eit_vector[32] = BRA_INSN(ei_handler, 32); eit_vector[32] = BRA_INSN(ei_handler, 32);
eit_vector[64] = BRA_INSN(pie_handler, 64); eit_vector[64] = BRA_INSN(pie_handler, 64);
#ifdef CONFIG_MMU #ifdef CONFIG_MMU
...@@ -286,7 +285,8 @@ asmlinkage void do_##name(struct pt_regs * regs, long error_code) \ ...@@ -286,7 +285,8 @@ asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
DO_ERROR( 1, SIGTRAP, "debug trap", debug_trap) DO_ERROR( 1, SIGTRAP, "debug trap", debug_trap)
DO_ERROR_INFO(0x20, SIGILL, "reserved instruction ", rie_handler, ILL_ILLOPC, regs->bpc) DO_ERROR_INFO(0x20, SIGILL, "reserved instruction ", rie_handler, ILL_ILLOPC, regs->bpc)
DO_ERROR_INFO(0x100, SIGILL, "privilege instruction", pie_handler, ILL_PRVOPC, regs->bpc) DO_ERROR_INFO(0x100, SIGILL, "privileged instruction", pie_handler, ILL_PRVOPC, regs->bpc)
DO_ERROR_INFO(-1, SIGILL, "illegal trap", ill_trap, ILL_ILLTRP, regs->bpc)
extern int handle_unaligned_access(unsigned long, struct pt_regs *); extern int handle_unaligned_access(unsigned long, struct pt_regs *);
...@@ -329,4 +329,3 @@ asmlinkage void do_alignment_check(struct pt_regs *regs, long error_code) ...@@ -329,4 +329,3 @@ asmlinkage void do_alignment_check(struct pt_regs *regs, long error_code)
set_fs(oldfs); set_fs(oldfs);
} }
} }
/* /*
* fixup-tb0226.c, The TANBAC TB0226 specific PCI fixups. * fixup-tb0226.c, The TANBAC TB0226 specific PCI fixups.
* *
* Copyright (C) 2002-2004 Yoichi Yuasa <yuasa@hh.iij4u.or.jp> * Copyright (C) 2002-2005 Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <asm/vr41xx/giu.h>
#include <asm/vr41xx/tb0226.h> #include <asm/vr41xx/tb0226.h>
int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
...@@ -29,42 +30,42 @@ int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) ...@@ -29,42 +30,42 @@ int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
switch (slot) { switch (slot) {
case 12: case 12:
vr41xx_set_irq_trigger(GD82559_1_PIN, vr41xx_set_irq_trigger(GD82559_1_PIN,
TRIGGER_LEVEL, IRQ_TRIGGER_LEVEL,
SIGNAL_THROUGH); IRQ_SIGNAL_THROUGH);
vr41xx_set_irq_level(GD82559_1_PIN, LEVEL_LOW); vr41xx_set_irq_level(GD82559_1_PIN, IRQ_LEVEL_LOW);
irq = GD82559_1_IRQ; irq = GD82559_1_IRQ;
break; break;
case 13: case 13:
vr41xx_set_irq_trigger(GD82559_2_PIN, vr41xx_set_irq_trigger(GD82559_2_PIN,
TRIGGER_LEVEL, IRQ_TRIGGER_LEVEL,
SIGNAL_THROUGH); IRQ_SIGNAL_THROUGH);
vr41xx_set_irq_level(GD82559_2_PIN, LEVEL_LOW); vr41xx_set_irq_level(GD82559_2_PIN, IRQ_LEVEL_LOW);
irq = GD82559_2_IRQ; irq = GD82559_2_IRQ;
break; break;
case 14: case 14:
switch (pin) { switch (pin) {
case 1: case 1:
vr41xx_set_irq_trigger(UPD720100_INTA_PIN, vr41xx_set_irq_trigger(UPD720100_INTA_PIN,
TRIGGER_LEVEL, IRQ_TRIGGER_LEVEL,
SIGNAL_THROUGH); IRQ_SIGNAL_THROUGH);
vr41xx_set_irq_level(UPD720100_INTA_PIN, vr41xx_set_irq_level(UPD720100_INTA_PIN,
LEVEL_LOW); IRQ_LEVEL_LOW);
irq = UPD720100_INTA_IRQ; irq = UPD720100_INTA_IRQ;
break; break;
case 2: case 2:
vr41xx_set_irq_trigger(UPD720100_INTB_PIN, vr41xx_set_irq_trigger(UPD720100_INTB_PIN,
TRIGGER_LEVEL, IRQ_TRIGGER_LEVEL,
SIGNAL_THROUGH); IRQ_SIGNAL_THROUGH);
vr41xx_set_irq_level(UPD720100_INTB_PIN, vr41xx_set_irq_level(UPD720100_INTB_PIN,
LEVEL_LOW); IRQ_LEVEL_LOW);
irq = UPD720100_INTB_IRQ; irq = UPD720100_INTB_IRQ;
break; break;
case 3: case 3:
vr41xx_set_irq_trigger(UPD720100_INTC_PIN, vr41xx_set_irq_trigger(UPD720100_INTC_PIN,
TRIGGER_LEVEL, IRQ_TRIGGER_LEVEL,
SIGNAL_THROUGH); IRQ_SIGNAL_THROUGH);
vr41xx_set_irq_level(UPD720100_INTC_PIN, vr41xx_set_irq_level(UPD720100_INTC_PIN,
LEVEL_LOW); IRQ_LEVEL_LOW);
irq = UPD720100_INTC_IRQ; irq = UPD720100_INTC_IRQ;
break; break;
default: default:
......
...@@ -91,7 +91,7 @@ struct cpu_spec cpu_specs[] = { ...@@ -91,7 +91,7 @@ struct cpu_spec cpu_specs[] = {
.cpu_features = CPU_FTR_COMMON | CPU_FTR_601 | .cpu_features = CPU_FTR_COMMON | CPU_FTR_601 |
CPU_FTR_HPTE_TABLE, CPU_FTR_HPTE_TABLE,
.cpu_user_features = COMMON_PPC | PPC_FEATURE_601_INSTR | .cpu_user_features = COMMON_PPC | PPC_FEATURE_601_INSTR |
PPC_FEATURE_UNIFIED_CACHE, PPC_FEATURE_UNIFIED_CACHE | PPC_FEATURE_NO_TB,
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
.cpu_setup = __setup_cpu_601 .cpu_setup = __setup_cpu_601
...@@ -745,7 +745,8 @@ struct cpu_spec cpu_specs[] = { ...@@ -745,7 +745,8 @@ struct cpu_spec cpu_specs[] = {
.cpu_name = "403GCX", .cpu_name = "403GCX",
.cpu_features = CPU_FTR_SPLIT_ID_CACHE | .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
CPU_FTR_USE_TB, CPU_FTR_USE_TB,
.cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, .cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_NO_TB,
.icache_bsize = 16, .icache_bsize = 16,
.dcache_bsize = 16, .dcache_bsize = 16,
}, },
......
...@@ -401,10 +401,10 @@ EXPORT_SYMBOL(__dma_sync); ...@@ -401,10 +401,10 @@ EXPORT_SYMBOL(__dma_sync);
static inline void __dma_sync_page_highmem(struct page *page, static inline void __dma_sync_page_highmem(struct page *page,
unsigned long offset, size_t size, int direction) unsigned long offset, size_t size, int direction)
{ {
size_t seg_size = min((size_t)PAGE_SIZE, size) - offset; size_t seg_size = min((size_t)(PAGE_SIZE - offset), size);
size_t cur_size = seg_size; size_t cur_size = seg_size;
unsigned long flags, start, seg_offset = offset; unsigned long flags, start, seg_offset = offset;
int nr_segs = PAGE_ALIGN(size + (PAGE_SIZE - offset))/PAGE_SIZE; int nr_segs = 1 + ((size - seg_size) + PAGE_SIZE - 1)/PAGE_SIZE;
int seg_nr = 0; int seg_nr = 0;
local_irq_save(flags); local_irq_save(flags);
......
...@@ -341,6 +341,19 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, ...@@ -341,6 +341,19 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
*(unsigned long *)location = my_r2(sechdrs, me); *(unsigned long *)location = my_r2(sechdrs, me);
break; break;
case R_PPC64_TOC16:
/* Subtact TOC pointer */
value -= my_r2(sechdrs, me);
if (value + 0x8000 > 0xffff) {
printk("%s: bad TOC16 relocation (%lu)\n",
me->name, value);
return -ENOEXEC;
}
*((uint16_t *) location)
= (*((uint16_t *) location) & ~0xffff)
| (value & 0xffff);
break;
case R_PPC64_TOC16_DS: case R_PPC64_TOC16_DS:
/* Subtact TOC pointer */ /* Subtact TOC pointer */
value -= my_r2(sechdrs, me); value -= my_r2(sechdrs, me);
......
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
#include "pci.h" #include "pci.h"
static int __initdata s7a_workaround = -1; static int __devinitdata s7a_workaround = -1;
#if 0 #if 0
void pcibios_name_device(struct pci_dev *dev) void pcibios_name_device(struct pci_dev *dev)
...@@ -60,7 +60,7 @@ void pcibios_name_device(struct pci_dev *dev) ...@@ -60,7 +60,7 @@ void pcibios_name_device(struct pci_dev *dev)
DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_name_device); DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_name_device);
#endif #endif
static void __init check_s7a(void) static void __devinit check_s7a(void)
{ {
struct device_node *root; struct device_node *root;
char *model; char *model;
......
...@@ -115,7 +115,7 @@ static void __pmac pmac_show_cpuinfo(struct seq_file *m) ...@@ -115,7 +115,7 @@ static void __pmac pmac_show_cpuinfo(struct seq_file *m)
/* find motherboard type */ /* find motherboard type */
seq_printf(m, "machine\t\t: "); seq_printf(m, "machine\t\t: ");
np = find_devices("device-tree"); np = of_find_node_by_path("/");
if (np != NULL) { if (np != NULL) {
pp = (char *) get_property(np, "model", NULL); pp = (char *) get_property(np, "model", NULL);
if (pp != NULL) if (pp != NULL)
...@@ -133,6 +133,7 @@ static void __pmac pmac_show_cpuinfo(struct seq_file *m) ...@@ -133,6 +133,7 @@ static void __pmac pmac_show_cpuinfo(struct seq_file *m)
} }
seq_printf(m, "\n"); seq_printf(m, "\n");
} }
of_node_put(np);
} else } else
seq_printf(m, "PowerMac\n"); seq_printf(m, "PowerMac\n");
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <linux/time.h> #include <linux/time.h>
#include <linux/timex.h> #include <linux/timex.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/module.h>
#include <asm/atomic.h> #include <asm/atomic.h>
#include <asm/processor.h> #include <asm/processor.h>
...@@ -39,6 +40,8 @@ struct sh_cpuinfo cpu_data[NR_CPUS]; ...@@ -39,6 +40,8 @@ struct sh_cpuinfo cpu_data[NR_CPUS];
extern void per_cpu_trap_init(void); extern void per_cpu_trap_init(void);
cpumask_t cpu_possible_map; cpumask_t cpu_possible_map;
EXPORT_SYMBOL(cpu_possible_map);
cpumask_t cpu_online_map; cpumask_t cpu_online_map;
static atomic_t cpus_booted = ATOMIC_INIT(0); static atomic_t cpus_booted = ATOMIC_INIT(0);
......
...@@ -21,10 +21,6 @@ config GENERIC_ISA_DMA ...@@ -21,10 +21,6 @@ config GENERIC_ISA_DMA
bool bool
default y default y
config GENERIC_IOMAP
bool
default y
source "init/Kconfig" source "init/Kconfig"
menu "General machine setup" menu "General machine setup"
......
...@@ -5,7 +5,6 @@ CONFIG_MMU=y ...@@ -5,7 +5,6 @@ CONFIG_MMU=y
CONFIG_UID16=y CONFIG_UID16=y
CONFIG_HIGHMEM=y CONFIG_HIGHMEM=y
CONFIG_GENERIC_ISA_DMA=y CONFIG_GENERIC_ISA_DMA=y
CONFIG_GENERIC_IOMAP=y
# #
# Code maturity level options # Code maturity level options
......
...@@ -53,19 +53,18 @@ ...@@ -53,19 +53,18 @@
* be guaranteed to be 0 ... mmu_context.h does guarantee this * be guaranteed to be 0 ... mmu_context.h does guarantee this
* by only using 10 bits in the hwcontext value. * by only using 10 bits in the hwcontext value.
*/ */
#define CREATE_VPTE_OFFSET1(r1, r2) #define CREATE_VPTE_OFFSET1(r1, r2) nop
#define CREATE_VPTE_OFFSET2(r1, r2) \ #define CREATE_VPTE_OFFSET2(r1, r2) \
srax r1, 10, r2 srax r1, 10, r2
#define CREATE_VPTE_NOP nop
#else #else
#define CREATE_VPTE_OFFSET1(r1, r2) \ #define CREATE_VPTE_OFFSET1(r1, r2) \
srax r1, PAGE_SHIFT, r2 srax r1, PAGE_SHIFT, r2
#define CREATE_VPTE_OFFSET2(r1, r2) \ #define CREATE_VPTE_OFFSET2(r1, r2) \
sllx r2, 3, r2 sllx r2, 3, r2
#define CREATE_VPTE_NOP
#endif #endif
/* DTLB ** ICACHE line 1: Quick user TLB misses */ /* DTLB ** ICACHE line 1: Quick user TLB misses */
mov TLB_SFSR, %g1
ldxa [%g1 + %g1] ASI_DMMU, %g4 ! Get TAG_ACCESS ldxa [%g1 + %g1] ASI_DMMU, %g4 ! Get TAG_ACCESS
andcc %g4, TAG_CONTEXT_BITS, %g0 ! From Nucleus? andcc %g4, TAG_CONTEXT_BITS, %g0 ! From Nucleus?
from_tl1_trap: from_tl1_trap:
...@@ -74,18 +73,16 @@ from_tl1_trap: ...@@ -74,18 +73,16 @@ from_tl1_trap:
be,pn %xcc, kvmap ! Yep, special processing be,pn %xcc, kvmap ! Yep, special processing
CREATE_VPTE_OFFSET2(%g4, %g6) ! Create VPTE offset CREATE_VPTE_OFFSET2(%g4, %g6) ! Create VPTE offset
cmp %g5, 4 ! Last trap level? cmp %g5, 4 ! Last trap level?
be,pn %xcc, longpath ! Yep, cannot risk VPTE miss
nop ! delay slot
/* DTLB ** ICACHE line 2: User finish + quick kernel TLB misses */ /* DTLB ** ICACHE line 2: User finish + quick kernel TLB misses */
be,pn %xcc, longpath ! Yep, cannot risk VPTE miss
nop ! delay slot
ldxa [%g3 + %g6] ASI_S, %g5 ! Load VPTE ldxa [%g3 + %g6] ASI_S, %g5 ! Load VPTE
1: brgez,pn %g5, longpath ! Invalid, branch out 1: brgez,pn %g5, longpath ! Invalid, branch out
nop ! Delay-slot nop ! Delay-slot
9: stxa %g5, [%g0] ASI_DTLB_DATA_IN ! Reload TLB 9: stxa %g5, [%g0] ASI_DTLB_DATA_IN ! Reload TLB
retry ! Trap return retry ! Trap return
nop nop
nop
nop
/* DTLB ** ICACHE line 3: winfixups+real_faults */ /* DTLB ** ICACHE line 3: winfixups+real_faults */
longpath: longpath:
...@@ -106,8 +103,7 @@ longpath: ...@@ -106,8 +103,7 @@ longpath:
nop nop
nop nop
nop nop
CREATE_VPTE_NOP nop
#undef CREATE_VPTE_OFFSET1 #undef CREATE_VPTE_OFFSET1
#undef CREATE_VPTE_OFFSET2 #undef CREATE_VPTE_OFFSET2
#undef CREATE_VPTE_NOP
...@@ -14,14 +14,14 @@ ...@@ -14,14 +14,14 @@
*/ */
/* PROT ** ICACHE line 1: User DTLB protection trap */ /* PROT ** ICACHE line 1: User DTLB protection trap */
stxa %g0, [%g1] ASI_DMMU ! Clear SFSR FaultValid bit mov TLB_SFSR, %g1
membar #Sync ! Synchronize ASI stores stxa %g0, [%g1] ASI_DMMU ! Clear FaultValid bit
rdpr %pstate, %g5 ! Move into alternate globals membar #Sync ! Synchronize stores
rdpr %pstate, %g5 ! Move into alt-globals
wrpr %g5, PSTATE_AG|PSTATE_MG, %pstate wrpr %g5, PSTATE_AG|PSTATE_MG, %pstate
rdpr %tl, %g1 ! Need to do a winfixup? rdpr %tl, %g1 ! Need a winfixup?
cmp %g1, 1 ! Trap level >1? cmp %g1, 1 ! Trap level >1?
mov TLB_TAG_ACCESS, %g4 ! Prepare reload of vaddr mov TLB_TAG_ACCESS, %g4 ! For reload of vaddr
nop
/* PROT ** ICACHE line 2: More real fault processing */ /* PROT ** ICACHE line 2: More real fault processing */
bgu,pn %xcc, winfix_trampoline ! Yes, perform winfixup bgu,pn %xcc, winfix_trampoline ! Yes, perform winfixup
......
...@@ -28,19 +28,14 @@ ...@@ -28,19 +28,14 @@
#include <asm/mmu.h> #include <asm/mmu.h>
/* This section from from _start to sparc64_boot_end should fit into /* This section from from _start to sparc64_boot_end should fit into
* 0x0000.0000.0040.4000 to 0x0000.0000.0040.8000 and will be sharing space * 0x0000000000404000 to 0x0000000000408000.
* with bootup_user_stack, which is from 0x0000.0000.0040.4000 to
* 0x0000.0000.0040.6000 and empty_bad_page, which is from
* 0x0000.0000.0040.6000 to 0x0000.0000.0040.8000.
*/ */
.text .text
.globl start, _start, stext, _stext .globl start, _start, stext, _stext
_start: _start:
start: start:
_stext: _stext:
stext: stext:
bootup_user_stack:
! 0x0000000000404000 ! 0x0000000000404000
b sparc64_boot b sparc64_boot
flushw /* Flush register file. */ flushw /* Flush register file. */
...@@ -191,8 +186,9 @@ prom_boot_mapping_phys_low: ...@@ -191,8 +186,9 @@ prom_boot_mapping_phys_low:
stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 5 stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 5
stx %l2, [%sp + 2047 + 128 + 0x18] ! arg1: "translate" stx %l2, [%sp + 2047 + 128 + 0x18] ! arg1: "translate"
stx %l5, [%sp + 2047 + 128 + 0x20] ! arg2: prom_mmu_ihandle_cache stx %l5, [%sp + 2047 + 128 + 0x20] ! arg2: prom_mmu_ihandle_cache
srlx %l0, 22, %l3 /* PAGE align */
sllx %l3, 22, %l3 srlx %l0, 13, %l3
sllx %l3, 13, %l3
stx %l3, [%sp + 2047 + 128 + 0x28] ! arg3: vaddr, our PC stx %l3, [%sp + 2047 + 128 + 0x28] ! arg3: vaddr, our PC
stx %g0, [%sp + 2047 + 128 + 0x30] ! res1 stx %g0, [%sp + 2047 + 128 + 0x30] ! res1
stx %g0, [%sp + 2047 + 128 + 0x38] ! res2 stx %g0, [%sp + 2047 + 128 + 0x38] ! res2
...@@ -211,6 +207,9 @@ prom_boot_mapping_phys_low: ...@@ -211,6 +207,9 @@ prom_boot_mapping_phys_low:
ldx [%sp + 2047 + 128 + 0x48], %l2 ! physaddr high ldx [%sp + 2047 + 128 + 0x48], %l2 ! physaddr high
stx %l2, [%l4 + 0x0] stx %l2, [%l4 + 0x0]
ldx [%sp + 2047 + 128 + 0x50], %l3 ! physaddr low ldx [%sp + 2047 + 128 + 0x50], %l3 ! physaddr low
/* 4MB align */
srlx %l3, 22, %l3
sllx %l3, 22, %l3
stx %l3, [%l4 + 0x8] stx %l3, [%l4 + 0x8]
/* Leave service as-is, "call-method" */ /* Leave service as-is, "call-method" */
...@@ -388,31 +387,30 @@ tlb_fixup_done: ...@@ -388,31 +387,30 @@ tlb_fixup_done:
* former does use this code, the latter does not yet due * former does use this code, the latter does not yet due
* to some complexities. That should be fixed up at some * to some complexities. That should be fixed up at some
* point. * point.
*
* There used to be enormous complexity wrt. transferring
* over from the firwmare's trap table to the Linux kernel's.
* For example, there was a chicken & egg problem wrt. building
* the OBP page tables, yet needing to be on the Linux kernel
* trap table (to translate PAGE_OFFSET addresses) in order to
* do that.
*
* We now handle OBP tlb misses differently, via linear lookups
* into the prom_trans[] array. So that specific problem no
* longer exists. Yet, unfortunately there are still some issues
* preventing trampoline.S from using this code... ho hum.
*/ */
.globl setup_trap_table .globl setup_trap_table
setup_trap_table: setup_trap_table:
save %sp, -192, %sp save %sp, -192, %sp
/* Force interrupts to be disabled. Transferring over to /* Force interrupts to be disabled. */
* the Linux trap table is a very delicate operation.
* Until we are actually on the Linux trap table, we cannot
* get the PAGE_OFFSET linear mappings translated. We need
* that mapping to be setup in order to initialize the firmware
* page tables.
*
* So there is this window of time, from the return from
* prom_set_trap_table() until inherit_prom_mappings_post()
* (in arch/sparc64/mm/init.c) completes, during which no
* firmware address space accesses can be made.
*/
rdpr %pstate, %o1 rdpr %pstate, %o1
andn %o1, PSTATE_IE, %o1 andn %o1, PSTATE_IE, %o1
wrpr %o1, 0x0, %pstate wrpr %o1, 0x0, %pstate
wrpr %g0, 15, %pil wrpr %g0, 15, %pil
/* Ok, now make the final valid firmware call to jump over /* Make the firmware call to jump over to the Linux trap table. */
* to the Linux trap table.
*/
call prom_set_trap_table call prom_set_trap_table
sethi %hi(sparc64_ttable_tl0), %o0 sethi %hi(sparc64_ttable_tl0), %o0
...@@ -536,15 +534,21 @@ setup_tba: /* i0 = is_starfire */ ...@@ -536,15 +534,21 @@ setup_tba: /* i0 = is_starfire */
ret ret
restore restore
sparc64_boot_end:
#include "systbls.S"
#include "ktlb.S"
#include "etrap.S"
#include "rtrap.S"
#include "winfixup.S"
#include "entry.S"
/* /*
* The following skips make sure the trap table in ttable.S is aligned * The following skip makes sure the trap table in ttable.S is aligned
* on a 32K boundary as required by the v9 specs for TBA register. * on a 32K boundary as required by the v9 specs for TBA register.
*/ */
sparc64_boot_end: 1:
.skip 0x2000 + _start - sparc64_boot_end .skip 0x4000 + _start - 1b
bootup_user_stack_end:
.skip 0x2000
#ifdef CONFIG_SBUS #ifdef CONFIG_SBUS
/* This is just a hack to fool make depend config.h discovering /* This is just a hack to fool make depend config.h discovering
...@@ -556,15 +560,6 @@ bootup_user_stack_end: ...@@ -556,15 +560,6 @@ bootup_user_stack_end:
! 0x0000000000408000 ! 0x0000000000408000
#include "ttable.S" #include "ttable.S"
#include "systbls.S"
#include "ktlb.S"
#include "etrap.S"
#include "rtrap.S"
#include "winfixup.S"
#include "entry.S"
/* This is just anal retentiveness on my part... */
.align 16384
.data .data
.align 8 .align 8
......
...@@ -15,14 +15,12 @@ ...@@ -15,14 +15,12 @@
*/ */
#define CREATE_VPTE_OFFSET1(r1, r2) \ #define CREATE_VPTE_OFFSET1(r1, r2) \
srax r1, 10, r2 srax r1, 10, r2
#define CREATE_VPTE_OFFSET2(r1, r2) #define CREATE_VPTE_OFFSET2(r1, r2) nop
#define CREATE_VPTE_NOP nop
#else /* PAGE_SHIFT */ #else /* PAGE_SHIFT */
#define CREATE_VPTE_OFFSET1(r1, r2) \ #define CREATE_VPTE_OFFSET1(r1, r2) \
srax r1, PAGE_SHIFT, r2 srax r1, PAGE_SHIFT, r2
#define CREATE_VPTE_OFFSET2(r1, r2) \ #define CREATE_VPTE_OFFSET2(r1, r2) \
sllx r2, 3, r2 sllx r2, 3, r2
#define CREATE_VPTE_NOP
#endif /* PAGE_SHIFT */ #endif /* PAGE_SHIFT */
...@@ -36,6 +34,7 @@ ...@@ -36,6 +34,7 @@
*/ */
/* ITLB ** ICACHE line 1: Quick user TLB misses */ /* ITLB ** ICACHE line 1: Quick user TLB misses */
mov TLB_SFSR, %g1
ldxa [%g1 + %g1] ASI_IMMU, %g4 ! Get TAG_ACCESS ldxa [%g1 + %g1] ASI_IMMU, %g4 ! Get TAG_ACCESS
CREATE_VPTE_OFFSET1(%g4, %g6) ! Create VPTE offset CREATE_VPTE_OFFSET1(%g4, %g6) ! Create VPTE offset
CREATE_VPTE_OFFSET2(%g4, %g6) ! Create VPTE offset CREATE_VPTE_OFFSET2(%g4, %g6) ! Create VPTE offset
...@@ -43,41 +42,38 @@ ...@@ -43,41 +42,38 @@
1: brgez,pn %g5, 3f ! Not valid, branch out 1: brgez,pn %g5, 3f ! Not valid, branch out
sethi %hi(_PAGE_EXEC), %g4 ! Delay-slot sethi %hi(_PAGE_EXEC), %g4 ! Delay-slot
andcc %g5, %g4, %g0 ! Executable? andcc %g5, %g4, %g0 ! Executable?
/* ITLB ** ICACHE line 2: Real faults */
be,pn %xcc, 3f ! Nope, branch. be,pn %xcc, 3f ! Nope, branch.
nop ! Delay-slot nop ! Delay-slot
2: stxa %g5, [%g0] ASI_ITLB_DATA_IN ! Load PTE into TLB 2: stxa %g5, [%g0] ASI_ITLB_DATA_IN ! Load PTE into TLB
retry ! Trap return retry ! Trap return
3: rdpr %pstate, %g4 ! Move into alternate globals 3: rdpr %pstate, %g4 ! Move into alt-globals
/* ITLB ** ICACHE line 2: Real faults */
wrpr %g4, PSTATE_AG|PSTATE_MG, %pstate wrpr %g4, PSTATE_AG|PSTATE_MG, %pstate
rdpr %tpc, %g5 ! And load faulting VA rdpr %tpc, %g5 ! And load faulting VA
mov FAULT_CODE_ITLB, %g4 ! It was read from ITLB mov FAULT_CODE_ITLB, %g4 ! It was read from ITLB
sparc64_realfault_common: ! Called by TL0 dtlb_miss too
/* ITLB ** ICACHE line 3: Finish faults */
sparc64_realfault_common: ! Called by dtlb_miss
stb %g4, [%g6 + TI_FAULT_CODE] stb %g4, [%g6 + TI_FAULT_CODE]
stx %g5, [%g6 + TI_FAULT_ADDR] stx %g5, [%g6 + TI_FAULT_ADDR]
ba,pt %xcc, etrap ! Save state ba,pt %xcc, etrap ! Save state
1: rd %pc, %g7 ! ... 1: rd %pc, %g7 ! ...
nop
/* ITLB ** ICACHE line 3: Finish faults + window fixups */
call do_sparc64_fault ! Call fault handler call do_sparc64_fault ! Call fault handler
add %sp, PTREGS_OFF, %o0! Compute pt_regs arg add %sp, PTREGS_OFF, %o0! Compute pt_regs arg
ba,pt %xcc, rtrap_clr_l6 ! Restore cpu state ba,pt %xcc, rtrap_clr_l6 ! Restore cpu state
nop nop
/* ITLB ** ICACHE line 4: Window fixups */
winfix_trampoline: winfix_trampoline:
rdpr %tpc, %g3 ! Prepare winfixup TNPC rdpr %tpc, %g3 ! Prepare winfixup TNPC
or %g3, 0x7c, %g3 ! Compute offset to branch or %g3, 0x7c, %g3 ! Compute branch offset
wrpr %g3, %tnpc ! Write it into TNPC wrpr %g3, %tnpc ! Write it into TNPC
done ! Do it to it done ! Do it to it
/* ITLB ** ICACHE line 4: Unused... */
nop nop
nop nop
nop nop
nop nop
CREATE_VPTE_NOP
#undef CREATE_VPTE_OFFSET1 #undef CREATE_VPTE_OFFSET1
#undef CREATE_VPTE_OFFSET2 #undef CREATE_VPTE_OFFSET2
#undef CREATE_VPTE_NOP
...@@ -58,9 +58,6 @@ vpte_noent: ...@@ -58,9 +58,6 @@ vpte_noent:
done done
vpte_insn_obp: vpte_insn_obp:
sethi %hi(prom_pmd_phys), %g5
ldx [%g5 + %lo(prom_pmd_phys)], %g5
/* Behave as if we are at TL0. */ /* Behave as if we are at TL0. */
wrpr %g0, 1, %tl wrpr %g0, 1, %tl
rdpr %tpc, %g4 /* Find original faulting iaddr */ rdpr %tpc, %g4 /* Find original faulting iaddr */
...@@ -71,58 +68,57 @@ vpte_insn_obp: ...@@ -71,58 +68,57 @@ vpte_insn_obp:
mov TLB_SFSR, %g1 mov TLB_SFSR, %g1
stxa %g4, [%g1 + %g1] ASI_IMMU stxa %g4, [%g1 + %g1] ASI_IMMU
/* Get PMD offset. */ sethi %hi(prom_trans), %g5
srlx %g4, 23, %g6 or %g5, %lo(prom_trans), %g5
and %g6, 0x7ff, %g6
sllx %g6, 2, %g6 1: ldx [%g5 + 0x00], %g6 ! base
brz,a,pn %g6, longpath ! no more entries, fail
/* Load PMD, is it valid? */ mov TLB_SFSR, %g1 ! and restore %g1
lduwa [%g5 + %g6] ASI_PHYS_USE_EC, %g5 ldx [%g5 + 0x08], %g1 ! len
brz,pn %g5, longpath add %g6, %g1, %g1 ! end
sllx %g5, 11, %g5 cmp %g6, %g4
bgu,pt %xcc, 2f
/* Get PTE offset. */ cmp %g4, %g1
srlx %g4, 13, %g6 bgeu,pt %xcc, 2f
and %g6, 0x3ff, %g6 ldx [%g5 + 0x10], %g1 ! PTE
sllx %g6, 3, %g6
/* TLB load, restore %g1, and return from trap. */
/* Load PTE. */ sub %g4, %g6, %g6
ldxa [%g5 + %g6] ASI_PHYS_USE_EC, %g5 add %g1, %g6, %g5
brgez,pn %g5, longpath mov TLB_SFSR, %g1
nop
/* TLB load and return from trap. */
stxa %g5, [%g0] ASI_ITLB_DATA_IN stxa %g5, [%g0] ASI_ITLB_DATA_IN
retry retry
kvmap_do_obp: 2: ba,pt %xcc, 1b
sethi %hi(prom_pmd_phys), %g5 add %g5, (3 * 8), %g5 ! next entry
ldx [%g5 + %lo(prom_pmd_phys)], %g5
/* Get PMD offset. */
srlx %g4, 23, %g6
and %g6, 0x7ff, %g6
sllx %g6, 2, %g6
/* Load PMD, is it valid? */
lduwa [%g5 + %g6] ASI_PHYS_USE_EC, %g5
brz,pn %g5, longpath
sllx %g5, 11, %g5
/* Get PTE offset. */
srlx %g4, 13, %g6
and %g6, 0x3ff, %g6
sllx %g6, 3, %g6
/* Load PTE. */
ldxa [%g5 + %g6] ASI_PHYS_USE_EC, %g5
brgez,pn %g5, longpath
nop
/* TLB load and return from trap. */ kvmap_do_obp:
sethi %hi(prom_trans), %g5
or %g5, %lo(prom_trans), %g5
srlx %g4, 13, %g4
sllx %g4, 13, %g4
1: ldx [%g5 + 0x00], %g6 ! base
brz,a,pn %g6, longpath ! no more entries, fail
mov TLB_SFSR, %g1 ! and restore %g1
ldx [%g5 + 0x08], %g1 ! len
add %g6, %g1, %g1 ! end
cmp %g6, %g4
bgu,pt %xcc, 2f
cmp %g4, %g1
bgeu,pt %xcc, 2f
ldx [%g5 + 0x10], %g1 ! PTE
/* TLB load, restore %g1, and return from trap. */
sub %g4, %g6, %g6
add %g1, %g6, %g5
mov TLB_SFSR, %g1
stxa %g5, [%g0] ASI_DTLB_DATA_IN stxa %g5, [%g0] ASI_DTLB_DATA_IN
retry retry
2: ba,pt %xcc, 1b
add %g5, (3 * 8), %g5 ! next entry
/* /*
* On a first level data miss, check whether this is to the OBP range (note * On a first level data miss, check whether this is to the OBP range (note
* that such accesses can be made by prom, as well as by kernel using * that such accesses can be made by prom, as well as by kernel using
......
...@@ -49,12 +49,6 @@ static void __iommu_flushall(struct pci_iommu *iommu) ...@@ -49,12 +49,6 @@ static void __iommu_flushall(struct pci_iommu *iommu)
/* Ensure completion of previous PIO writes. */ /* Ensure completion of previous PIO writes. */
(void) pci_iommu_read(iommu->write_complete_reg); (void) pci_iommu_read(iommu->write_complete_reg);
/* Now update everyone's flush point. */
for (entry = 0; entry < PBM_NCLUSTERS; entry++) {
iommu->alloc_info[entry].flush =
iommu->alloc_info[entry].next;
}
} }
#define IOPTE_CONSISTENT(CTX) \ #define IOPTE_CONSISTENT(CTX) \
...@@ -80,120 +74,117 @@ static void inline iopte_make_dummy(struct pci_iommu *iommu, iopte_t *iopte) ...@@ -80,120 +74,117 @@ static void inline iopte_make_dummy(struct pci_iommu *iommu, iopte_t *iopte)
iopte_val(*iopte) = val; iopte_val(*iopte) = val;
} }
void pci_iommu_table_init(struct pci_iommu *iommu, int tsbsize) /* Based largely upon the ppc64 iommu allocator. */
static long pci_arena_alloc(struct pci_iommu *iommu, unsigned long npages)
{ {
int i; struct pci_iommu_arena *arena = &iommu->arena;
unsigned long n, i, start, end, limit;
tsbsize /= sizeof(iopte_t); int pass;
for (i = 0; i < tsbsize; i++) limit = arena->limit;
iopte_make_dummy(iommu, &iommu->page_table[i]); start = arena->hint;
} pass = 0;
static iopte_t *alloc_streaming_cluster(struct pci_iommu *iommu, unsigned long npages) again:
{ n = find_next_zero_bit(arena->map, limit, start);
iopte_t *iopte, *limit, *first; end = n + npages;
unsigned long cnum, ent, flush_point; if (unlikely(end >= limit)) {
if (likely(pass < 1)) {
cnum = 0; limit = start;
while ((1UL << cnum) < npages) start = 0;
cnum++; __iommu_flushall(iommu);
iopte = (iommu->page_table + pass++;
(cnum << (iommu->page_table_sz_bits - PBM_LOGCLUSTERS))); goto again;
} else {
if (cnum == 0) /* Scanned the whole thing, give up. */
limit = (iommu->page_table + return -1;
iommu->lowest_consistent_map);
else
limit = (iopte +
(1 << (iommu->page_table_sz_bits - PBM_LOGCLUSTERS)));
iopte += ((ent = iommu->alloc_info[cnum].next) << cnum);
flush_point = iommu->alloc_info[cnum].flush;
first = iopte;
for (;;) {
if (IOPTE_IS_DUMMY(iommu, iopte)) {
if ((iopte + (1 << cnum)) >= limit)
ent = 0;
else
ent = ent + 1;
iommu->alloc_info[cnum].next = ent;
if (ent == flush_point)
__iommu_flushall(iommu);
break;
} }
iopte += (1 << cnum); }
ent++;
if (iopte >= limit) { for (i = n; i < end; i++) {
iopte = (iommu->page_table + if (test_bit(i, arena->map)) {
(cnum << start = i + 1;
(iommu->page_table_sz_bits - PBM_LOGCLUSTERS))); goto again;
ent = 0;
} }
if (ent == flush_point)
__iommu_flushall(iommu);
if (iopte == first)
goto bad;
} }
/* I've got your streaming cluster right here buddy boy... */ for (i = n; i < end; i++)
return iopte; __set_bit(i, arena->map);
bad: arena->hint = end;
printk(KERN_EMERG "pci_iommu: alloc_streaming_cluster of npages(%ld) failed!\n",
npages); return n;
return NULL;
} }
static void free_streaming_cluster(struct pci_iommu *iommu, dma_addr_t base, static void pci_arena_free(struct pci_iommu_arena *arena, unsigned long base, unsigned long npages)
unsigned long npages, unsigned long ctx)
{ {
unsigned long cnum, ent; unsigned long i;
cnum = 0; for (i = base; i < (base + npages); i++)
while ((1UL << cnum) < npages) __clear_bit(i, arena->map);
cnum++; }
ent = (base << (32 - IO_PAGE_SHIFT + PBM_LOGCLUSTERS - iommu->page_table_sz_bits)) void pci_iommu_table_init(struct pci_iommu *iommu, int tsbsize, u32 dma_offset, u32 dma_addr_mask)
>> (32 + PBM_LOGCLUSTERS + cnum - iommu->page_table_sz_bits); {
unsigned long i, tsbbase, order, sz, num_tsb_entries;
num_tsb_entries = tsbsize / sizeof(iopte_t);
/* Setup initial software IOMMU state. */
spin_lock_init(&iommu->lock);
iommu->ctx_lowest_free = 1;
iommu->page_table_map_base = dma_offset;
iommu->dma_addr_mask = dma_addr_mask;
/* Allocate and initialize the free area map. */
sz = num_tsb_entries / 8;
sz = (sz + 7UL) & ~7UL;
iommu->arena.map = kmalloc(sz, GFP_KERNEL);
if (!iommu->arena.map) {
prom_printf("PCI_IOMMU: Error, kmalloc(arena.map) failed.\n");
prom_halt();
}
memset(iommu->arena.map, 0, sz);
iommu->arena.limit = num_tsb_entries;
/* If the global flush might not have caught this entry, /* Allocate and initialize the dummy page which we
* adjust the flush point such that we will flush before * set inactive IO PTEs to point to.
* ever trying to reuse it.
*/ */
#define between(X,Y,Z) (((Z) - (Y)) >= ((X) - (Y))) iommu->dummy_page = __get_free_pages(GFP_KERNEL, 0);
if (between(ent, iommu->alloc_info[cnum].next, iommu->alloc_info[cnum].flush)) if (!iommu->dummy_page) {
iommu->alloc_info[cnum].flush = ent; prom_printf("PCI_IOMMU: Error, gfp(dummy_page) failed.\n");
#undef between prom_halt();
}
memset((void *)iommu->dummy_page, 0, PAGE_SIZE);
iommu->dummy_page_pa = (unsigned long) __pa(iommu->dummy_page);
/* Now allocate and setup the IOMMU page table itself. */
order = get_order(tsbsize);
tsbbase = __get_free_pages(GFP_KERNEL, order);
if (!tsbbase) {
prom_printf("PCI_IOMMU: Error, gfp(tsb) failed.\n");
prom_halt();
}
iommu->page_table = (iopte_t *)tsbbase;
for (i = 0; i < num_tsb_entries; i++)
iopte_make_dummy(iommu, &iommu->page_table[i]);
} }
/* We allocate consistent mappings from the end of cluster zero. */ static inline iopte_t *alloc_npages(struct pci_iommu *iommu, unsigned long npages)
static iopte_t *alloc_consistent_cluster(struct pci_iommu *iommu, unsigned long npages)
{ {
iopte_t *iopte; long entry;
iopte = iommu->page_table + (1 << (iommu->page_table_sz_bits - PBM_LOGCLUSTERS)); entry = pci_arena_alloc(iommu, npages);
while (iopte > iommu->page_table) { if (unlikely(entry < 0))
iopte--; return NULL;
if (IOPTE_IS_DUMMY(iommu, iopte)) {
unsigned long tmp = npages;
while (--tmp) { return iommu->page_table + entry;
iopte--; }
if (!IOPTE_IS_DUMMY(iommu, iopte))
break;
}
if (tmp == 0) {
u32 entry = (iopte - iommu->page_table);
if (entry < iommu->lowest_consistent_map) static inline void free_npages(struct pci_iommu *iommu, dma_addr_t base, unsigned long npages)
iommu->lowest_consistent_map = entry; {
return iopte; pci_arena_free(&iommu->arena, base >> IO_PAGE_SHIFT, npages);
}
}
}
return NULL;
} }
static int iommu_alloc_ctx(struct pci_iommu *iommu) static int iommu_alloc_ctx(struct pci_iommu *iommu)
...@@ -233,7 +224,7 @@ void *pci_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_ad ...@@ -233,7 +224,7 @@ void *pci_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_ad
struct pcidev_cookie *pcp; struct pcidev_cookie *pcp;
struct pci_iommu *iommu; struct pci_iommu *iommu;
iopte_t *iopte; iopte_t *iopte;
unsigned long flags, order, first_page, ctx; unsigned long flags, order, first_page;
void *ret; void *ret;
int npages; int npages;
...@@ -251,9 +242,10 @@ void *pci_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_ad ...@@ -251,9 +242,10 @@ void *pci_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_ad
iommu = pcp->pbm->iommu; iommu = pcp->pbm->iommu;
spin_lock_irqsave(&iommu->lock, flags); spin_lock_irqsave(&iommu->lock, flags);
iopte = alloc_consistent_cluster(iommu, size >> IO_PAGE_SHIFT); iopte = alloc_npages(iommu, size >> IO_PAGE_SHIFT);
if (iopte == NULL) { spin_unlock_irqrestore(&iommu->lock, flags);
spin_unlock_irqrestore(&iommu->lock, flags);
if (unlikely(iopte == NULL)) {
free_pages(first_page, order); free_pages(first_page, order);
return NULL; return NULL;
} }
...@@ -262,31 +254,15 @@ void *pci_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_ad ...@@ -262,31 +254,15 @@ void *pci_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_ad
((iopte - iommu->page_table) << IO_PAGE_SHIFT)); ((iopte - iommu->page_table) << IO_PAGE_SHIFT));
ret = (void *) first_page; ret = (void *) first_page;
npages = size >> IO_PAGE_SHIFT; npages = size >> IO_PAGE_SHIFT;
ctx = 0;
if (iommu->iommu_ctxflush)
ctx = iommu_alloc_ctx(iommu);
first_page = __pa(first_page); first_page = __pa(first_page);
while (npages--) { while (npages--) {
iopte_val(*iopte) = (IOPTE_CONSISTENT(ctx) | iopte_val(*iopte) = (IOPTE_CONSISTENT(0UL) |
IOPTE_WRITE | IOPTE_WRITE |
(first_page & IOPTE_PAGE)); (first_page & IOPTE_PAGE));
iopte++; iopte++;
first_page += IO_PAGE_SIZE; first_page += IO_PAGE_SIZE;
} }
{
int i;
u32 daddr = *dma_addrp;
npages = size >> IO_PAGE_SHIFT;
for (i = 0; i < npages; i++) {
pci_iommu_write(iommu->iommu_flush, daddr);
daddr += IO_PAGE_SIZE;
}
}
spin_unlock_irqrestore(&iommu->lock, flags);
return ret; return ret;
} }
...@@ -296,7 +272,7 @@ void pci_free_consistent(struct pci_dev *pdev, size_t size, void *cpu, dma_addr_ ...@@ -296,7 +272,7 @@ void pci_free_consistent(struct pci_dev *pdev, size_t size, void *cpu, dma_addr_
struct pcidev_cookie *pcp; struct pcidev_cookie *pcp;
struct pci_iommu *iommu; struct pci_iommu *iommu;
iopte_t *iopte; iopte_t *iopte;
unsigned long flags, order, npages, i, ctx; unsigned long flags, order, npages;
npages = IO_PAGE_ALIGN(size) >> IO_PAGE_SHIFT; npages = IO_PAGE_ALIGN(size) >> IO_PAGE_SHIFT;
pcp = pdev->sysdata; pcp = pdev->sysdata;
...@@ -306,46 +282,7 @@ void pci_free_consistent(struct pci_dev *pdev, size_t size, void *cpu, dma_addr_ ...@@ -306,46 +282,7 @@ void pci_free_consistent(struct pci_dev *pdev, size_t size, void *cpu, dma_addr_
spin_lock_irqsave(&iommu->lock, flags); spin_lock_irqsave(&iommu->lock, flags);
if ((iopte - iommu->page_table) == free_npages(iommu, dvma, npages);
iommu->lowest_consistent_map) {
iopte_t *walk = iopte + npages;
iopte_t *limit;
limit = (iommu->page_table +
(1 << (iommu->page_table_sz_bits - PBM_LOGCLUSTERS)));
while (walk < limit) {
if (!IOPTE_IS_DUMMY(iommu, walk))
break;
walk++;
}
iommu->lowest_consistent_map =
(walk - iommu->page_table);
}
/* Data for consistent mappings cannot enter the streaming
* buffers, so we only need to update the TSB. We flush
* the IOMMU here as well to prevent conflicts with the
* streaming mapping deferred tlb flush scheme.
*/
ctx = 0;
if (iommu->iommu_ctxflush)
ctx = (iopte_val(*iopte) & IOPTE_CONTEXT) >> 47UL;
for (i = 0; i < npages; i++, iopte++)
iopte_make_dummy(iommu, iopte);
if (iommu->iommu_ctxflush) {
pci_iommu_write(iommu->iommu_ctxflush, ctx);
} else {
for (i = 0; i < npages; i++) {
u32 daddr = dvma + (i << IO_PAGE_SHIFT);
pci_iommu_write(iommu->iommu_flush, daddr);
}
}
iommu_free_ctx(iommu, ctx);
spin_unlock_irqrestore(&iommu->lock, flags); spin_unlock_irqrestore(&iommu->lock, flags);
...@@ -372,25 +309,27 @@ dma_addr_t pci_map_single(struct pci_dev *pdev, void *ptr, size_t sz, int direct ...@@ -372,25 +309,27 @@ dma_addr_t pci_map_single(struct pci_dev *pdev, void *ptr, size_t sz, int direct
iommu = pcp->pbm->iommu; iommu = pcp->pbm->iommu;
strbuf = &pcp->pbm->stc; strbuf = &pcp->pbm->stc;
if (direction == PCI_DMA_NONE) if (unlikely(direction == PCI_DMA_NONE))
BUG(); goto bad_no_ctx;
oaddr = (unsigned long)ptr; oaddr = (unsigned long)ptr;
npages = IO_PAGE_ALIGN(oaddr + sz) - (oaddr & IO_PAGE_MASK); npages = IO_PAGE_ALIGN(oaddr + sz) - (oaddr & IO_PAGE_MASK);
npages >>= IO_PAGE_SHIFT; npages >>= IO_PAGE_SHIFT;
spin_lock_irqsave(&iommu->lock, flags); spin_lock_irqsave(&iommu->lock, flags);
base = alloc_npages(iommu, npages);
ctx = 0;
if (iommu->iommu_ctxflush)
ctx = iommu_alloc_ctx(iommu);
spin_unlock_irqrestore(&iommu->lock, flags);
base = alloc_streaming_cluster(iommu, npages); if (unlikely(!base))
if (base == NULL)
goto bad; goto bad;
bus_addr = (iommu->page_table_map_base + bus_addr = (iommu->page_table_map_base +
((base - iommu->page_table) << IO_PAGE_SHIFT)); ((base - iommu->page_table) << IO_PAGE_SHIFT));
ret = bus_addr | (oaddr & ~IO_PAGE_MASK); ret = bus_addr | (oaddr & ~IO_PAGE_MASK);
base_paddr = __pa(oaddr & IO_PAGE_MASK); base_paddr = __pa(oaddr & IO_PAGE_MASK);
ctx = 0;
if (iommu->iommu_ctxflush)
ctx = iommu_alloc_ctx(iommu);
if (strbuf->strbuf_enabled) if (strbuf->strbuf_enabled)
iopte_protection = IOPTE_STREAMING(ctx); iopte_protection = IOPTE_STREAMING(ctx);
else else
...@@ -401,12 +340,13 @@ dma_addr_t pci_map_single(struct pci_dev *pdev, void *ptr, size_t sz, int direct ...@@ -401,12 +340,13 @@ dma_addr_t pci_map_single(struct pci_dev *pdev, void *ptr, size_t sz, int direct
for (i = 0; i < npages; i++, base++, base_paddr += IO_PAGE_SIZE) for (i = 0; i < npages; i++, base++, base_paddr += IO_PAGE_SIZE)
iopte_val(*base) = iopte_protection | base_paddr; iopte_val(*base) = iopte_protection | base_paddr;
spin_unlock_irqrestore(&iommu->lock, flags);
return ret; return ret;
bad: bad:
spin_unlock_irqrestore(&iommu->lock, flags); iommu_free_ctx(iommu, ctx);
bad_no_ctx:
if (printk_ratelimit())
WARN_ON(1);
return PCI_DMA_ERROR_CODE; return PCI_DMA_ERROR_CODE;
} }
...@@ -481,10 +421,13 @@ void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int ...@@ -481,10 +421,13 @@ void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int
struct pci_iommu *iommu; struct pci_iommu *iommu;
struct pci_strbuf *strbuf; struct pci_strbuf *strbuf;
iopte_t *base; iopte_t *base;
unsigned long flags, npages, ctx; unsigned long flags, npages, ctx, i;
if (direction == PCI_DMA_NONE) if (unlikely(direction == PCI_DMA_NONE)) {
BUG(); if (printk_ratelimit())
WARN_ON(1);
return;
}
pcp = pdev->sysdata; pcp = pdev->sysdata;
iommu = pcp->pbm->iommu; iommu = pcp->pbm->iommu;
...@@ -510,13 +453,14 @@ void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int ...@@ -510,13 +453,14 @@ void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int
/* Step 1: Kick data out of streaming buffers if necessary. */ /* Step 1: Kick data out of streaming buffers if necessary. */
if (strbuf->strbuf_enabled) if (strbuf->strbuf_enabled)
pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages, direction); pci_strbuf_flush(strbuf, iommu, bus_addr, ctx,
npages, direction);
/* Step 2: Clear out first TSB entry. */ /* Step 2: Clear out TSB entries. */
iopte_make_dummy(iommu, base); for (i = 0; i < npages; i++)
iopte_make_dummy(iommu, base + i);
free_streaming_cluster(iommu, bus_addr - iommu->page_table_map_base, free_npages(iommu, bus_addr - iommu->page_table_map_base, npages);
npages, ctx);
iommu_free_ctx(iommu, ctx); iommu_free_ctx(iommu, ctx);
...@@ -621,6 +565,8 @@ int pci_map_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int ...@@ -621,6 +565,8 @@ int pci_map_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int
pci_map_single(pdev, pci_map_single(pdev,
(page_address(sglist->page) + sglist->offset), (page_address(sglist->page) + sglist->offset),
sglist->length, direction); sglist->length, direction);
if (unlikely(sglist->dma_address == PCI_DMA_ERROR_CODE))
return 0;
sglist->dma_length = sglist->length; sglist->dma_length = sglist->length;
return 1; return 1;
} }
...@@ -629,21 +575,29 @@ int pci_map_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int ...@@ -629,21 +575,29 @@ int pci_map_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int
iommu = pcp->pbm->iommu; iommu = pcp->pbm->iommu;
strbuf = &pcp->pbm->stc; strbuf = &pcp->pbm->stc;
if (direction == PCI_DMA_NONE) if (unlikely(direction == PCI_DMA_NONE))
BUG(); goto bad_no_ctx;
/* Step 1: Prepare scatter list. */ /* Step 1: Prepare scatter list. */
npages = prepare_sg(sglist, nelems); npages = prepare_sg(sglist, nelems);
/* Step 2: Allocate a cluster. */ /* Step 2: Allocate a cluster and context, if necessary. */
spin_lock_irqsave(&iommu->lock, flags); spin_lock_irqsave(&iommu->lock, flags);
base = alloc_streaming_cluster(iommu, npages); base = alloc_npages(iommu, npages);
ctx = 0;
if (iommu->iommu_ctxflush)
ctx = iommu_alloc_ctx(iommu);
spin_unlock_irqrestore(&iommu->lock, flags);
if (base == NULL) if (base == NULL)
goto bad; goto bad;
dma_base = iommu->page_table_map_base + ((base - iommu->page_table) << IO_PAGE_SHIFT);
dma_base = iommu->page_table_map_base +
((base - iommu->page_table) << IO_PAGE_SHIFT);
/* Step 3: Normalize DMA addresses. */ /* Step 3: Normalize DMA addresses. */
used = nelems; used = nelems;
...@@ -656,30 +610,28 @@ int pci_map_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int ...@@ -656,30 +610,28 @@ int pci_map_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int
} }
used = nelems - used; used = nelems - used;
/* Step 4: Choose a context if necessary. */ /* Step 4: Create the mappings. */
ctx = 0;
if (iommu->iommu_ctxflush)
ctx = iommu_alloc_ctx(iommu);
/* Step 5: Create the mappings. */
if (strbuf->strbuf_enabled) if (strbuf->strbuf_enabled)
iopte_protection = IOPTE_STREAMING(ctx); iopte_protection = IOPTE_STREAMING(ctx);
else else
iopte_protection = IOPTE_CONSISTENT(ctx); iopte_protection = IOPTE_CONSISTENT(ctx);
if (direction != PCI_DMA_TODEVICE) if (direction != PCI_DMA_TODEVICE)
iopte_protection |= IOPTE_WRITE; iopte_protection |= IOPTE_WRITE;
fill_sg (base, sglist, used, nelems, iopte_protection);
fill_sg(base, sglist, used, nelems, iopte_protection);
#ifdef VERIFY_SG #ifdef VERIFY_SG
verify_sglist(sglist, nelems, base, npages); verify_sglist(sglist, nelems, base, npages);
#endif #endif
spin_unlock_irqrestore(&iommu->lock, flags);
return used; return used;
bad: bad:
spin_unlock_irqrestore(&iommu->lock, flags); iommu_free_ctx(iommu, ctx);
return PCI_DMA_ERROR_CODE; bad_no_ctx:
if (printk_ratelimit())
WARN_ON(1);
return 0;
} }
/* Unmap a set of streaming mode DMA translations. */ /* Unmap a set of streaming mode DMA translations. */
...@@ -692,8 +644,10 @@ void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, ...@@ -692,8 +644,10 @@ void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems,
unsigned long flags, ctx, i, npages; unsigned long flags, ctx, i, npages;
u32 bus_addr; u32 bus_addr;
if (direction == PCI_DMA_NONE) if (unlikely(direction == PCI_DMA_NONE)) {
BUG(); if (printk_ratelimit())
WARN_ON(1);
}
pcp = pdev->sysdata; pcp = pdev->sysdata;
iommu = pcp->pbm->iommu; iommu = pcp->pbm->iommu;
...@@ -705,7 +659,8 @@ void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, ...@@ -705,7 +659,8 @@ void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems,
if (sglist[i].dma_length == 0) if (sglist[i].dma_length == 0)
break; break;
i--; i--;
npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length) - bus_addr) >> IO_PAGE_SHIFT; npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length) -
bus_addr) >> IO_PAGE_SHIFT;
base = iommu->page_table + base = iommu->page_table +
((bus_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT); ((bus_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT);
...@@ -726,11 +681,11 @@ void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, ...@@ -726,11 +681,11 @@ void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems,
if (strbuf->strbuf_enabled) if (strbuf->strbuf_enabled)
pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages, direction); pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages, direction);
/* Step 2: Clear out first TSB entry. */ /* Step 2: Clear out the TSB entries. */
iopte_make_dummy(iommu, base); for (i = 0; i < npages; i++)
iopte_make_dummy(iommu, base + i);
free_streaming_cluster(iommu, bus_addr - iommu->page_table_map_base, free_npages(iommu, bus_addr - iommu->page_table_map_base, npages);
npages, ctx);
iommu_free_ctx(iommu, ctx); iommu_free_ctx(iommu, ctx);
......
...@@ -1207,13 +1207,9 @@ static void psycho_scan_bus(struct pci_controller_info *p) ...@@ -1207,13 +1207,9 @@ static void psycho_scan_bus(struct pci_controller_info *p)
static void psycho_iommu_init(struct pci_controller_info *p) static void psycho_iommu_init(struct pci_controller_info *p)
{ {
struct pci_iommu *iommu = p->pbm_A.iommu; struct pci_iommu *iommu = p->pbm_A.iommu;
unsigned long tsbbase, i; unsigned long i;
u64 control; u64 control;
/* Setup initial software IOMMU state. */
spin_lock_init(&iommu->lock);
iommu->ctx_lowest_free = 1;
/* Register addresses. */ /* Register addresses. */
iommu->iommu_control = p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL; iommu->iommu_control = p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL;
iommu->iommu_tsbbase = p->pbm_A.controller_regs + PSYCHO_IOMMU_TSBBASE; iommu->iommu_tsbbase = p->pbm_A.controller_regs + PSYCHO_IOMMU_TSBBASE;
...@@ -1240,40 +1236,10 @@ static void psycho_iommu_init(struct pci_controller_info *p) ...@@ -1240,40 +1236,10 @@ static void psycho_iommu_init(struct pci_controller_info *p)
/* Leave diag mode enabled for full-flushing done /* Leave diag mode enabled for full-flushing done
* in pci_iommu.c * in pci_iommu.c
*/ */
pci_iommu_table_init(iommu, IO_TSB_SIZE, 0xc0000000, 0xffffffff);
iommu->dummy_page = __get_free_pages(GFP_KERNEL, 0); psycho_write(p->pbm_A.controller_regs + PSYCHO_IOMMU_TSBBASE,
if (!iommu->dummy_page) { __pa(iommu->page_table));
prom_printf("PSYCHO_IOMMU: Error, gfp(dummy_page) failed.\n");
prom_halt();
}
memset((void *)iommu->dummy_page, 0, PAGE_SIZE);
iommu->dummy_page_pa = (unsigned long) __pa(iommu->dummy_page);
/* Using assumed page size 8K with 128K entries we need 1MB iommu page
* table (128K ioptes * 8 bytes per iopte). This is
* page order 7 on UltraSparc.
*/
tsbbase = __get_free_pages(GFP_KERNEL, get_order(IO_TSB_SIZE));
if (!tsbbase) {
prom_printf("PSYCHO_IOMMU: Error, gfp(tsb) failed.\n");
prom_halt();
}
iommu->page_table = (iopte_t *)tsbbase;
iommu->page_table_sz_bits = 17;
iommu->page_table_map_base = 0xc0000000;
iommu->dma_addr_mask = 0xffffffff;
pci_iommu_table_init(iommu, IO_TSB_SIZE);
/* We start with no consistent mappings. */
iommu->lowest_consistent_map =
1 << (iommu->page_table_sz_bits - PBM_LOGCLUSTERS);
for (i = 0; i < PBM_NCLUSTERS; i++) {
iommu->alloc_info[i].flush = 0;
iommu->alloc_info[i].next = 0;
}
psycho_write(p->pbm_A.controller_regs + PSYCHO_IOMMU_TSBBASE, __pa(tsbbase));
control = psycho_read(p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL); control = psycho_read(p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL);
control &= ~(PSYCHO_IOMMU_CTRL_TSBSZ | PSYCHO_IOMMU_CTRL_TBWSZ); control &= ~(PSYCHO_IOMMU_CTRL_TSBSZ | PSYCHO_IOMMU_CTRL_TBWSZ);
...@@ -1281,7 +1247,7 @@ static void psycho_iommu_init(struct pci_controller_info *p) ...@@ -1281,7 +1247,7 @@ static void psycho_iommu_init(struct pci_controller_info *p)
psycho_write(p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL, control); psycho_write(p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL, control);
/* If necessary, hook us up for starfire IRQ translations. */ /* If necessary, hook us up for starfire IRQ translations. */
if(this_is_starfire) if (this_is_starfire)
p->starfire_cookie = starfire_hookup(p->pbm_A.portid); p->starfire_cookie = starfire_hookup(p->pbm_A.portid);
else else
p->starfire_cookie = NULL; p->starfire_cookie = NULL;
......
...@@ -1267,13 +1267,9 @@ static void sabre_iommu_init(struct pci_controller_info *p, ...@@ -1267,13 +1267,9 @@ static void sabre_iommu_init(struct pci_controller_info *p,
u32 dma_mask) u32 dma_mask)
{ {
struct pci_iommu *iommu = p->pbm_A.iommu; struct pci_iommu *iommu = p->pbm_A.iommu;
unsigned long tsbbase, i, order; unsigned long i;
u64 control; u64 control;
/* Setup initial software IOMMU state. */
spin_lock_init(&iommu->lock);
iommu->ctx_lowest_free = 1;
/* Register addresses. */ /* Register addresses. */
iommu->iommu_control = p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL; iommu->iommu_control = p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL;
iommu->iommu_tsbbase = p->pbm_A.controller_regs + SABRE_IOMMU_TSBBASE; iommu->iommu_tsbbase = p->pbm_A.controller_regs + SABRE_IOMMU_TSBBASE;
...@@ -1295,26 +1291,10 @@ static void sabre_iommu_init(struct pci_controller_info *p, ...@@ -1295,26 +1291,10 @@ static void sabre_iommu_init(struct pci_controller_info *p,
/* Leave diag mode enabled for full-flushing done /* Leave diag mode enabled for full-flushing done
* in pci_iommu.c * in pci_iommu.c
*/ */
pci_iommu_table_init(iommu, tsbsize * 1024 * 8, dvma_offset, dma_mask);
iommu->dummy_page = __get_free_pages(GFP_KERNEL, 0); sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_TSBBASE,
if (!iommu->dummy_page) { __pa(iommu->page_table));
prom_printf("PSYCHO_IOMMU: Error, gfp(dummy_page) failed.\n");
prom_halt();
}
memset((void *)iommu->dummy_page, 0, PAGE_SIZE);
iommu->dummy_page_pa = (unsigned long) __pa(iommu->dummy_page);
tsbbase = __get_free_pages(GFP_KERNEL, order = get_order(tsbsize * 1024 * 8));
if (!tsbbase) {
prom_printf("SABRE_IOMMU: Error, gfp(tsb) failed.\n");
prom_halt();
}
iommu->page_table = (iopte_t *)tsbbase;
iommu->page_table_map_base = dvma_offset;
iommu->dma_addr_mask = dma_mask;
pci_iommu_table_init(iommu, PAGE_SIZE << order);
sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_TSBBASE, __pa(tsbbase));
control = sabre_read(p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL); control = sabre_read(p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL);
control &= ~(SABRE_IOMMUCTRL_TSBSZ | SABRE_IOMMUCTRL_TBWSZ); control &= ~(SABRE_IOMMUCTRL_TSBSZ | SABRE_IOMMUCTRL_TBWSZ);
...@@ -1322,11 +1302,9 @@ static void sabre_iommu_init(struct pci_controller_info *p, ...@@ -1322,11 +1302,9 @@ static void sabre_iommu_init(struct pci_controller_info *p,
switch(tsbsize) { switch(tsbsize) {
case 64: case 64:
control |= SABRE_IOMMU_TSBSZ_64K; control |= SABRE_IOMMU_TSBSZ_64K;
iommu->page_table_sz_bits = 16;
break; break;
case 128: case 128:
control |= SABRE_IOMMU_TSBSZ_128K; control |= SABRE_IOMMU_TSBSZ_128K;
iommu->page_table_sz_bits = 17;
break; break;
default: default:
prom_printf("iommu_init: Illegal TSB size %d\n", tsbsize); prom_printf("iommu_init: Illegal TSB size %d\n", tsbsize);
...@@ -1334,15 +1312,6 @@ static void sabre_iommu_init(struct pci_controller_info *p, ...@@ -1334,15 +1312,6 @@ static void sabre_iommu_init(struct pci_controller_info *p,
break; break;
} }
sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL, control); sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL, control);
/* We start with no consistent mappings. */
iommu->lowest_consistent_map =
1 << (iommu->page_table_sz_bits - PBM_LOGCLUSTERS);
for (i = 0; i < PBM_NCLUSTERS; i++) {
iommu->alloc_info[i].flush = 0;
iommu->alloc_info[i].next = 0;
}
} }
static void pbm_register_toplevel_resources(struct pci_controller_info *p, static void pbm_register_toplevel_resources(struct pci_controller_info *p,
......
...@@ -1765,7 +1765,7 @@ static void schizo_pbm_strbuf_init(struct pci_pbm_info *pbm) ...@@ -1765,7 +1765,7 @@ static void schizo_pbm_strbuf_init(struct pci_pbm_info *pbm)
static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm) static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm)
{ {
struct pci_iommu *iommu = pbm->iommu; struct pci_iommu *iommu = pbm->iommu;
unsigned long tsbbase, i, tagbase, database, order; unsigned long i, tagbase, database;
u32 vdma[2], dma_mask; u32 vdma[2], dma_mask;
u64 control; u64 control;
int err, tsbsize; int err, tsbsize;
...@@ -1800,10 +1800,6 @@ static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm) ...@@ -1800,10 +1800,6 @@ static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm)
prom_halt(); prom_halt();
}; };
/* Setup initial software IOMMU state. */
spin_lock_init(&iommu->lock);
iommu->ctx_lowest_free = 1;
/* Register addresses, SCHIZO has iommu ctx flushing. */ /* Register addresses, SCHIZO has iommu ctx flushing. */
iommu->iommu_control = pbm->pbm_regs + SCHIZO_IOMMU_CONTROL; iommu->iommu_control = pbm->pbm_regs + SCHIZO_IOMMU_CONTROL;
iommu->iommu_tsbbase = pbm->pbm_regs + SCHIZO_IOMMU_TSBBASE; iommu->iommu_tsbbase = pbm->pbm_regs + SCHIZO_IOMMU_TSBBASE;
...@@ -1832,56 +1828,9 @@ static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm) ...@@ -1832,56 +1828,9 @@ static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm)
/* Leave diag mode enabled for full-flushing done /* Leave diag mode enabled for full-flushing done
* in pci_iommu.c * in pci_iommu.c
*/ */
pci_iommu_table_init(iommu, tsbsize * 8 * 1024, vdma[0], dma_mask);
iommu->dummy_page = __get_free_pages(GFP_KERNEL, 0); schizo_write(iommu->iommu_tsbbase, __pa(iommu->page_table));
if (!iommu->dummy_page) {
prom_printf("PSYCHO_IOMMU: Error, gfp(dummy_page) failed.\n");
prom_halt();
}
memset((void *)iommu->dummy_page, 0, PAGE_SIZE);
iommu->dummy_page_pa = (unsigned long) __pa(iommu->dummy_page);
/* Using assumed page size 8K with 128K entries we need 1MB iommu page
* table (128K ioptes * 8 bytes per iopte). This is
* page order 7 on UltraSparc.
*/
order = get_order(tsbsize * 8 * 1024);
tsbbase = __get_free_pages(GFP_KERNEL, order);
if (!tsbbase) {
prom_printf("%s: Error, gfp(tsb) failed.\n", pbm->name);
prom_halt();
}
iommu->page_table = (iopte_t *)tsbbase;
iommu->page_table_map_base = vdma[0];
iommu->dma_addr_mask = dma_mask;
pci_iommu_table_init(iommu, PAGE_SIZE << order);
switch (tsbsize) {
case 64:
iommu->page_table_sz_bits = 16;
break;
case 128:
iommu->page_table_sz_bits = 17;
break;
default:
prom_printf("iommu_init: Illegal TSB size %d\n", tsbsize);
prom_halt();
break;
};
/* We start with no consistent mappings. */
iommu->lowest_consistent_map =
1 << (iommu->page_table_sz_bits - PBM_LOGCLUSTERS);
for (i = 0; i < PBM_NCLUSTERS; i++) {
iommu->alloc_info[i].flush = 0;
iommu->alloc_info[i].next = 0;
}
schizo_write(iommu->iommu_tsbbase, __pa(tsbbase));
control = schizo_read(iommu->iommu_control); control = schizo_read(iommu->iommu_control);
control &= ~(SCHIZO_IOMMU_CTRL_TSBSZ | SCHIZO_IOMMU_CTRL_TBWSZ); control &= ~(SCHIZO_IOMMU_CTRL_TSBSZ | SCHIZO_IOMMU_CTRL_TBWSZ);
......
...@@ -1001,13 +1001,6 @@ void smp_penguin_jailcell(int irq, struct pt_regs *regs) ...@@ -1001,13 +1001,6 @@ void smp_penguin_jailcell(int irq, struct pt_regs *regs)
preempt_enable(); preempt_enable();
} }
extern unsigned long xcall_promstop;
void smp_promstop_others(void)
{
smp_cross_call(&xcall_promstop, 0, 0, 0);
}
#define prof_multiplier(__cpu) cpu_data(__cpu).multiplier #define prof_multiplier(__cpu) cpu_data(__cpu).multiplier
#define prof_counter(__cpu) cpu_data(__cpu).counter #define prof_counter(__cpu) cpu_data(__cpu).counter
......
...@@ -105,7 +105,7 @@ static void __init read_obp_memory(const char *property, ...@@ -105,7 +105,7 @@ static void __init read_obp_memory(const char *property,
regs[i].phys_addr = base; regs[i].phys_addr = base;
regs[i].reg_size = size; regs[i].reg_size = size;
} }
sort(regs, ents, sizeof(struct linux_prom64_registers), sort(regs, ents, sizeof(struct linux_prom64_registers),
cmp_p64, NULL); cmp_p64, NULL);
} }
...@@ -367,8 +367,11 @@ struct linux_prom_translation { ...@@ -367,8 +367,11 @@ struct linux_prom_translation {
unsigned long size; unsigned long size;
unsigned long data; unsigned long data;
}; };
static struct linux_prom_translation prom_trans[512] __initdata;
static unsigned int prom_trans_ents __initdata; /* Exported for kernel TLB miss handling in ktlb.S */
struct linux_prom_translation prom_trans[512] __read_mostly;
unsigned int prom_trans_ents __read_mostly;
unsigned int swapper_pgd_zero __read_mostly;
extern unsigned long prom_boot_page; extern unsigned long prom_boot_page;
extern void prom_remap(unsigned long physpage, unsigned long virtpage, int mmu_ihandle); extern void prom_remap(unsigned long physpage, unsigned long virtpage, int mmu_ihandle);
...@@ -378,122 +381,57 @@ extern void register_prom_callbacks(void); ...@@ -378,122 +381,57 @@ extern void register_prom_callbacks(void);
/* Exported for SMP bootup purposes. */ /* Exported for SMP bootup purposes. */
unsigned long kern_locked_tte_data; unsigned long kern_locked_tte_data;
/* Exported for kernel TLB miss handling in ktlb.S */
unsigned long prom_pmd_phys __read_mostly;
unsigned int swapper_pgd_zero __read_mostly;
static pmd_t *prompmd __read_mostly;
#define BASE_PAGE_SIZE 8192
/* /*
* Translate PROM's mapping we capture at boot time into physical address. * Translate PROM's mapping we capture at boot time into physical address.
* The second parameter is only set from prom_callback() invocations. * The second parameter is only set from prom_callback() invocations.
*/ */
unsigned long prom_virt_to_phys(unsigned long promva, int *error) unsigned long prom_virt_to_phys(unsigned long promva, int *error)
{ {
pmd_t *pmdp = prompmd + ((promva >> 23) & 0x7ff); int i;
pte_t *ptep;
unsigned long base;
if (pmd_none(*pmdp)) {
if (error)
*error = 1;
return 0;
}
ptep = (pte_t *)__pmd_page(*pmdp) + ((promva >> 13) & 0x3ff);
if (!pte_present(*ptep)) {
if (error)
*error = 1;
return 0;
}
if (error) {
*error = 0;
return pte_val(*ptep);
}
base = pte_val(*ptep) & _PAGE_PADDR;
return base + (promva & (BASE_PAGE_SIZE - 1));
}
/* The obp translations are saved based on 8k pagesize, since obp can for (i = 0; i < prom_trans_ents; i++) {
* use a mixture of pagesizes. Misses to the LOW_OBP_ADDRESS -> struct linux_prom_translation *p = &prom_trans[i];
* HI_OBP_ADDRESS range are handled in entry.S and do not use the vpte
* scheme (also, see rant in inherit_locked_prom_mappings()).
*/
static void __init build_obp_range(unsigned long start, unsigned long end, unsigned long data)
{
unsigned long vaddr;
for (vaddr = start; vaddr < end; vaddr += BASE_PAGE_SIZE) { if (promva >= p->virt &&
unsigned long val; promva < (p->virt + p->size)) {
pmd_t *pmd; unsigned long base = p->data & _PAGE_PADDR;
pte_t *pte;
pmd = prompmd + ((vaddr >> 23) & 0x7ff); if (error)
if (pmd_none(*pmd)) { *error = 0;
pte = __alloc_bootmem(BASE_PAGE_SIZE, BASE_PAGE_SIZE, return base + (promva & (8192 - 1));
PAGE_SIZE);
if (!pte)
prom_halt();
memset(pte, 0, BASE_PAGE_SIZE);
pmd_set(pmd, pte);
} }
pte = (pte_t *) __pmd_page(*pmd) + ((vaddr >> 13) & 0x3ff);
val = data;
/* Clear diag TTE bits. */
if (tlb_type == spitfire)
val &= ~0x0003fe0000000000UL;
set_pte_at(&init_mm, vaddr, pte,
__pte(val | _PAGE_MODIFIED));
data += BASE_PAGE_SIZE;
} }
if (error)
*error = 1;
return 0UL;
} }
/* The obp translations are saved based on 8k pagesize, since obp can
* use a mixture of pagesizes. Misses to the LOW_OBP_ADDRESS ->
* HI_OBP_ADDRESS range are handled in ktlb.S and do not use the vpte
* scheme (also, see rant in inherit_locked_prom_mappings()).
*/
static inline int in_obp_range(unsigned long vaddr) static inline int in_obp_range(unsigned long vaddr)
{ {
return (vaddr >= LOW_OBP_ADDRESS && return (vaddr >= LOW_OBP_ADDRESS &&
vaddr < HI_OBP_ADDRESS); vaddr < HI_OBP_ADDRESS);
} }
#define OBP_PMD_SIZE 2048 static int cmp_ptrans(const void *a, const void *b)
static void __init build_obp_pgtable(void)
{ {
unsigned long i; const struct linux_prom_translation *x = a, *y = b;
prompmd = __alloc_bootmem(OBP_PMD_SIZE, OBP_PMD_SIZE, PAGE_SIZE);
if (!prompmd)
prom_halt();
memset(prompmd, 0, OBP_PMD_SIZE);
prom_pmd_phys = __pa(prompmd);
for (i = 0; i < prom_trans_ents; i++) {
unsigned long start, end;
if (!in_obp_range(prom_trans[i].virt))
continue;
start = prom_trans[i].virt; if (x->virt > y->virt)
end = start + prom_trans[i].size; return 1;
if (end > HI_OBP_ADDRESS) if (x->virt < y->virt)
end = HI_OBP_ADDRESS; return -1;
return 0;
build_obp_range(start, end, prom_trans[i].data);
}
} }
/* Read OBP translations property into 'prom_trans[]'. /* Read OBP translations property into 'prom_trans[]'. */
* Return the number of entries.
*/
static void __init read_obp_translations(void) static void __init read_obp_translations(void)
{ {
int n, node; int n, node, ents, first, last, i;
node = prom_finddevice("/virtual-memory"); node = prom_finddevice("/virtual-memory");
n = prom_getproplen(node, "translations"); n = prom_getproplen(node, "translations");
...@@ -515,7 +453,41 @@ static void __init read_obp_translations(void) ...@@ -515,7 +453,41 @@ static void __init read_obp_translations(void)
n = n / sizeof(struct linux_prom_translation); n = n / sizeof(struct linux_prom_translation);
prom_trans_ents = n; ents = n;
sort(prom_trans, ents, sizeof(struct linux_prom_translation),
cmp_ptrans, NULL);
/* Now kick out all the non-OBP entries. */
for (i = 0; i < ents; i++) {
if (in_obp_range(prom_trans[i].virt))
break;
}
first = i;
for (; i < ents; i++) {
if (!in_obp_range(prom_trans[i].virt))
break;
}
last = i;
for (i = 0; i < (last - first); i++) {
struct linux_prom_translation *src = &prom_trans[i + first];
struct linux_prom_translation *dest = &prom_trans[i];
*dest = *src;
}
for (; i < ents; i++) {
struct linux_prom_translation *dest = &prom_trans[i];
dest->virt = dest->size = dest->data = 0x0UL;
}
prom_trans_ents = last - first;
if (tlb_type == spitfire) {
/* Clear diag TTE bits. */
for (i = 0; i < prom_trans_ents; i++)
prom_trans[i].data &= ~0x0003fe0000000000UL;
}
} }
static void __init remap_kernel(void) static void __init remap_kernel(void)
...@@ -553,21 +525,18 @@ static void __init remap_kernel(void) ...@@ -553,21 +525,18 @@ static void __init remap_kernel(void)
} }
static void __init inherit_prom_mappings_pre(void) static void __init inherit_prom_mappings(void)
{ {
read_obp_translations(); read_obp_translations();
/* Now fixup OBP's idea about where we really are mapped. */ /* Now fixup OBP's idea about where we really are mapped. */
prom_printf("Remapping the kernel... "); prom_printf("Remapping the kernel... ");
remap_kernel(); remap_kernel();
prom_printf("done.\n"); prom_printf("done.\n");
}
static void __init inherit_prom_mappings_post(void) prom_printf("Registering callbacks... ");
{
build_obp_pgtable();
register_prom_callbacks(); register_prom_callbacks();
prom_printf("done.\n");
} }
/* The OBP specifications for sun4u mark 0xfffffffc00000000 and /* The OBP specifications for sun4u mark 0xfffffffc00000000 and
...@@ -1519,7 +1488,7 @@ void __init paging_init(void) ...@@ -1519,7 +1488,7 @@ void __init paging_init(void)
swapper_pgd_zero = pgd_val(swapper_pg_dir[0]); swapper_pgd_zero = pgd_val(swapper_pg_dir[0]);
inherit_prom_mappings_pre(); inherit_prom_mappings();
/* Ok, we can use our TLB miss and window trap handlers safely. /* Ok, we can use our TLB miss and window trap handlers safely.
* We need to do a quick peek here to see if we are on StarFire * We need to do a quick peek here to see if we are on StarFire
...@@ -1530,23 +1499,15 @@ void __init paging_init(void) ...@@ -1530,23 +1499,15 @@ void __init paging_init(void)
extern void setup_tba(int); extern void setup_tba(int);
setup_tba(this_is_starfire); setup_tba(this_is_starfire);
} }
__flush_tlb_all();
/* Everything from this point forward, until we are done with inherit_locked_prom_mappings(1);
* inherit_prom_mappings_post(), must complete successfully
* without calling into the firmware. The firwmare page tables __flush_tlb_all();
* have not been built, but we are running on the Linux kernel's
* trap table.
*/
/* Setup bootmem... */ /* Setup bootmem... */
pages_avail = 0; pages_avail = 0;
last_valid_pfn = end_pfn = bootmem_init(&pages_avail); last_valid_pfn = end_pfn = bootmem_init(&pages_avail);
inherit_prom_mappings_post();
inherit_locked_prom_mappings(1);
#ifdef CONFIG_DEBUG_PAGEALLOC #ifdef CONFIG_DEBUG_PAGEALLOC
kernel_physical_mapping_init(); kernel_physical_mapping_init();
#endif #endif
......
...@@ -453,22 +453,6 @@ xcall_flush_dcache_page_spitfire: /* %g1 == physical page address ...@@ -453,22 +453,6 @@ xcall_flush_dcache_page_spitfire: /* %g1 == physical page address
nop nop
nop nop
.globl xcall_promstop
xcall_promstop:
rdpr %pstate, %g2
wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate
rdpr %pil, %g2
wrpr %g0, 15, %pil
sethi %hi(109f), %g7
b,pt %xcc, etrap_irq
109: or %g7, %lo(109b), %g7
flushw
call prom_stopself
nop
/* We should not return, just spin if we do... */
1: b,a,pt %xcc, 1b
nop
.data .data
errata32_hwbug: errata32_hwbug:
......
...@@ -68,19 +68,11 @@ void prom_cmdline(void) ...@@ -68,19 +68,11 @@ void prom_cmdline(void)
local_irq_restore(flags); local_irq_restore(flags);
} }
#ifdef CONFIG_SMP
extern void smp_promstop_others(void);
#endif
/* Drop into the prom, but completely terminate the program. /* Drop into the prom, but completely terminate the program.
* No chance of continuing. * No chance of continuing.
*/ */
void prom_halt(void) void prom_halt(void)
{ {
#ifdef CONFIG_SMP
smp_promstop_others();
udelay(8000);
#endif
again: again:
p1275_cmd("exit", P1275_INOUT(0, 0)); p1275_cmd("exit", P1275_INOUT(0, 0));
goto again; /* PROM is out to get me -DaveM */ goto again; /* PROM is out to get me -DaveM */
...@@ -88,10 +80,6 @@ void prom_halt(void) ...@@ -88,10 +80,6 @@ void prom_halt(void)
void prom_halt_power_off(void) void prom_halt_power_off(void)
{ {
#ifdef CONFIG_SMP
smp_promstop_others();
udelay(8000);
#endif
p1275_cmd("SUNW,power-off", P1275_INOUT(0, 0)); p1275_cmd("SUNW,power-off", P1275_INOUT(0, 0));
/* if nothing else helps, we just halt */ /* if nothing else helps, we just halt */
......
...@@ -13,7 +13,7 @@ mcast-objs := mcast_kern.o mcast_user.o ...@@ -13,7 +13,7 @@ mcast-objs := mcast_kern.o mcast_user.o
net-objs := net_kern.o net_user.o net-objs := net_kern.o net_user.o
mconsole-objs := mconsole_kern.o mconsole_user.o mconsole-objs := mconsole_kern.o mconsole_user.o
hostaudio-objs := hostaudio_kern.o hostaudio-objs := hostaudio_kern.o
ubd-objs := ubd_kern.o ubd-objs := ubd_kern.o ubd_user.o
port-objs := port_kern.o port_user.o port-objs := port_kern.o port_user.o
harddog-objs := harddog_kern.o harddog_user.o harddog-objs := harddog_kern.o harddog_user.o
......
此差异已折叠。
/*
* Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
* Copyright (C) 2001 Ridgerun,Inc (glonnon@ridgerun.com)
* Licensed under the GPL
*/
#include <stddef.h>
#include <unistd.h>
#include <errno.h>
#include <sched.h>
#include <signal.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/mman.h>
#include <sys/param.h>
#include "asm/types.h"
#include "user_util.h"
#include "kern_util.h"
#include "user.h"
#include "ubd_user.h"
#include "os.h"
#include "cow.h"
#include <endian.h>
#include <byteswap.h>
void ignore_sigwinch_sig(void)
{
signal(SIGWINCH, SIG_IGN);
}
int start_io_thread(unsigned long sp, int *fd_out)
{
int pid, fds[2], err;
err = os_pipe(fds, 1, 1);
if(err < 0){
printk("start_io_thread - os_pipe failed, err = %d\n", -err);
goto out;
}
kernel_fd = fds[0];
*fd_out = fds[1];
pid = clone(io_thread, (void *) sp, CLONE_FILES | CLONE_VM | SIGCHLD,
NULL);
if(pid < 0){
printk("start_io_thread - clone failed : errno = %d\n", errno);
err = -errno;
goto out_close;
}
return(pid);
out_close:
os_close_file(fds[0]);
os_close_file(fds[1]);
kernel_fd = -1;
*fd_out = -1;
out:
return(err);
}
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-file-style: "linux"
* End:
*/
...@@ -14,27 +14,15 @@ struct aio_thread_reply { ...@@ -14,27 +14,15 @@ struct aio_thread_reply {
}; };
struct aio_context { struct aio_context {
enum aio_type type;
int fd;
void *data;
int len;
unsigned long long offset;
int reply_fd; int reply_fd;
struct aio_context *next; struct aio_context *next;
}; };
#define INIT_AIO(aio_type, aio_fd, aio_data, aio_len, aio_offset, \
aio_reply_fd) \
{ .type = aio_type, \
.fd = aio_fd, \
.data = aio_data, \
.len = aio_len, \
.offset = aio_offset, \
.reply_fd = aio_reply_fd }
#define INIT_AIO_CONTEXT { .reply_fd = -1, \ #define INIT_AIO_CONTEXT { .reply_fd = -1, \
.next = NULL } .next = NULL }
extern int submit_aio(struct aio_context *aio); extern int submit_aio(enum aio_type type, int fd, char *buf, int len,
unsigned long long offset, int reply_fd,
struct aio_context *aio);
#endif #endif
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#ifndef __OS_H__ #ifndef __OS_H__
#define __OS_H__ #define __OS_H__
#include "uml-config.h"
#include "asm/types.h" #include "asm/types.h"
#include "../os/include/file.h" #include "../os/include/file.h"
...@@ -159,7 +160,11 @@ extern int can_do_skas(void); ...@@ -159,7 +160,11 @@ extern int can_do_skas(void);
/* Make sure they are clear when running in TT mode. Required by /* Make sure they are clear when running in TT mode. Required by
* SEGV_MAYBE_FIXABLE */ * SEGV_MAYBE_FIXABLE */
#ifdef UML_CONFIG_MODE_SKAS
#define clear_can_do_skas() do { ptrace_faultinfo = proc_mm = 0; } while (0) #define clear_can_do_skas() do { ptrace_faultinfo = proc_mm = 0; } while (0)
#else
#define clear_can_do_skas() do {} while (0)
#endif
/* mem.c */ /* mem.c */
extern int create_mem_file(unsigned long len); extern int create_mem_file(unsigned long len);
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <signal.h> #include <signal.h>
#include <string.h>
#include <errno.h> #include <errno.h>
#include <sched.h> #include <sched.h>
#include <sys/syscall.h> #include <sys/syscall.h>
...@@ -17,31 +16,18 @@ ...@@ -17,31 +16,18 @@
#include "user.h" #include "user.h"
#include "mode.h" #include "mode.h"
struct aio_thread_req {
enum aio_type type;
int io_fd;
unsigned long long offset;
char *buf;
int len;
struct aio_context *aio;
};
static int aio_req_fd_r = -1; static int aio_req_fd_r = -1;
static int aio_req_fd_w = -1; static int aio_req_fd_w = -1;
static int update_aio(struct aio_context *aio, int res)
{
if(res < 0)
aio->len = res;
else if((res == 0) && (aio->type == AIO_READ)){
/* This is the EOF case - we have hit the end of the file
* and it ends in a partial block, so we fill the end of
* the block with zeros and claim success.
*/
memset(aio->data, 0, aio->len);
aio->len = 0;
}
else if(res > 0){
aio->len -= res;
aio->data += res;
aio->offset += res;
return aio->len;
}
return 0;
}
#if defined(HAVE_AIO_ABI) #if defined(HAVE_AIO_ABI)
#include <linux/aio_abi.h> #include <linux/aio_abi.h>
...@@ -80,7 +66,8 @@ static long io_getevents(aio_context_t ctx_id, long min_nr, long nr, ...@@ -80,7 +66,8 @@ static long io_getevents(aio_context_t ctx_id, long min_nr, long nr,
* that it now backs the mmapped area. * that it now backs the mmapped area.
*/ */
static int do_aio(aio_context_t ctx, struct aio_context *aio) static int do_aio(aio_context_t ctx, enum aio_type type, int fd, char *buf,
int len, unsigned long long offset, struct aio_context *aio)
{ {
struct iocb iocb, *iocbp = &iocb; struct iocb iocb, *iocbp = &iocb;
char c; char c;
...@@ -88,39 +75,40 @@ static int do_aio(aio_context_t ctx, struct aio_context *aio) ...@@ -88,39 +75,40 @@ static int do_aio(aio_context_t ctx, struct aio_context *aio)
iocb = ((struct iocb) { .aio_data = (unsigned long) aio, iocb = ((struct iocb) { .aio_data = (unsigned long) aio,
.aio_reqprio = 0, .aio_reqprio = 0,
.aio_fildes = aio->fd, .aio_fildes = fd,
.aio_buf = (unsigned long) aio->data, .aio_buf = (unsigned long) buf,
.aio_nbytes = aio->len, .aio_nbytes = len,
.aio_offset = aio->offset, .aio_offset = offset,
.aio_reserved1 = 0, .aio_reserved1 = 0,
.aio_reserved2 = 0, .aio_reserved2 = 0,
.aio_reserved3 = 0 }); .aio_reserved3 = 0 });
switch(aio->type){ switch(type){
case AIO_READ: case AIO_READ:
iocb.aio_lio_opcode = IOCB_CMD_PREAD; iocb.aio_lio_opcode = IOCB_CMD_PREAD;
err = io_submit(ctx, 1, &iocbp);
break; break;
case AIO_WRITE: case AIO_WRITE:
iocb.aio_lio_opcode = IOCB_CMD_PWRITE; iocb.aio_lio_opcode = IOCB_CMD_PWRITE;
err = io_submit(ctx, 1, &iocbp);
break; break;
case AIO_MMAP: case AIO_MMAP:
iocb.aio_lio_opcode = IOCB_CMD_PREAD; iocb.aio_lio_opcode = IOCB_CMD_PREAD;
iocb.aio_buf = (unsigned long) &c; iocb.aio_buf = (unsigned long) &c;
iocb.aio_nbytes = sizeof(c); iocb.aio_nbytes = sizeof(c);
err = io_submit(ctx, 1, &iocbp);
break; break;
default: default:
printk("Bogus op in do_aio - %d\n", aio->type); printk("Bogus op in do_aio - %d\n", type);
err = -EINVAL; err = -EINVAL;
goto out; break;
} }
err = io_submit(ctx, 1, &iocbp);
if(err > 0) if(err > 0)
err = 0; err = 0;
else else
err = -errno; err = -errno;
out:
return err; return err;
} }
...@@ -129,9 +117,8 @@ static aio_context_t ctx = 0; ...@@ -129,9 +117,8 @@ static aio_context_t ctx = 0;
static int aio_thread(void *arg) static int aio_thread(void *arg)
{ {
struct aio_thread_reply reply; struct aio_thread_reply reply;
struct aio_context *aio;
struct io_event event; struct io_event event;
int err, n; int err, n, reply_fd;
signal(SIGWINCH, SIG_IGN); signal(SIGWINCH, SIG_IGN);
...@@ -144,22 +131,14 @@ static int aio_thread(void *arg) ...@@ -144,22 +131,14 @@ static int aio_thread(void *arg)
"errno = %d\n", errno); "errno = %d\n", errno);
} }
else { 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);
continue;
}
reply = ((struct aio_thread_reply) reply = ((struct aio_thread_reply)
{ .data = aio, { .data = (void *) (long) event.data,
.err = aio->len }); .err = event.res });
err = os_write_file(aio->reply_fd, &reply, reply_fd = ((struct aio_context *) reply.data)->reply_fd;
sizeof(reply)); err = os_write_file(reply_fd, &reply, sizeof(reply));
if(err != sizeof(reply)) if(err != sizeof(reply))
printk("aio_thread - write failed, " printk("aio_thread - write failed, fd = %d, "
"fd = %d, err = %d\n", aio->reply_fd, "err = %d\n", aio_req_fd_r, -err);
-err);
} }
} }
return 0; return 0;
...@@ -167,35 +146,35 @@ static int aio_thread(void *arg) ...@@ -167,35 +146,35 @@ static int aio_thread(void *arg)
#endif #endif
static int do_not_aio(struct aio_context *aio) static int do_not_aio(struct aio_thread_req *req)
{ {
char c; char c;
int err; int err;
switch(aio->type){ switch(req->type){
case AIO_READ: case AIO_READ:
err = os_seek_file(aio->fd, aio->offset); err = os_seek_file(req->io_fd, req->offset);
if(err) if(err)
goto out; goto out;
err = os_read_file(aio->fd, aio->data, aio->len); err = os_read_file(req->io_fd, req->buf, req->len);
break; break;
case AIO_WRITE: case AIO_WRITE:
err = os_seek_file(aio->fd, aio->offset); err = os_seek_file(req->io_fd, req->offset);
if(err) if(err)
goto out; goto out;
err = os_write_file(aio->fd, aio->data, aio->len); err = os_write_file(req->io_fd, req->buf, req->len);
break; break;
case AIO_MMAP: case AIO_MMAP:
err = os_seek_file(aio->fd, aio->offset); err = os_seek_file(req->io_fd, req->offset);
if(err) if(err)
goto out; goto out;
err = os_read_file(aio->fd, &c, sizeof(c)); err = os_read_file(req->io_fd, &c, sizeof(c));
break; break;
default: default:
printk("do_not_aio - bad request type : %d\n", aio->type); printk("do_not_aio - bad request type : %d\n", req->type);
err = -EINVAL; err = -EINVAL;
break; break;
} }
...@@ -206,14 +185,14 @@ static int do_not_aio(struct aio_context *aio) ...@@ -206,14 +185,14 @@ static int do_not_aio(struct aio_context *aio)
static int not_aio_thread(void *arg) static int not_aio_thread(void *arg)
{ {
struct aio_context *aio; struct aio_thread_req req;
struct aio_thread_reply reply; struct aio_thread_reply reply;
int err; int err;
signal(SIGWINCH, SIG_IGN); signal(SIGWINCH, SIG_IGN);
while(1){ while(1){
err = os_read_file(aio_req_fd_r, &aio, sizeof(aio)); err = os_read_file(aio_req_fd_r, &req, sizeof(req));
if(err != sizeof(aio)){ if(err != sizeof(req)){
if(err < 0) if(err < 0)
printk("not_aio_thread - read failed, " printk("not_aio_thread - read failed, "
"fd = %d, err = %d\n", aio_req_fd_r, "fd = %d, err = %d\n", aio_req_fd_r,
...@@ -224,34 +203,17 @@ static int not_aio_thread(void *arg) ...@@ -224,34 +203,17 @@ static int not_aio_thread(void *arg)
} }
continue; continue;
} }
again: err = do_not_aio(&req);
err = do_not_aio(aio); reply = ((struct aio_thread_reply) { .data = req.aio,
.err = err });
if(update_aio(aio, err)) err = os_write_file(req.aio->reply_fd, &reply, sizeof(reply));
goto again;
reply = ((struct aio_thread_reply) { .data = aio,
.err = aio->len });
err = os_write_file(aio->reply_fd, &reply, sizeof(reply));
if(err != sizeof(reply)) if(err != sizeof(reply))
printk("not_aio_thread - write failed, fd = %d, " printk("not_aio_thread - write failed, fd = %d, "
"err = %d\n", aio_req_fd_r, -err); "err = %d\n", aio_req_fd_r, -err);
} }
} }
static int submit_aio_24(struct aio_context *aio)
{
int err;
err = os_write_file(aio_req_fd_w, &aio, sizeof(aio));
if(err == sizeof(aio))
err = 0;
return err;
}
static int aio_pid = -1; static int aio_pid = -1;
static int (*submit_proc)(struct aio_context *aio);
static int init_aio_24(void) static int init_aio_24(void)
{ {
...@@ -283,33 +245,11 @@ static int init_aio_24(void) ...@@ -283,33 +245,11 @@ static int init_aio_24(void)
#endif #endif
printk("2.6 host AIO support not used - falling back to I/O " printk("2.6 host AIO support not used - falling back to I/O "
"thread\n"); "thread\n");
submit_proc = submit_aio_24;
return 0; return 0;
} }
#ifdef HAVE_AIO_ABI #ifdef HAVE_AIO_ABI
#define DEFAULT_24_AIO 0 #define DEFAULT_24_AIO 0
static int submit_aio_26(struct aio_context *aio)
{
struct aio_thread_reply reply;
int err;
err = do_aio(ctx, aio);
if(err){
reply = ((struct aio_thread_reply) { .data = aio,
.err = err });
err = os_write_file(aio->reply_fd, &reply, sizeof(reply));
if(err != sizeof(reply))
printk("submit_aio_26 - write failed, "
"fd = %d, err = %d\n", aio->reply_fd, -err);
else err = 0;
}
return err;
}
static int init_aio_26(void) static int init_aio_26(void)
{ {
unsigned long stack; unsigned long stack;
...@@ -330,22 +270,39 @@ static int init_aio_26(void) ...@@ -330,22 +270,39 @@ static int init_aio_26(void)
aio_pid = err; aio_pid = err;
printk("Using 2.6 host AIO\n"); printk("Using 2.6 host AIO\n");
return 0;
}
static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len,
unsigned long long offset, struct aio_context *aio)
{
struct aio_thread_reply reply;
int err;
submit_proc = submit_aio_26; err = do_aio(ctx, type, io_fd, buf, len, offset, aio);
if(err){
reply = ((struct aio_thread_reply) { .data = aio,
.err = err });
err = os_write_file(aio->reply_fd, &reply, sizeof(reply));
if(err != sizeof(reply))
printk("submit_aio_26 - write failed, "
"fd = %d, err = %d\n", aio->reply_fd, -err);
else err = 0;
}
return 0; return err;
} }
#else #else
#define DEFAULT_24_AIO 1 #define DEFAULT_24_AIO 1
static int submit_aio_26(struct aio_context *aio) static int init_aio_26(void)
{ {
return -ENOSYS; return -ENOSYS;
} }
static int init_aio_26(void) static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len,
unsigned long long offset, struct aio_context *aio)
{ {
submit_proc = submit_aio_26;
return -ENOSYS; return -ENOSYS;
} }
#endif #endif
...@@ -412,7 +369,33 @@ static void exit_aio(void) ...@@ -412,7 +369,33 @@ static void exit_aio(void)
__uml_exitcall(exit_aio); __uml_exitcall(exit_aio);
int submit_aio(struct aio_context *aio) static int submit_aio_24(enum aio_type type, int io_fd, char *buf, int len,
unsigned long long offset, struct aio_context *aio)
{ {
return (*submit_proc)(aio); struct aio_thread_req req = { .type = type,
.io_fd = io_fd,
.offset = offset,
.buf = buf,
.len = len,
.aio = aio,
};
int err;
err = os_write_file(aio_req_fd_w, &req, sizeof(req));
if(err == sizeof(req))
err = 0;
return err;
}
int submit_aio(enum aio_type type, int io_fd, char *buf, int len,
unsigned long long offset, int reply_fd,
struct aio_context *aio)
{
aio->reply_fd = reply_fd;
if(aio_24)
return submit_aio_24(type, io_fd, buf, len, offset, aio);
else {
return submit_aio_26(type, io_fd, buf, len, offset, aio);
}
} }
...@@ -830,6 +830,9 @@ static int __init mbcs_init(void) ...@@ -830,6 +830,9 @@ static int __init mbcs_init(void)
{ {
int rv; int rv;
if (!ia64_platform_is("sn2"))
return -ENODEV;
// Put driver into chrdevs[]. Get major number. // Put driver into chrdevs[]. Get major number.
rv = register_chrdev(mbcs_major, DEVICE_NAME, &mbcs_ops); rv = register_chrdev(mbcs_major, DEVICE_NAME, &mbcs_ops);
if (rv < 0) { if (rv < 0) {
......
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
MODULE_AUTHOR("Abhay Salunke <abhay_salunke@dell.com>"); MODULE_AUTHOR("Abhay Salunke <abhay_salunke@dell.com>");
MODULE_DESCRIPTION("Driver for updating BIOS image on DELL systems"); MODULE_DESCRIPTION("Driver for updating BIOS image on DELL systems");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_VERSION("2.0"); MODULE_VERSION("3.0");
#define BIOS_SCAN_LIMIT 0xffffffff #define BIOS_SCAN_LIMIT 0xffffffff
#define MAX_IMAGE_LENGTH 16 #define MAX_IMAGE_LENGTH 16
...@@ -62,15 +62,16 @@ static struct _rbu_data { ...@@ -62,15 +62,16 @@ static struct _rbu_data {
int dma_alloc; int dma_alloc;
spinlock_t lock; spinlock_t lock;
unsigned long packet_read_count; unsigned long packet_read_count;
unsigned long packet_write_count;
unsigned long num_packets; unsigned long num_packets;
unsigned long packetsize; unsigned long packetsize;
unsigned long imagesize;
int entry_created; int entry_created;
} rbu_data; } rbu_data;
static char image_type[MAX_IMAGE_LENGTH + 1] = "mono"; static char image_type[MAX_IMAGE_LENGTH + 1] = "mono";
module_param_string(image_type, image_type, sizeof (image_type), 0); module_param_string(image_type, image_type, sizeof (image_type), 0);
MODULE_PARM_DESC(image_type, "BIOS image type. choose- mono or packet"); MODULE_PARM_DESC(image_type,
"BIOS image type. choose- mono or packet or init");
struct packet_data { struct packet_data {
struct list_head list; struct list_head list;
...@@ -88,55 +89,13 @@ static dma_addr_t dell_rbu_dmaaddr; ...@@ -88,55 +89,13 @@ static dma_addr_t dell_rbu_dmaaddr;
static void init_packet_head(void) static void init_packet_head(void)
{ {
INIT_LIST_HEAD(&packet_data_head.list); INIT_LIST_HEAD(&packet_data_head.list);
rbu_data.packet_write_count = 0;
rbu_data.packet_read_count = 0; rbu_data.packet_read_count = 0;
rbu_data.num_packets = 0; rbu_data.num_packets = 0;
rbu_data.packetsize = 0; rbu_data.packetsize = 0;
rbu_data.imagesize = 0;
} }
static int fill_last_packet(void *data, size_t length) static int create_packet(void *data, size_t length)
{
struct list_head *ptemp_list;
struct packet_data *packet = NULL;
int packet_count = 0;
pr_debug("fill_last_packet: entry \n");
if (!rbu_data.num_packets) {
pr_debug("fill_last_packet: num_packets=0\n");
return -ENOMEM;
}
packet_count = rbu_data.num_packets;
ptemp_list = (&packet_data_head.list)->prev;
packet = list_entry(ptemp_list, struct packet_data, list);
if ((rbu_data.packet_write_count + length) > rbu_data.packetsize) {
pr_debug("dell_rbu:%s: packet size data "
"overrun\n", __FUNCTION__);
return -EINVAL;
}
pr_debug("fill_last_packet : buffer = %p\n", packet->data);
memcpy((packet->data + rbu_data.packet_write_count), data, length);
if ((rbu_data.packet_write_count + length) == rbu_data.packetsize) {
/*
* this was the last data chunk in the packet
* so reinitialize the packet data counter to zero
*/
rbu_data.packet_write_count = 0;
} else
rbu_data.packet_write_count += length;
pr_debug("fill_last_packet: exit \n");
return 0;
}
static int create_packet(size_t length)
{ {
struct packet_data *newpacket; struct packet_data *newpacket;
int ordernum = 0; int ordernum = 0;
...@@ -186,9 +145,11 @@ static int create_packet(size_t length) ...@@ -186,9 +145,11 @@ static int create_packet(size_t length)
INIT_LIST_HEAD(&newpacket->list); INIT_LIST_HEAD(&newpacket->list);
list_add_tail(&newpacket->list, &packet_data_head.list); list_add_tail(&newpacket->list, &packet_data_head.list);
/* /*
* packets have fixed size * packets may not have fixed size
*/ */
newpacket->length = rbu_data.packetsize; newpacket->length = length;
memcpy(newpacket->data, data, length);
pr_debug("create_packet: exit \n"); pr_debug("create_packet: exit \n");
...@@ -198,13 +159,37 @@ static int create_packet(size_t length) ...@@ -198,13 +159,37 @@ static int create_packet(size_t length)
static int packetize_data(void *data, size_t length) static int packetize_data(void *data, size_t length)
{ {
int rc = 0; int rc = 0;
int done = 0;
int packet_length;
u8 *temp;
u8 *end = (u8 *) data + length;
pr_debug("packetize_data: data length %d\n", length);
if (!rbu_data.packetsize) {
printk(KERN_WARNING
"dell_rbu: packetsize not specified\n");
return -EIO;
}
if (!rbu_data.packet_write_count) { temp = (u8 *) data;
if ((rc = create_packet(length)))
/* packetize the hunk */
while (!done) {
if ((temp + rbu_data.packetsize) < end)
packet_length = rbu_data.packetsize;
else {
/* this is the last packet */
packet_length = end - temp;
done = 1;
}
if ((rc = create_packet(temp, packet_length)))
return rc; return rc;
pr_debug("%lu:%lu\n", temp, (end - temp));
temp += packet_length;
} }
if ((rc = fill_last_packet(data, length)))
return rc; rbu_data.imagesize = length;
return rc; return rc;
} }
...@@ -243,7 +228,7 @@ static int do_packet_read(char *data, struct list_head *ptemp_list, ...@@ -243,7 +228,7 @@ static int do_packet_read(char *data, struct list_head *ptemp_list,
return bytes_copied; return bytes_copied;
} }
static int packet_read_list(char *data, size_t *pread_length) static int packet_read_list(char *data, size_t * pread_length)
{ {
struct list_head *ptemp_list; struct list_head *ptemp_list;
int temp_count = 0; int temp_count = 0;
...@@ -303,10 +288,9 @@ static void packet_empty_list(void) ...@@ -303,10 +288,9 @@ static void packet_empty_list(void)
newpacket->ordernum); newpacket->ordernum);
kfree(newpacket); kfree(newpacket);
} }
rbu_data.packet_write_count = 0;
rbu_data.packet_read_count = 0; rbu_data.packet_read_count = 0;
rbu_data.num_packets = 0; rbu_data.num_packets = 0;
rbu_data.packetsize = 0; rbu_data.imagesize = 0;
} }
/* /*
...@@ -425,7 +409,6 @@ static ssize_t read_packet_data(char *buffer, loff_t pos, size_t count) ...@@ -425,7 +409,6 @@ static ssize_t read_packet_data(char *buffer, loff_t pos, size_t count)
size_t bytes_left; size_t bytes_left;
size_t data_length; size_t data_length;
char *ptempBuf = buffer; char *ptempBuf = buffer;
unsigned long imagesize;
/* check to see if we have something to return */ /* check to see if we have something to return */
if (rbu_data.num_packets == 0) { if (rbu_data.num_packets == 0) {
...@@ -434,22 +417,20 @@ static ssize_t read_packet_data(char *buffer, loff_t pos, size_t count) ...@@ -434,22 +417,20 @@ static ssize_t read_packet_data(char *buffer, loff_t pos, size_t count)
goto read_rbu_data_exit; goto read_rbu_data_exit;
} }
imagesize = rbu_data.num_packets * rbu_data.packetsize; if (pos > rbu_data.imagesize) {
if (pos > imagesize) {
retval = 0; retval = 0;
printk(KERN_WARNING "dell_rbu:read_packet_data: " printk(KERN_WARNING "dell_rbu:read_packet_data: "
"data underrun\n"); "data underrun\n");
goto read_rbu_data_exit; goto read_rbu_data_exit;
} }
bytes_left = imagesize - pos; bytes_left = rbu_data.imagesize - pos;
data_length = min(bytes_left, count); data_length = min(bytes_left, count);
if ((retval = packet_read_list(ptempBuf, &data_length)) < 0) if ((retval = packet_read_list(ptempBuf, &data_length)) < 0)
goto read_rbu_data_exit; goto read_rbu_data_exit;
if ((pos + count) > imagesize) { if ((pos + count) > rbu_data.imagesize) {
rbu_data.packet_read_count = 0; rbu_data.packet_read_count = 0;
/* this was the last copy */ /* this was the last copy */
retval = bytes_left; retval = bytes_left;
...@@ -499,7 +480,7 @@ static ssize_t read_rbu_mono_data(char *buffer, loff_t pos, size_t count) ...@@ -499,7 +480,7 @@ static ssize_t read_rbu_mono_data(char *buffer, loff_t pos, size_t count)
} }
static ssize_t read_rbu_data(struct kobject *kobj, char *buffer, static ssize_t read_rbu_data(struct kobject *kobj, char *buffer,
loff_t pos, size_t count) loff_t pos, size_t count)
{ {
ssize_t ret_count = 0; ssize_t ret_count = 0;
...@@ -531,13 +512,18 @@ static void callbackfn_rbu(const struct firmware *fw, void *context) ...@@ -531,13 +512,18 @@ static void callbackfn_rbu(const struct firmware *fw, void *context)
memcpy(rbu_data.image_update_buffer, memcpy(rbu_data.image_update_buffer,
fw->data, fw->size); fw->data, fw->size);
} else if (!strcmp(image_type, "packet")) { } else if (!strcmp(image_type, "packet")) {
if (!rbu_data.packetsize) /*
rbu_data.packetsize = fw->size; * we need to free previous packets if a
else if (rbu_data.packetsize != fw->size) { * new hunk of packets needs to be downloaded
*/
packet_empty_list();
if (packetize_data(fw->data, fw->size))
/* Incase something goes wrong when we are
* in middle of packetizing the data, we
* need to free up whatever packets might
* have been created before we quit.
*/
packet_empty_list(); packet_empty_list();
rbu_data.packetsize = fw->size;
}
packetize_data(fw->data, fw->size);
} else } else
pr_debug("invalid image type specified.\n"); pr_debug("invalid image type specified.\n");
spin_unlock(&rbu_data.lock); spin_unlock(&rbu_data.lock);
...@@ -553,7 +539,7 @@ static void callbackfn_rbu(const struct firmware *fw, void *context) ...@@ -553,7 +539,7 @@ static void callbackfn_rbu(const struct firmware *fw, void *context)
} }
static ssize_t read_rbu_image_type(struct kobject *kobj, char *buffer, static ssize_t read_rbu_image_type(struct kobject *kobj, char *buffer,
loff_t pos, size_t count) loff_t pos, size_t count)
{ {
int size = 0; int size = 0;
if (!pos) if (!pos)
...@@ -562,7 +548,7 @@ static ssize_t read_rbu_image_type(struct kobject *kobj, char *buffer, ...@@ -562,7 +548,7 @@ static ssize_t read_rbu_image_type(struct kobject *kobj, char *buffer,
} }
static ssize_t write_rbu_image_type(struct kobject *kobj, char *buffer, static ssize_t write_rbu_image_type(struct kobject *kobj, char *buffer,
loff_t pos, size_t count) loff_t pos, size_t count)
{ {
int rc = count; int rc = count;
int req_firm_rc = 0; int req_firm_rc = 0;
...@@ -621,25 +607,49 @@ static ssize_t write_rbu_image_type(struct kobject *kobj, char *buffer, ...@@ -621,25 +607,49 @@ static ssize_t write_rbu_image_type(struct kobject *kobj, char *buffer,
return rc; return rc;
} }
static ssize_t read_rbu_packet_size(struct kobject *kobj, char *buffer,
loff_t pos, size_t count)
{
int size = 0;
if (!pos) {
spin_lock(&rbu_data.lock);
size = sprintf(buffer, "%lu\n", rbu_data.packetsize);
spin_unlock(&rbu_data.lock);
}
return size;
}
static ssize_t write_rbu_packet_size(struct kobject *kobj, char *buffer,
loff_t pos, size_t count)
{
unsigned long temp;
spin_lock(&rbu_data.lock);
packet_empty_list();
sscanf(buffer, "%lu", &temp);
if (temp < 0xffffffff)
rbu_data.packetsize = temp;
spin_unlock(&rbu_data.lock);
return count;
}
static struct bin_attribute rbu_data_attr = { static struct bin_attribute rbu_data_attr = {
.attr = { .attr = {.name = "data",.owner = THIS_MODULE,.mode = 0444},
.name = "data",
.owner = THIS_MODULE,
.mode = 0444,
},
.read = read_rbu_data, .read = read_rbu_data,
}; };
static struct bin_attribute rbu_image_type_attr = { static struct bin_attribute rbu_image_type_attr = {
.attr = { .attr = {.name = "image_type",.owner = THIS_MODULE,.mode = 0644},
.name = "image_type",
.owner = THIS_MODULE,
.mode = 0644,
},
.read = read_rbu_image_type, .read = read_rbu_image_type,
.write = write_rbu_image_type, .write = write_rbu_image_type,
}; };
static struct bin_attribute rbu_packet_size_attr = {
.attr = {.name = "packet_size",.owner = THIS_MODULE,.mode = 0644},
.read = read_rbu_packet_size,
.write = write_rbu_packet_size,
};
static int __init dcdrbu_init(void) static int __init dcdrbu_init(void)
{ {
int rc = 0; int rc = 0;
...@@ -657,6 +667,8 @@ static int __init dcdrbu_init(void) ...@@ -657,6 +667,8 @@ static int __init dcdrbu_init(void)
sysfs_create_bin_file(&rbu_device->dev.kobj, &rbu_data_attr); sysfs_create_bin_file(&rbu_device->dev.kobj, &rbu_data_attr);
sysfs_create_bin_file(&rbu_device->dev.kobj, &rbu_image_type_attr); sysfs_create_bin_file(&rbu_device->dev.kobj, &rbu_image_type_attr);
sysfs_create_bin_file(&rbu_device->dev.kobj,
&rbu_packet_size_attr);
rc = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG, rc = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG,
"dell_rbu", &rbu_device->dev, &context, callbackfn_rbu); "dell_rbu", &rbu_device->dev, &context, callbackfn_rbu);
......
...@@ -93,7 +93,7 @@ config KEYBOARD_LKKBD ...@@ -93,7 +93,7 @@ config KEYBOARD_LKKBD
config KEYBOARD_LOCOMO config KEYBOARD_LOCOMO
tristate "LoCoMo Keyboard Support" tristate "LoCoMo Keyboard Support"
depends on SHARP_LOCOMO depends on SHARP_LOCOMO && INPUT_KEYBOARD
help help
Say Y here if you are running Linux on a Sharp Zaurus Collie or Poodle based PDA Say Y here if you are running Linux on a Sharp Zaurus Collie or Poodle based PDA
......
...@@ -53,7 +53,7 @@ static unsigned char spitzkbd_keycode[NR_SCANCODES] = { ...@@ -53,7 +53,7 @@ static unsigned char spitzkbd_keycode[NR_SCANCODES] = {
KEY_LEFTCTRL, KEY_1, KEY_3, KEY_5, KEY_6, KEY_7, KEY_9, KEY_0, KEY_BACKSPACE, SPITZ_KEY_EXOK, SPITZ_KEY_EXCANCEL, 0, 0, 0, 0, 0, /* 1-16 */ KEY_LEFTCTRL, KEY_1, KEY_3, KEY_5, KEY_6, KEY_7, KEY_9, KEY_0, KEY_BACKSPACE, SPITZ_KEY_EXOK, SPITZ_KEY_EXCANCEL, 0, 0, 0, 0, 0, /* 1-16 */
0, KEY_2, KEY_4, KEY_R, KEY_Y, KEY_8, KEY_I, KEY_O, KEY_P, SPITZ_KEY_EXJOGDOWN, SPITZ_KEY_EXJOGUP, 0, 0, 0, 0, 0, /* 17-32 */ 0, KEY_2, KEY_4, KEY_R, KEY_Y, KEY_8, KEY_I, KEY_O, KEY_P, SPITZ_KEY_EXJOGDOWN, SPITZ_KEY_EXJOGUP, 0, 0, 0, 0, 0, /* 17-32 */
KEY_TAB, KEY_Q, KEY_E, KEY_T, KEY_G, KEY_U, KEY_J, KEY_K, 0, 0, 0, 0, 0, 0, 0, 0, /* 33-48 */ KEY_TAB, KEY_Q, KEY_E, KEY_T, KEY_G, KEY_U, KEY_J, KEY_K, 0, 0, 0, 0, 0, 0, 0, 0, /* 33-48 */
SPITZ_KEY_CALENDER, KEY_W, KEY_S, KEY_F, KEY_V, KEY_H, KEY_M, KEY_L, 0, 0, KEY_RIGHTSHIFT, 0, 0, 0, 0, 0, /* 49-64 */ SPITZ_KEY_CALENDER, KEY_W, KEY_S, KEY_F, KEY_V, KEY_H, KEY_M, KEY_L, 0, KEY_RIGHTSHIFT, 0, 0, 0, 0, 0, 0, /* 49-64 */
SPITZ_KEY_ADDRESS, KEY_A, KEY_D, KEY_C, KEY_B, KEY_N, KEY_DOT, 0, KEY_ENTER, KEY_LEFTSHIFT, 0, 0, 0, 0, 0, 0, /* 65-80 */ SPITZ_KEY_ADDRESS, KEY_A, KEY_D, KEY_C, KEY_B, KEY_N, KEY_DOT, 0, KEY_ENTER, KEY_LEFTSHIFT, 0, 0, 0, 0, 0, 0, /* 65-80 */
SPITZ_KEY_MAIL, KEY_Z, KEY_X, KEY_MINUS, KEY_SPACE, KEY_COMMA, 0, KEY_UP, 0, 0, SPITZ_KEY_FN, 0, 0, 0, 0, 0, /* 81-96 */ SPITZ_KEY_MAIL, KEY_Z, KEY_X, KEY_MINUS, KEY_SPACE, KEY_COMMA, 0, KEY_UP, 0, 0, SPITZ_KEY_FN, 0, 0, 0, 0, 0, /* 81-96 */
KEY_SYSRQ, SPITZ_KEY_JAP1, SPITZ_KEY_JAP2, SPITZ_KEY_CANCEL, SPITZ_KEY_OK, SPITZ_KEY_MENU, KEY_LEFT, KEY_DOWN, KEY_RIGHT, 0, 0, 0, 0, 0, 0, 0 /* 97-112 */ KEY_SYSRQ, SPITZ_KEY_JAP1, SPITZ_KEY_JAP2, SPITZ_KEY_CANCEL, SPITZ_KEY_OK, SPITZ_KEY_MENU, KEY_LEFT, KEY_DOWN, KEY_RIGHT, 0, 0, 0, 0, 0, 0, 0 /* 97-112 */
......
...@@ -543,7 +543,7 @@ static int cadet_probe(void) ...@@ -543,7 +543,7 @@ static int cadet_probe(void)
for(i=0;i<8;i++) { for(i=0;i<8;i++) {
io=iovals[i]; io=iovals[i];
if(request_region(io,2, "cadet-probe")>=0) { if (request_region(io, 2, "cadet-probe")) {
cadet_setfreq(1410); cadet_setfreq(1410);
if(cadet_getfreq()==1410) { if(cadet_getfreq()==1410) {
release_region(io, 2); release_region(io, 2);
......
...@@ -2393,10 +2393,10 @@ struct tvcard bttv_tvcards[] = { ...@@ -2393,10 +2393,10 @@ struct tvcard bttv_tvcards[] = {
.tuner = 0, .tuner = 0,
.tuner_type = TUNER_LG_TDVS_H062F, .tuner_type = TUNER_LG_TDVS_H062F,
.tuner_addr = ADDR_UNSET, .tuner_addr = ADDR_UNSET,
.video_inputs = 2, .video_inputs = 3,
.audio_inputs = 1, .audio_inputs = 1,
.svhs = 2, .svhs = 2,
.muxsel = { 2, 3 }, .muxsel = { 2, 3, 1 },
.gpiomask = 0x00e00007, .gpiomask = 0x00e00007,
.audiomux = { 0x00400005, 0, 0x00000001, 0, 0x00c00007, 0 }, .audiomux = { 0x00400005, 0, 0x00000001, 0, 0x00c00007, 0 },
.no_msp34xx = 1, .no_msp34xx = 1,
......
...@@ -903,8 +903,8 @@ static void mdio_write(struct net_device *netdev, int addr, int reg, int data) ...@@ -903,8 +903,8 @@ static void mdio_write(struct net_device *netdev, int addr, int reg, int data)
static void e100_get_defaults(struct nic *nic) static void e100_get_defaults(struct nic *nic)
{ {
struct param_range rfds = { .min = 16, .max = 256, .count = 256 }; struct param_range rfds = { .min = 16, .max = 256, .count = 64 };
struct param_range cbs = { .min = 64, .max = 256, .count = 128 }; struct param_range cbs = { .min = 64, .max = 256, .count = 64 };
pci_read_config_byte(nic->pdev, PCI_REVISION_ID, &nic->rev_id); pci_read_config_byte(nic->pdev, PCI_REVISION_ID, &nic->rev_id);
/* MAC type is encoded as rev ID; exception: ICH is treated as 82559 */ /* MAC type is encoded as rev ID; exception: ICH is treated as 82559 */
...@@ -1007,213 +1007,25 @@ static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb) ...@@ -1007,213 +1007,25 @@ static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb)
c[16], c[17], c[18], c[19], c[20], c[21], c[22], c[23]); c[16], c[17], c[18], c[19], c[20], c[21], c[22], c[23]);
} }
/********************************************************/
/* Micro code for 8086:1229 Rev 8 */
/********************************************************/
/* Parameter values for the D101M B-step */
#define D101M_CPUSAVER_TIMER_DWORD 78
#define D101M_CPUSAVER_BUNDLE_DWORD 65
#define D101M_CPUSAVER_MIN_SIZE_DWORD 126
#define D101M_B_RCVBUNDLE_UCODE \
{\
0x00550215, 0xFFFF0437, 0xFFFFFFFF, 0x06A70789, 0xFFFFFFFF, 0x0558FFFF, \
0x000C0001, 0x00101312, 0x000C0008, 0x00380216, \
0x0010009C, 0x00204056, 0x002380CC, 0x00380056, \
0x0010009C, 0x00244C0B, 0x00000800, 0x00124818, \
0x00380438, 0x00000000, 0x00140000, 0x00380555, \
0x00308000, 0x00100662, 0x00100561, 0x000E0408, \
0x00134861, 0x000C0002, 0x00103093, 0x00308000, \
0x00100624, 0x00100561, 0x000E0408, 0x00100861, \
0x000C007E, 0x00222C21, 0x000C0002, 0x00103093, \
0x00380C7A, 0x00080000, 0x00103090, 0x00380C7A, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x0010009C, 0x00244C2D, 0x00010004, 0x00041000, \
0x003A0437, 0x00044010, 0x0038078A, 0x00000000, \
0x00100099, 0x00206C7A, 0x0010009C, 0x00244C48, \
0x00130824, 0x000C0001, 0x00101213, 0x00260C75, \
0x00041000, 0x00010004, 0x00130826, 0x000C0006, \
0x002206A8, 0x0013C926, 0x00101313, 0x003806A8, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00080600, 0x00101B10, 0x00050004, 0x00100826, \
0x00101210, 0x00380C34, 0x00000000, 0x00000000, \
0x0021155B, 0x00100099, 0x00206559, 0x0010009C, \
0x00244559, 0x00130836, 0x000C0000, 0x00220C62, \
0x000C0001, 0x00101B13, 0x00229C0E, 0x00210C0E, \
0x00226C0E, 0x00216C0E, 0x0022FC0E, 0x00215C0E, \
0x00214C0E, 0x00380555, 0x00010004, 0x00041000, \
0x00278C67, 0x00040800, 0x00018100, 0x003A0437, \
0x00130826, 0x000C0001, 0x00220559, 0x00101313, \
0x00380559, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00130831, 0x0010090B, 0x00124813, \
0x000CFF80, 0x002606AB, 0x00041000, 0x00010004, \
0x003806A8, 0x00000000, 0x00000000, 0x00000000, \
}
/********************************************************/
/* Micro code for 8086:1229 Rev 9 */
/********************************************************/
/* Parameter values for the D101S */
#define D101S_CPUSAVER_TIMER_DWORD 78
#define D101S_CPUSAVER_BUNDLE_DWORD 67
#define D101S_CPUSAVER_MIN_SIZE_DWORD 128
#define D101S_RCVBUNDLE_UCODE \
{\
0x00550242, 0xFFFF047E, 0xFFFFFFFF, 0x06FF0818, 0xFFFFFFFF, 0x05A6FFFF, \
0x000C0001, 0x00101312, 0x000C0008, 0x00380243, \
0x0010009C, 0x00204056, 0x002380D0, 0x00380056, \
0x0010009C, 0x00244F8B, 0x00000800, 0x00124818, \
0x0038047F, 0x00000000, 0x00140000, 0x003805A3, \
0x00308000, 0x00100610, 0x00100561, 0x000E0408, \
0x00134861, 0x000C0002, 0x00103093, 0x00308000, \
0x00100624, 0x00100561, 0x000E0408, 0x00100861, \
0x000C007E, 0x00222FA1, 0x000C0002, 0x00103093, \
0x00380F90, 0x00080000, 0x00103090, 0x00380F90, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x0010009C, 0x00244FAD, 0x00010004, 0x00041000, \
0x003A047E, 0x00044010, 0x00380819, 0x00000000, \
0x00100099, 0x00206FFD, 0x0010009A, 0x0020AFFD, \
0x0010009C, 0x00244FC8, 0x00130824, 0x000C0001, \
0x00101213, 0x00260FF7, 0x00041000, 0x00010004, \
0x00130826, 0x000C0006, 0x00220700, 0x0013C926, \
0x00101313, 0x00380700, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00080600, 0x00101B10, 0x00050004, 0x00100826, \
0x00101210, 0x00380FB6, 0x00000000, 0x00000000, \
0x002115A9, 0x00100099, 0x002065A7, 0x0010009A, \
0x0020A5A7, 0x0010009C, 0x002445A7, 0x00130836, \
0x000C0000, 0x00220FE4, 0x000C0001, 0x00101B13, \
0x00229F8E, 0x00210F8E, 0x00226F8E, 0x00216F8E, \
0x0022FF8E, 0x00215F8E, 0x00214F8E, 0x003805A3, \
0x00010004, 0x00041000, 0x00278FE9, 0x00040800, \
0x00018100, 0x003A047E, 0x00130826, 0x000C0001, \
0x002205A7, 0x00101313, 0x003805A7, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00130831, \
0x0010090B, 0x00124813, 0x000CFF80, 0x00260703, \
0x00041000, 0x00010004, 0x00380700 \
}
/********************************************************/
/* Micro code for the 8086:1229 Rev F/10 */
/********************************************************/
/* Parameter values for the D102 E-step */
#define D102_E_CPUSAVER_TIMER_DWORD 42
#define D102_E_CPUSAVER_BUNDLE_DWORD 54
#define D102_E_CPUSAVER_MIN_SIZE_DWORD 46
#define D102_E_RCVBUNDLE_UCODE \
{\
0x007D028F, 0x0E4204F9, 0x14ED0C85, 0x14FA14E9, 0x0EF70E36, 0x1FFF1FFF, \
0x00E014B9, 0x00000000, 0x00000000, 0x00000000, \
0x00E014BD, 0x00000000, 0x00000000, 0x00000000, \
0x00E014D5, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00E014C1, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00E014C8, 0x00000000, 0x00000000, 0x00000000, \
0x00200600, 0x00E014EE, 0x00000000, 0x00000000, \
0x0030FF80, 0x00940E46, 0x00038200, 0x00102000, \
0x00E00E43, 0x00000000, 0x00000000, 0x00000000, \
0x00300006, 0x00E014FB, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00906E41, 0x00800E3C, 0x00E00E39, 0x00000000, \
0x00906EFD, 0x00900EFD, 0x00E00EF8, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
}
static void e100_load_ucode(struct nic *nic, struct cb *cb, struct sk_buff *skb) static void e100_load_ucode(struct nic *nic, struct cb *cb, struct sk_buff *skb)
{ {
/* *INDENT-OFF* */ int i;
static struct { static const u32 ucode[UCODE_SIZE] = {
u32 ucode[UCODE_SIZE + 1]; /* NFS packets are misinterpreted as TCO packets and
u8 mac; * incorrectly routed to the BMC over SMBus. This
u8 timer_dword; * microcode patch checks the fragmented IP bit in the
u8 bundle_dword; * NFS/UDP header to distinguish between NFS and TCO. */
u8 min_size_dword; 0x0EF70E36, 0x1FFF1FFF, 0x1FFF1FFF, 0x1FFF1FFF, 0x1FFF1FFF,
} ucode_opts[] = { 0x1FFF1FFF, 0x00906E41, 0x00800E3C, 0x00E00E39, 0x00000000,
{ D101M_B_RCVBUNDLE_UCODE, 0x00906EFD, 0x00900EFD, 0x00E00EF8,
mac_82559_D101M, };
D101M_CPUSAVER_TIMER_DWORD,
D101M_CPUSAVER_BUNDLE_DWORD,
D101M_CPUSAVER_MIN_SIZE_DWORD },
{ D101S_RCVBUNDLE_UCODE,
mac_82559_D101S,
D101S_CPUSAVER_TIMER_DWORD,
D101S_CPUSAVER_BUNDLE_DWORD,
D101S_CPUSAVER_MIN_SIZE_DWORD },
{ D102_E_RCVBUNDLE_UCODE,
mac_82551_F,
D102_E_CPUSAVER_TIMER_DWORD,
D102_E_CPUSAVER_BUNDLE_DWORD,
D102_E_CPUSAVER_MIN_SIZE_DWORD },
{ D102_E_RCVBUNDLE_UCODE,
mac_82551_10,
D102_E_CPUSAVER_TIMER_DWORD,
D102_E_CPUSAVER_BUNDLE_DWORD,
D102_E_CPUSAVER_MIN_SIZE_DWORD },
{ {0}, 0, 0, 0, 0}
}, *opts;
/* *INDENT-ON* */
#define BUNDLESMALL 1
#define BUNDLEMAX 50
#define INTDELAY 15000
opts = ucode_opts;
/* do not load u-code for ICH devices */
if (nic->flags & ich)
return;
/* Search for ucode match against h/w rev_id */
while (opts->mac) {
if (nic->mac == opts->mac) {
int i;
u32 *ucode = opts->ucode;
/* Insert user-tunable settings */
ucode[opts->timer_dword] &= 0xFFFF0000;
ucode[opts->timer_dword] |=
(u16) INTDELAY;
ucode[opts->bundle_dword] &= 0xFFFF0000;
ucode[opts->bundle_dword] |= (u16) BUNDLEMAX;
ucode[opts->min_size_dword] &= 0xFFFF0000;
ucode[opts->min_size_dword] |=
(BUNDLESMALL) ? 0xFFFF : 0xFF80;
for(i = 0; i < UCODE_SIZE; i++)
cb->u.ucode[i] = cpu_to_le32(ucode[i]);
cb->command = cpu_to_le16(cb_ucode);
return;
}
opts++;
}
cb->command = cpu_to_le16(cb_nop); if(nic->mac == mac_82551_F || nic->mac == mac_82551_10) {
for(i = 0; i < UCODE_SIZE; i++)
cb->u.ucode[i] = cpu_to_le32(ucode[i]);
cb->command = cpu_to_le16(cb_ucode);
} else
cb->command = cpu_to_le16(cb_nop);
} }
static void e100_setup_iaaddr(struct nic *nic, struct cb *cb, static void e100_setup_iaaddr(struct nic *nic, struct cb *cb,
......
...@@ -243,7 +243,7 @@ config IPW_DEBUG ...@@ -243,7 +243,7 @@ config IPW_DEBUG
config AIRO config AIRO
tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards" tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards"
depends on NET_RADIO && ISA && (PCI || BROKEN) depends on NET_RADIO && ISA_DMA_API && (PCI || BROKEN)
---help--- ---help---
This is the standard Linux driver to support Cisco/Aironet ISA and This is the standard Linux driver to support Cisco/Aironet ISA and
PCI 802.11 wireless cards. PCI 802.11 wireless cards.
......
...@@ -66,7 +66,7 @@ void soc_pcmcia_debug(struct soc_pcmcia_socket *skt, const char *func, ...@@ -66,7 +66,7 @@ void soc_pcmcia_debug(struct soc_pcmcia_socket *skt, const char *func,
if (pc_debug > lvl) { if (pc_debug > lvl) {
printk(KERN_DEBUG "skt%u: %s: ", skt->nr, func); printk(KERN_DEBUG "skt%u: %s: ", skt->nr, func);
va_start(args, fmt); va_start(args, fmt);
printk(fmt, args); vprintk(fmt, args);
va_end(args); va_end(args);
} }
} }
...@@ -321,8 +321,6 @@ soc_common_pcmcia_get_socket(struct pcmcia_socket *sock, socket_state_t *state) ...@@ -321,8 +321,6 @@ soc_common_pcmcia_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
* less punt all of this work and let the kernel handle the details * less punt all of this work and let the kernel handle the details
* of power configuration, reset, &c. We also record the value of * of power configuration, reset, &c. We also record the value of
* `state' in order to regurgitate it to the PCMCIA core later. * `state' in order to regurgitate it to the PCMCIA core later.
*
* Returns: 0
*/ */
static int static int
soc_common_pcmcia_set_socket(struct pcmcia_socket *sock, socket_state_t *state) soc_common_pcmcia_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
...@@ -407,7 +405,7 @@ soc_common_pcmcia_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *m ...@@ -407,7 +405,7 @@ soc_common_pcmcia_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *m
* the map speed as requested, but override the address ranges * the map speed as requested, but override the address ranges
* supplied by Card Services. * supplied by Card Services.
* *
* Returns: 0 on success, -1 on error * Returns: 0 on success, -ERRNO on error
*/ */
static int static int
soc_common_pcmcia_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *map) soc_common_pcmcia_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *map)
...@@ -655,8 +653,8 @@ static void soc_pcmcia_cpufreq_unregister(void) ...@@ -655,8 +653,8 @@ static void soc_pcmcia_cpufreq_unregister(void)
} }
#else #else
#define soc_pcmcia_cpufreq_register() static int soc_pcmcia_cpufreq_register(void) { return 0; }
#define soc_pcmcia_cpufreq_unregister() static void soc_pcmcia_cpufreq_unregister(void) {}
#endif #endif
int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr) int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr)
...@@ -738,7 +736,7 @@ int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops ...@@ -738,7 +736,7 @@ int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops
goto out_err_5; goto out_err_5;
} }
if ( list_empty(&soc_pcmcia_sockets) ) if (list_empty(&soc_pcmcia_sockets))
soc_pcmcia_cpufreq_register(); soc_pcmcia_cpufreq_register();
list_add(&skt->node, &soc_pcmcia_sockets); list_add(&skt->node, &soc_pcmcia_sockets);
...@@ -839,7 +837,7 @@ int soc_common_drv_pcmcia_remove(struct device *dev) ...@@ -839,7 +837,7 @@ int soc_common_drv_pcmcia_remove(struct device *dev)
release_resource(&skt->res_io); release_resource(&skt->res_io);
release_resource(&skt->res_skt); release_resource(&skt->res_skt);
} }
if ( list_empty(&soc_pcmcia_sockets) ) if (list_empty(&soc_pcmcia_sockets))
soc_pcmcia_cpufreq_unregister(); soc_pcmcia_cpufreq_unregister();
up(&soc_pcmcia_sockets_lock); up(&soc_pcmcia_sockets_lock);
......
...@@ -544,7 +544,7 @@ get_disc_ccwdev_by_devno(unsigned int devno, struct ccw_device *sibling) ...@@ -544,7 +544,7 @@ get_disc_ccwdev_by_devno(unsigned int devno, struct ccw_device *sibling)
.sibling = sibling, .sibling = sibling,
}; };
dev = bus_find_device(&css_bus_type, NULL, &data, match_devno); dev = bus_find_device(&ccw_bus_type, NULL, &data, match_devno);
return dev ? to_ccwdev(dev) : NULL; return dev ? to_ccwdev(dev) : NULL;
} }
......
...@@ -453,9 +453,9 @@ static int aac_eh_reset(struct scsi_cmnd* cmd) ...@@ -453,9 +453,9 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
/* /*
* We can exit If all the commands are complete * We can exit If all the commands are complete
*/ */
spin_unlock_irq(host->host_lock);
if (active == 0) if (active == 0)
return SUCCESS; return SUCCESS;
spin_unlock_irq(host->host_lock);
ssleep(1); ssleep(1);
spin_lock_irq(host->host_lock); spin_lock_irq(host->host_lock);
} }
......
...@@ -1119,6 +1119,36 @@ static inline void update_can_queue(struct Scsi_Host *host, u_int in_ptr, u_int ...@@ -1119,6 +1119,36 @@ static inline void update_can_queue(struct Scsi_Host *host, u_int in_ptr, u_int
host->sg_tablesize = QLOGICPTI_MAX_SG(num_free); host->sg_tablesize = QLOGICPTI_MAX_SG(num_free);
} }
static unsigned int scsi_rbuf_get(struct scsi_cmnd *cmd, unsigned char **buf_out)
{
unsigned char *buf;
unsigned int buflen;
if (cmd->use_sg) {
struct scatterlist *sg;
sg = (struct scatterlist *) cmd->request_buffer;
buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
buflen = sg->length;
} else {
buf = cmd->request_buffer;
buflen = cmd->request_bufflen;
}
*buf_out = buf;
return buflen;
}
static void scsi_rbuf_put(struct scsi_cmnd *cmd, unsigned char *buf)
{
if (cmd->use_sg) {
struct scatterlist *sg;
sg = (struct scatterlist *) cmd->request_buffer;
kunmap_atomic(buf - sg->offset, KM_IRQ0);
}
}
/* /*
* Until we scan the entire bus with inquiries, go throught this fella... * Until we scan the entire bus with inquiries, go throught this fella...
*/ */
...@@ -1145,11 +1175,9 @@ static void ourdone(struct scsi_cmnd *Cmnd) ...@@ -1145,11 +1175,9 @@ static void ourdone(struct scsi_cmnd *Cmnd)
int ok = host_byte(Cmnd->result) == DID_OK; int ok = host_byte(Cmnd->result) == DID_OK;
if (Cmnd->cmnd[0] == 0x12 && ok) { if (Cmnd->cmnd[0] == 0x12 && ok) {
unsigned char *iqd; unsigned char *iqd;
unsigned int iqd_len;
if (Cmnd->use_sg != 0) iqd_len = scsi_rbuf_get(Cmnd, &iqd);
BUG();
iqd = ((unsigned char *)Cmnd->buffer);
/* tags handled in midlayer */ /* tags handled in midlayer */
/* enable sync mode? */ /* enable sync mode? */
...@@ -1163,6 +1191,9 @@ static void ourdone(struct scsi_cmnd *Cmnd) ...@@ -1163,6 +1191,9 @@ static void ourdone(struct scsi_cmnd *Cmnd)
if (iqd[7] & 0x20) { if (iqd[7] & 0x20) {
qpti->dev_param[tgt].device_flags |= 0x20; qpti->dev_param[tgt].device_flags |= 0x20;
} }
scsi_rbuf_put(Cmnd, iqd);
qpti->sbits |= (1 << tgt); qpti->sbits |= (1 << tgt);
} else if (!ok) { } else if (!ok) {
qpti->sbits |= (1 << tgt); qpti->sbits |= (1 << tgt);
......
...@@ -29,6 +29,8 @@ ...@@ -29,6 +29,8 @@
* NV-specific details such as register offsets, SATA phy location, * NV-specific details such as register offsets, SATA phy location,
* hotplug info, etc. * hotplug info, etc.
* *
* 0.09
* - Fixed bug introduced by 0.08's MCP51 and MCP55 support.
* *
* 0.08 * 0.08
* - Added support for MCP51 and MCP55. * - Added support for MCP51 and MCP55.
...@@ -132,9 +134,7 @@ enum nv_host_type ...@@ -132,9 +134,7 @@ enum nv_host_type
GENERIC, GENERIC,
NFORCE2, NFORCE2,
NFORCE3, NFORCE3,
CK804, CK804
MCP51,
MCP55
}; };
static struct pci_device_id nv_pci_tbl[] = { static struct pci_device_id nv_pci_tbl[] = {
...@@ -153,13 +153,13 @@ static struct pci_device_id nv_pci_tbl[] = { ...@@ -153,13 +153,13 @@ static struct pci_device_id nv_pci_tbl[] = {
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, CK804 }, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CK804 },
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, MCP51 }, PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, MCP51 }, PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, MCP55 }, PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, MCP55 }, PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
{ PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, { PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
PCI_CLASS_STORAGE_IDE<<8, 0xffff00, GENERIC }, PCI_CLASS_STORAGE_IDE<<8, 0xffff00, GENERIC },
......
...@@ -272,6 +272,8 @@ static const struct pnp_device_id pnp_dev_table[] = { ...@@ -272,6 +272,8 @@ static const struct pnp_device_id pnp_dev_table[] = {
{ "SUP1421", 0 }, { "SUP1421", 0 },
/* SupraExpress 33.6 Data/Fax PnP modem */ /* SupraExpress 33.6 Data/Fax PnP modem */
{ "SUP1590", 0 }, { "SUP1590", 0 },
/* SupraExpress 336i Sp ASVD */
{ "SUP1620", 0 },
/* SupraExpress 33.6 Data/Fax PnP modem */ /* SupraExpress 33.6 Data/Fax PnP modem */
{ "SUP1760", 0 }, { "SUP1760", 0 },
/* Phoebe Micro */ /* Phoebe Micro */
......
...@@ -73,7 +73,7 @@ struct imx_port { ...@@ -73,7 +73,7 @@ struct imx_port {
struct uart_port port; struct uart_port port;
struct timer_list timer; struct timer_list timer;
unsigned int old_status; unsigned int old_status;
int txirq,rxirq; int txirq,rxirq,rtsirq;
}; };
/* /*
...@@ -181,6 +181,22 @@ static void imx_start_tx(struct uart_port *port) ...@@ -181,6 +181,22 @@ static void imx_start_tx(struct uart_port *port)
imx_transmit_buffer(sport); imx_transmit_buffer(sport);
} }
static irqreturn_t imx_rtsint(int irq, void *dev_id, struct pt_regs *regs)
{
struct imx_port *sport = (struct imx_port *)dev_id;
unsigned int val = USR1((u32)sport->port.membase)&USR1_RTSS;
unsigned long flags;
spin_lock_irqsave(&sport->port.lock, flags);
USR1((u32)sport->port.membase) = USR1_RTSD;
uart_handle_cts_change(&sport->port, !!val);
wake_up_interruptible(&sport->port.info->delta_msr_wait);
spin_unlock_irqrestore(&sport->port.lock, flags);
return IRQ_HANDLED;
}
static irqreturn_t imx_txint(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t imx_txint(int irq, void *dev_id, struct pt_regs *regs)
{ {
struct imx_port *sport = (struct imx_port *)dev_id; struct imx_port *sport = (struct imx_port *)dev_id;
...@@ -386,15 +402,21 @@ static int imx_startup(struct uart_port *port) ...@@ -386,15 +402,21 @@ static int imx_startup(struct uart_port *port)
if (retval) goto error_out1; if (retval) goto error_out1;
retval = request_irq(sport->txirq, imx_txint, 0, retval = request_irq(sport->txirq, imx_txint, 0,
"imx-uart", sport); DRIVER_NAME, sport);
if (retval) goto error_out2; if (retval) goto error_out2;
retval = request_irq(sport->rtsirq, imx_rtsint, 0,
DRIVER_NAME, sport);
if (retval) goto error_out3;
set_irq_type(sport->rtsirq, IRQT_BOTHEDGE);
/* /*
* Finally, clear and enable interrupts * Finally, clear and enable interrupts
*/ */
USR1((u32)sport->port.membase) = USR1_RTSD;
UCR1((u32)sport->port.membase) |= UCR1((u32)sport->port.membase) |=
(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_UARTEN); (UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN);
UCR2((u32)sport->port.membase) |= (UCR2_RXEN | UCR2_TXEN); UCR2((u32)sport->port.membase) |= (UCR2_RXEN | UCR2_TXEN);
/* /*
...@@ -406,6 +428,8 @@ static int imx_startup(struct uart_port *port) ...@@ -406,6 +428,8 @@ static int imx_startup(struct uart_port *port)
return 0; return 0;
error_out3:
free_irq(sport->txirq, sport);
error_out2: error_out2:
free_irq(sport->rxirq, sport); free_irq(sport->rxirq, sport);
error_out1: error_out1:
...@@ -424,6 +448,7 @@ static void imx_shutdown(struct uart_port *port) ...@@ -424,6 +448,7 @@ static void imx_shutdown(struct uart_port *port)
/* /*
* Free the interrupts * Free the interrupts
*/ */
free_irq(sport->rtsirq, sport);
free_irq(sport->txirq, sport); free_irq(sport->txirq, sport);
free_irq(sport->rxirq, sport); free_irq(sport->rxirq, sport);
...@@ -432,7 +457,7 @@ static void imx_shutdown(struct uart_port *port) ...@@ -432,7 +457,7 @@ static void imx_shutdown(struct uart_port *port)
*/ */
UCR1((u32)sport->port.membase) &= UCR1((u32)sport->port.membase) &=
~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_UARTEN); ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN);
} }
static void static void
...@@ -522,7 +547,7 @@ imx_set_termios(struct uart_port *port, struct termios *termios, ...@@ -522,7 +547,7 @@ imx_set_termios(struct uart_port *port, struct termios *termios,
* disable interrupts and drain transmitter * disable interrupts and drain transmitter
*/ */
old_ucr1 = UCR1((u32)sport->port.membase); old_ucr1 = UCR1((u32)sport->port.membase);
UCR1((u32)sport->port.membase) &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN); UCR1((u32)sport->port.membase) &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN);
while ( !(USR2((u32)sport->port.membase) & USR2_TXDC)) while ( !(USR2((u32)sport->port.membase) & USR2_TXDC))
barrier(); barrier();
...@@ -643,6 +668,7 @@ static struct imx_port imx_ports[] = { ...@@ -643,6 +668,7 @@ static struct imx_port imx_ports[] = {
{ {
.txirq = UART1_MINT_TX, .txirq = UART1_MINT_TX,
.rxirq = UART1_MINT_RX, .rxirq = UART1_MINT_RX,
.rtsirq = UART1_MINT_RTS,
.port = { .port = {
.type = PORT_IMX, .type = PORT_IMX,
.iotype = SERIAL_IO_MEM, .iotype = SERIAL_IO_MEM,
...@@ -658,6 +684,7 @@ static struct imx_port imx_ports[] = { ...@@ -658,6 +684,7 @@ static struct imx_port imx_ports[] = {
}, { }, {
.txirq = UART2_MINT_TX, .txirq = UART2_MINT_TX,
.rxirq = UART2_MINT_RX, .rxirq = UART2_MINT_RX,
.rtsirq = UART2_MINT_RTS,
.port = { .port = {
.type = PORT_IMX, .type = PORT_IMX,
.iotype = SERIAL_IO_MEM, .iotype = SERIAL_IO_MEM,
...@@ -737,7 +764,7 @@ imx_console_write(struct console *co, const char *s, unsigned int count) ...@@ -737,7 +764,7 @@ imx_console_write(struct console *co, const char *s, unsigned int count)
UCR1((u32)sport->port.membase) = UCR1((u32)sport->port.membase) =
(old_ucr1 | UCR1_UARTCLKEN | UCR1_UARTEN) (old_ucr1 | UCR1_UARTCLKEN | UCR1_UARTEN)
& ~(UCR1_TXMPTYEN | UCR1_RRDYEN); & ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN);
UCR2((u32)sport->port.membase) = old_ucr2 | UCR2_TXEN; UCR2((u32)sport->port.membase) = old_ucr2 | UCR2_TXEN;
/* /*
......
...@@ -499,7 +499,7 @@ serial_pxa_set_termios(struct uart_port *port, struct termios *termios, ...@@ -499,7 +499,7 @@ serial_pxa_set_termios(struct uart_port *port, struct termios *termios,
/* /*
* Update the per-port timeout. * Update the per-port timeout.
*/ */
uart_update_timeout(port, termios->c_cflag, quot); uart_update_timeout(port, termios->c_cflag, baud);
up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
if (termios->c_iflag & INPCK) if (termios->c_iflag & INPCK)
......
...@@ -1092,8 +1092,8 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, ...@@ -1092,8 +1092,8 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
static int probe_index = 0; static int probe_index = 0;
int s3c24xx_serial_probe(struct device *_dev, static int s3c24xx_serial_probe(struct device *_dev,
struct s3c24xx_uart_info *info) struct s3c24xx_uart_info *info)
{ {
struct s3c24xx_uart_port *ourport; struct s3c24xx_uart_port *ourport;
struct platform_device *dev = to_platform_device(_dev); struct platform_device *dev = to_platform_device(_dev);
...@@ -1120,7 +1120,7 @@ int s3c24xx_serial_probe(struct device *_dev, ...@@ -1120,7 +1120,7 @@ int s3c24xx_serial_probe(struct device *_dev,
return ret; return ret;
} }
int s3c24xx_serial_remove(struct device *_dev) static int s3c24xx_serial_remove(struct device *_dev)
{ {
struct uart_port *port = s3c24xx_dev_to_port(_dev); struct uart_port *port = s3c24xx_dev_to_port(_dev);
...@@ -1134,7 +1134,8 @@ int s3c24xx_serial_remove(struct device *_dev) ...@@ -1134,7 +1134,8 @@ int s3c24xx_serial_remove(struct device *_dev)
#ifdef CONFIG_PM #ifdef CONFIG_PM
int s3c24xx_serial_suspend(struct device *dev, pm_message_t state, u32 level) static int s3c24xx_serial_suspend(struct device *dev, pm_message_t state,
u32 level)
{ {
struct uart_port *port = s3c24xx_dev_to_port(dev); struct uart_port *port = s3c24xx_dev_to_port(dev);
...@@ -1144,7 +1145,7 @@ int s3c24xx_serial_suspend(struct device *dev, pm_message_t state, u32 level) ...@@ -1144,7 +1145,7 @@ int s3c24xx_serial_suspend(struct device *dev, pm_message_t state, u32 level)
return 0; return 0;
} }
int s3c24xx_serial_resume(struct device *dev, u32 level) static int s3c24xx_serial_resume(struct device *dev, u32 level)
{ {
struct uart_port *port = s3c24xx_dev_to_port(dev); struct uart_port *port = s3c24xx_dev_to_port(dev);
struct s3c24xx_uart_port *ourport = to_ourport(port); struct s3c24xx_uart_port *ourport = to_ourport(port);
...@@ -1165,8 +1166,8 @@ int s3c24xx_serial_resume(struct device *dev, u32 level) ...@@ -1165,8 +1166,8 @@ int s3c24xx_serial_resume(struct device *dev, u32 level)
#define s3c24xx_serial_resume NULL #define s3c24xx_serial_resume NULL
#endif #endif
int s3c24xx_serial_init(struct device_driver *drv, static int s3c24xx_serial_init(struct device_driver *drv,
struct s3c24xx_uart_info *info) struct s3c24xx_uart_info *info)
{ {
dbg("s3c24xx_serial_init(%p,%p)\n", drv, info); dbg("s3c24xx_serial_init(%p,%p)\n", drv, info);
return driver_register(drv); return driver_register(drv);
......
...@@ -967,7 +967,7 @@ static int sci_startup(struct uart_port *port) ...@@ -967,7 +967,7 @@ static int sci_startup(struct uart_port *port)
#endif #endif
sci_request_irq(s); sci_request_irq(s);
sci_start_tx(port, 1); sci_start_tx(port);
sci_start_rx(port, 1); sci_start_rx(port, 1);
return 0; return 0;
......
...@@ -274,7 +274,6 @@ static void transmit_chars(struct uart_sunsab_port *up, ...@@ -274,7 +274,6 @@ static void transmit_chars(struct uart_sunsab_port *up,
if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) {
up->interrupt_mask1 |= SAB82532_IMR1_XPR; up->interrupt_mask1 |= SAB82532_IMR1_XPR;
writeb(up->interrupt_mask1, &up->regs->w.imr1); writeb(up->interrupt_mask1, &up->regs->w.imr1);
uart_write_wakeup(&up->port);
return; return;
} }
......
...@@ -517,10 +517,9 @@ static void sunzilog_transmit_chars(struct uart_sunzilog_port *up, ...@@ -517,10 +517,9 @@ static void sunzilog_transmit_chars(struct uart_sunzilog_port *up,
if (up->port.info == NULL) if (up->port.info == NULL)
goto ack_tx_int; goto ack_tx_int;
xmit = &up->port.info->xmit; xmit = &up->port.info->xmit;
if (uart_circ_empty(xmit)) { if (uart_circ_empty(xmit))
uart_write_wakeup(&up->port);
goto ack_tx_int; goto ack_tx_int;
}
if (uart_tx_stopped(&up->port)) if (uart_tx_stopped(&up->port))
goto ack_tx_int; goto ack_tx_int;
......
...@@ -223,7 +223,7 @@ int usb_serial_generic_write_room (struct usb_serial_port *port) ...@@ -223,7 +223,7 @@ int usb_serial_generic_write_room (struct usb_serial_port *port)
dbg("%s - port %d", __FUNCTION__, port->number); dbg("%s - port %d", __FUNCTION__, port->number);
if (serial->num_bulk_out) { if (serial->num_bulk_out) {
if (port->write_urb_busy) if (!(port->write_urb_busy))
room = port->bulk_out_size; room = port->bulk_out_size;
} }
......
...@@ -592,6 +592,7 @@ sa1100fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, ...@@ -592,6 +592,7 @@ sa1100fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
return ret; return ret;
} }
#ifdef CONFIG_CPU_FREQ
/* /*
* sa1100fb_display_dma_period() * sa1100fb_display_dma_period()
* Calculate the minimum period (in picoseconds) between two DMA * Calculate the minimum period (in picoseconds) between two DMA
...@@ -606,6 +607,7 @@ static inline unsigned int sa1100fb_display_dma_period(struct fb_var_screeninfo ...@@ -606,6 +607,7 @@ static inline unsigned int sa1100fb_display_dma_period(struct fb_var_screeninfo
*/ */
return var->pixclock * 8 * 16 / var->bits_per_pixel; return var->pixclock * 8 * 16 / var->bits_per_pixel;
} }
#endif
/* /*
* sa1100fb_check_var(): * sa1100fb_check_var():
......
...@@ -77,8 +77,7 @@ static void w1_master_release(struct device *dev) ...@@ -77,8 +77,7 @@ static void w1_master_release(struct device *dev)
dev_dbg(dev, "%s: Releasing %s.\n", __func__, md->name); dev_dbg(dev, "%s: Releasing %s.\n", __func__, md->name);
if (md->nls && md->nls->sk_socket) dev_fini_netlink(md);
sock_release(md->nls->sk_socket);
memset(md, 0, sizeof(struct w1_master) + sizeof(struct w1_bus_master)); memset(md, 0, sizeof(struct w1_master) + sizeof(struct w1_bus_master));
kfree(md); kfree(md);
} }
......
...@@ -175,16 +175,16 @@ static int v9fs_file_lock(struct file *filp, int cmd, struct file_lock *fl) ...@@ -175,16 +175,16 @@ static int v9fs_file_lock(struct file *filp, int cmd, struct file_lock *fl)
} }
/** /**
* v9fs_read - read from a file (internal) * v9fs_file_read - read from a file
* @filep: file pointer to read * @filep: file pointer to read
* @data: data buffer to read data into * @data: data buffer to read data into
* @count: size of buffer * @count: size of buffer
* @offset: offset at which to read data * @offset: offset at which to read data
* *
*/ */
static ssize_t static ssize_t
v9fs_read(struct file *filp, char *buffer, size_t count, loff_t * offset) v9fs_file_read(struct file *filp, char __user * data, size_t count,
loff_t * offset)
{ {
struct inode *inode = filp->f_dentry->d_inode; struct inode *inode = filp->f_dentry->d_inode;
struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
...@@ -194,6 +194,7 @@ v9fs_read(struct file *filp, char *buffer, size_t count, loff_t * offset) ...@@ -194,6 +194,7 @@ v9fs_read(struct file *filp, char *buffer, size_t count, loff_t * offset)
int rsize = 0; int rsize = 0;
int result = 0; int result = 0;
int total = 0; int total = 0;
int n;
dprintk(DEBUG_VFS, "\n"); dprintk(DEBUG_VFS, "\n");
...@@ -216,10 +217,15 @@ v9fs_read(struct file *filp, char *buffer, size_t count, loff_t * offset) ...@@ -216,10 +217,15 @@ v9fs_read(struct file *filp, char *buffer, size_t count, loff_t * offset)
} else } else
*offset += result; *offset += result;
/* XXX - extra copy */ n = copy_to_user(data, fcall->params.rread.data, result);
memcpy(buffer, fcall->params.rread.data, result); if (n) {
dprintk(DEBUG_ERROR, "Problem copying to user %d\n", n);
kfree(fcall);
return -EFAULT;
}
count -= result; count -= result;
buffer += result; data += result;
total += result; total += result;
kfree(fcall); kfree(fcall);
...@@ -232,42 +238,7 @@ v9fs_read(struct file *filp, char *buffer, size_t count, loff_t * offset) ...@@ -232,42 +238,7 @@ v9fs_read(struct file *filp, char *buffer, size_t count, loff_t * offset)
} }
/** /**
* v9fs_file_read - read from a file * v9fs_file_write - write to a file
* @filep: file pointer to read
* @data: data buffer to read data into
* @count: size of buffer
* @offset: offset at which to read data
*
*/
static ssize_t
v9fs_file_read(struct file *filp, char __user * data, size_t count,
loff_t * offset)
{
int retval = -1;
int ret = 0;
char *buffer;
buffer = kmalloc(count, GFP_KERNEL);
if (!buffer)
return -ENOMEM;
retval = v9fs_read(filp, buffer, count, offset);
if (retval > 0) {
if ((ret = copy_to_user(data, buffer, retval)) != 0) {
dprintk(DEBUG_ERROR, "Problem copying to user %d\n",
ret);
retval = ret;
}
}
kfree(buffer);
return retval;
}
/**
* v9fs_write - write to a file
* @filep: file pointer to write * @filep: file pointer to write
* @data: data buffer to write data from * @data: data buffer to write data from
* @count: size of buffer * @count: size of buffer
...@@ -276,7 +247,8 @@ v9fs_file_read(struct file *filp, char __user * data, size_t count, ...@@ -276,7 +247,8 @@ v9fs_file_read(struct file *filp, char __user * data, size_t count,
*/ */
static ssize_t static ssize_t
v9fs_write(struct file *filp, char *buffer, size_t count, loff_t * offset) v9fs_file_write(struct file *filp, const char __user * data,
size_t count, loff_t * offset)
{ {
struct inode *inode = filp->f_dentry->d_inode; struct inode *inode = filp->f_dentry->d_inode;
struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
...@@ -286,30 +258,42 @@ v9fs_write(struct file *filp, char *buffer, size_t count, loff_t * offset) ...@@ -286,30 +258,42 @@ v9fs_write(struct file *filp, char *buffer, size_t count, loff_t * offset)
int result = -EIO; int result = -EIO;
int rsize = 0; int rsize = 0;
int total = 0; int total = 0;
char *buf;
dprintk(DEBUG_VFS, "data %p count %d offset %x\n", buffer, (int)count, dprintk(DEBUG_VFS, "data %p count %d offset %x\n", data, (int)count,
(int)*offset); (int)*offset);
rsize = v9ses->maxdata - V9FS_IOHDRSZ; rsize = v9ses->maxdata - V9FS_IOHDRSZ;
if (v9fid->iounit != 0 && rsize > v9fid->iounit) if (v9fid->iounit != 0 && rsize > v9fid->iounit)
rsize = v9fid->iounit; rsize = v9fid->iounit;
dump_data(buffer, count); buf = kmalloc(v9ses->maxdata - V9FS_IOHDRSZ, GFP_KERNEL);
if (!buf)
return -ENOMEM;
do { do {
if (count < rsize) if (count < rsize)
rsize = count; rsize = count;
result = result = copy_from_user(buf, data, rsize);
v9fs_t_write(v9ses, fid, *offset, rsize, buffer, &fcall); if (result) {
dprintk(DEBUG_ERROR, "Problem copying from user\n");
kfree(buf);
return -EFAULT;
}
dump_data(buf, rsize);
result = v9fs_t_write(v9ses, fid, *offset, rsize, buf, &fcall);
if (result < 0) { if (result < 0) {
eprintk(KERN_ERR, "error while writing: %s(%d)\n", eprintk(KERN_ERR, "error while writing: %s(%d)\n",
FCALL_ERROR(fcall), result); FCALL_ERROR(fcall), result);
kfree(fcall); kfree(fcall);
kfree(buf);
return result; return result;
} else } else
*offset += result; *offset += result;
kfree(fcall); kfree(fcall);
fcall = NULL;
if (result != rsize) { if (result != rsize) {
eprintk(KERN_ERR, eprintk(KERN_ERR,
...@@ -319,46 +303,14 @@ v9fs_write(struct file *filp, char *buffer, size_t count, loff_t * offset) ...@@ -319,46 +303,14 @@ v9fs_write(struct file *filp, char *buffer, size_t count, loff_t * offset)
} }
count -= result; count -= result;
buffer += result; data += result;
total += result; total += result;
} while (count); } while (count);
kfree(buf);
return total; return total;
} }
/**
* v9fs_file_write - write to a file
* @filep: file pointer to write
* @data: data buffer to write data from
* @count: size of buffer
* @offset: offset at which to write data
*
*/
static ssize_t
v9fs_file_write(struct file *filp, const char __user * data,
size_t count, loff_t * offset)
{
int ret = -1;
char *buffer;
buffer = kmalloc(count, GFP_KERNEL);
if (buffer == NULL)
return -ENOMEM;
ret = copy_from_user(buffer, data, count);
if (ret) {
dprintk(DEBUG_ERROR, "Problem copying from user\n");
ret = -EFAULT;
} else {
ret = v9fs_write(filp, buffer, count, offset);
}
kfree(buffer);
return ret;
}
struct file_operations v9fs_file_operations = { struct file_operations v9fs_file_operations = {
.llseek = generic_file_llseek, .llseek = generic_file_llseek,
.read = v9fs_file_read, .read = v9fs_file_read,
......
...@@ -905,7 +905,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -905,7 +905,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
send_sig(SIGKILL, current, 0); send_sig(SIGKILL, current, 0);
goto out_free_dentry; goto out_free_dentry;
} }
if (padzero(elf_bss)) { if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) {
send_sig(SIGSEGV, current, 0); send_sig(SIGSEGV, current, 0);
retval = -EFAULT; /* Nobody gets to see this, but.. */ retval = -EFAULT; /* Nobody gets to see this, but.. */
goto out_free_dentry; goto out_free_dentry;
......
...@@ -48,43 +48,26 @@ xdr_nfsace_encode(struct xdr_array2_desc *desc, void *elem) ...@@ -48,43 +48,26 @@ xdr_nfsace_encode(struct xdr_array2_desc *desc, void *elem)
(struct nfsacl_encode_desc *) desc; (struct nfsacl_encode_desc *) desc;
u32 *p = (u32 *) elem; u32 *p = (u32 *) elem;
if (nfsacl_desc->count < nfsacl_desc->acl->a_count) { struct posix_acl_entry *entry =
struct posix_acl_entry *entry = &nfsacl_desc->acl->a_entries[nfsacl_desc->count++];
&nfsacl_desc->acl->a_entries[nfsacl_desc->count++];
*p++ = htonl(entry->e_tag | nfsacl_desc->typeflag); *p++ = htonl(entry->e_tag | nfsacl_desc->typeflag);
switch(entry->e_tag) { switch(entry->e_tag) {
case ACL_USER_OBJ: case ACL_USER_OBJ:
*p++ = htonl(nfsacl_desc->uid); *p++ = htonl(nfsacl_desc->uid);
break; break;
case ACL_GROUP_OBJ: case ACL_GROUP_OBJ:
*p++ = htonl(nfsacl_desc->gid); *p++ = htonl(nfsacl_desc->gid);
break; break;
case ACL_USER: case ACL_USER:
case ACL_GROUP: case ACL_GROUP:
*p++ = htonl(entry->e_id); *p++ = htonl(entry->e_id);
break; break;
default: /* Solaris depends on that! */ default: /* Solaris depends on that! */
*p++ = 0; *p++ = 0;
break; break;
}
*p++ = htonl(entry->e_perm & S_IRWXO);
} else {
const struct posix_acl_entry *pa, *pe;
int group_obj_perm = ACL_READ|ACL_WRITE|ACL_EXECUTE;
FOREACH_ACL_ENTRY(pa, nfsacl_desc->acl, pe) {
if (pa->e_tag == ACL_GROUP_OBJ) {
group_obj_perm = pa->e_perm & S_IRWXO;
break;
}
}
/* fake up ACL_MASK entry */
*p++ = htonl(ACL_MASK | nfsacl_desc->typeflag);
*p++ = htonl(0);
*p++ = htonl(group_obj_perm);
} }
*p++ = htonl(entry->e_perm & S_IRWXO);
return 0; return 0;
} }
...@@ -105,11 +88,28 @@ nfsacl_encode(struct xdr_buf *buf, unsigned int base, struct inode *inode, ...@@ -105,11 +88,28 @@ nfsacl_encode(struct xdr_buf *buf, unsigned int base, struct inode *inode,
.gid = inode->i_gid, .gid = inode->i_gid,
}; };
int err; int err;
struct posix_acl *acl2 = NULL;
if (entries > NFS_ACL_MAX_ENTRIES || if (entries > NFS_ACL_MAX_ENTRIES ||
xdr_encode_word(buf, base, entries)) xdr_encode_word(buf, base, entries))
return -EINVAL; return -EINVAL;
if (encode_entries && acl && acl->a_count == 3) {
/* Fake up an ACL_MASK entry. */
acl2 = posix_acl_alloc(4, GFP_KERNEL);
if (!acl2)
return -ENOMEM;
/* Insert entries in canonical order: other orders seem
to confuse Solaris VxFS. */
acl2->a_entries[0] = acl->a_entries[0]; /* ACL_USER_OBJ */
acl2->a_entries[1] = acl->a_entries[1]; /* ACL_GROUP_OBJ */
acl2->a_entries[2] = acl->a_entries[1]; /* ACL_MASK */
acl2->a_entries[2].e_tag = ACL_MASK;
acl2->a_entries[3] = acl->a_entries[2]; /* ACL_OTHER */
nfsacl_desc.acl = acl2;
}
err = xdr_encode_array2(buf, base + 4, &nfsacl_desc.desc); err = xdr_encode_array2(buf, base + 4, &nfsacl_desc.desc);
if (acl2)
posix_acl_release(acl2);
if (!err) if (!err)
err = 8 + nfsacl_desc.desc.elem_size * err = 8 + nfsacl_desc.desc.elem_size *
nfsacl_desc.desc.array_len; nfsacl_desc.desc.array_len;
......
...@@ -103,7 +103,9 @@ enum pid_directory_inos { ...@@ -103,7 +103,9 @@ enum pid_directory_inos {
PROC_TGID_NUMA_MAPS, PROC_TGID_NUMA_MAPS,
PROC_TGID_MOUNTS, PROC_TGID_MOUNTS,
PROC_TGID_WCHAN, PROC_TGID_WCHAN,
#ifdef CONFIG_MMU
PROC_TGID_SMAPS, PROC_TGID_SMAPS,
#endif
#ifdef CONFIG_SCHEDSTATS #ifdef CONFIG_SCHEDSTATS
PROC_TGID_SCHEDSTAT, PROC_TGID_SCHEDSTAT,
#endif #endif
...@@ -141,7 +143,9 @@ enum pid_directory_inos { ...@@ -141,7 +143,9 @@ enum pid_directory_inos {
PROC_TID_NUMA_MAPS, PROC_TID_NUMA_MAPS,
PROC_TID_MOUNTS, PROC_TID_MOUNTS,
PROC_TID_WCHAN, PROC_TID_WCHAN,
#ifdef CONFIG_MMU
PROC_TID_SMAPS, PROC_TID_SMAPS,
#endif
#ifdef CONFIG_SCHEDSTATS #ifdef CONFIG_SCHEDSTATS
PROC_TID_SCHEDSTAT, PROC_TID_SCHEDSTAT,
#endif #endif
...@@ -195,7 +199,9 @@ static struct pid_entry tgid_base_stuff[] = { ...@@ -195,7 +199,9 @@ static struct pid_entry tgid_base_stuff[] = {
E(PROC_TGID_ROOT, "root", S_IFLNK|S_IRWXUGO), E(PROC_TGID_ROOT, "root", S_IFLNK|S_IRWXUGO),
E(PROC_TGID_EXE, "exe", S_IFLNK|S_IRWXUGO), E(PROC_TGID_EXE, "exe", S_IFLNK|S_IRWXUGO),
E(PROC_TGID_MOUNTS, "mounts", S_IFREG|S_IRUGO), E(PROC_TGID_MOUNTS, "mounts", S_IFREG|S_IRUGO),
#ifdef CONFIG_MMU
E(PROC_TGID_SMAPS, "smaps", S_IFREG|S_IRUGO), E(PROC_TGID_SMAPS, "smaps", S_IFREG|S_IRUGO),
#endif
#ifdef CONFIG_SECURITY #ifdef CONFIG_SECURITY
E(PROC_TGID_ATTR, "attr", S_IFDIR|S_IRUGO|S_IXUGO), E(PROC_TGID_ATTR, "attr", S_IFDIR|S_IRUGO|S_IXUGO),
#endif #endif
...@@ -235,7 +241,9 @@ static struct pid_entry tid_base_stuff[] = { ...@@ -235,7 +241,9 @@ static struct pid_entry tid_base_stuff[] = {
E(PROC_TID_ROOT, "root", S_IFLNK|S_IRWXUGO), E(PROC_TID_ROOT, "root", S_IFLNK|S_IRWXUGO),
E(PROC_TID_EXE, "exe", S_IFLNK|S_IRWXUGO), E(PROC_TID_EXE, "exe", S_IFLNK|S_IRWXUGO),
E(PROC_TID_MOUNTS, "mounts", S_IFREG|S_IRUGO), E(PROC_TID_MOUNTS, "mounts", S_IFREG|S_IRUGO),
#ifdef CONFIG_MMU
E(PROC_TID_SMAPS, "smaps", S_IFREG|S_IRUGO), E(PROC_TID_SMAPS, "smaps", S_IFREG|S_IRUGO),
#endif
#ifdef CONFIG_SECURITY #ifdef CONFIG_SECURITY
E(PROC_TID_ATTR, "attr", S_IFDIR|S_IRUGO|S_IXUGO), E(PROC_TID_ATTR, "attr", S_IFDIR|S_IRUGO|S_IXUGO),
#endif #endif
...@@ -630,6 +638,7 @@ static struct file_operations proc_numa_maps_operations = { ...@@ -630,6 +638,7 @@ static struct file_operations proc_numa_maps_operations = {
}; };
#endif #endif
#ifdef CONFIG_MMU
extern struct seq_operations proc_pid_smaps_op; extern struct seq_operations proc_pid_smaps_op;
static int smaps_open(struct inode *inode, struct file *file) static int smaps_open(struct inode *inode, struct file *file)
{ {
...@@ -648,6 +657,7 @@ static struct file_operations proc_smaps_operations = { ...@@ -648,6 +657,7 @@ static struct file_operations proc_smaps_operations = {
.llseek = seq_lseek, .llseek = seq_lseek,
.release = seq_release, .release = seq_release,
}; };
#endif
extern struct seq_operations mounts_op; extern struct seq_operations mounts_op;
static int mounts_open(struct inode *inode, struct file *file) static int mounts_open(struct inode *inode, struct file *file)
...@@ -1681,10 +1691,12 @@ static struct dentry *proc_pident_lookup(struct inode *dir, ...@@ -1681,10 +1691,12 @@ static struct dentry *proc_pident_lookup(struct inode *dir,
case PROC_TGID_MOUNTS: case PROC_TGID_MOUNTS:
inode->i_fop = &proc_mounts_operations; inode->i_fop = &proc_mounts_operations;
break; break;
#ifdef CONFIG_MMU
case PROC_TID_SMAPS: case PROC_TID_SMAPS:
case PROC_TGID_SMAPS: case PROC_TGID_SMAPS:
inode->i_fop = &proc_smaps_operations; inode->i_fop = &proc_smaps_operations;
break; break;
#endif
#ifdef CONFIG_SECURITY #ifdef CONFIG_SECURITY
case PROC_TID_ATTR: case PROC_TID_ATTR:
inode->i_nlink = 2; inode->i_nlink = 2;
......
...@@ -126,8 +126,8 @@ ...@@ -126,8 +126,8 @@
#define DRCMR12 __REG(0x40000130) /* Request to Channel Map Register for AC97 audio transmit Request */ #define DRCMR12 __REG(0x40000130) /* Request to Channel Map Register for AC97 audio transmit Request */
#define DRCMR13 __REG(0x40000134) /* Request to Channel Map Register for SSP receive Request */ #define DRCMR13 __REG(0x40000134) /* Request to Channel Map Register for SSP receive Request */
#define DRCMR14 __REG(0x40000138) /* Request to Channel Map Register for SSP transmit Request */ #define DRCMR14 __REG(0x40000138) /* Request to Channel Map Register for SSP transmit Request */
#define DRCMR15 __REG(0x4000013c) /* Reserved */ #define DRCMR15 __REG(0x4000013c) /* Request to Channel Map Register for SSP2 receive Request */
#define DRCMR16 __REG(0x40000140) /* Reserved */ #define DRCMR16 __REG(0x40000140) /* Request to Channel Map Register for SSP2 transmit Request */
#define DRCMR17 __REG(0x40000144) /* Request to Channel Map Register for ICP receive Request */ #define DRCMR17 __REG(0x40000144) /* Request to Channel Map Register for ICP receive Request */
#define DRCMR18 __REG(0x40000148) /* Request to Channel Map Register for ICP transmit Request */ #define DRCMR18 __REG(0x40000148) /* Request to Channel Map Register for ICP transmit Request */
#define DRCMR19 __REG(0x4000014c) /* Request to Channel Map Register for STUART receive Request */ #define DRCMR19 __REG(0x4000014c) /* Request to Channel Map Register for STUART receive Request */
...@@ -151,7 +151,8 @@ ...@@ -151,7 +151,8 @@
#define DRCMR37 __REG(0x40000194) /* Request to Channel Map Register for USB endpoint 13 Request */ #define DRCMR37 __REG(0x40000194) /* Request to Channel Map Register for USB endpoint 13 Request */
#define DRCMR38 __REG(0x40000198) /* Request to Channel Map Register for USB endpoint 14 Request */ #define DRCMR38 __REG(0x40000198) /* Request to Channel Map Register for USB endpoint 14 Request */
#define DRCMR39 __REG(0x4000019C) /* Reserved */ #define DRCMR39 __REG(0x4000019C) /* Reserved */
#define DRCMR66 __REG(0x40001108) /* Request to Channel Map Register for SSP3 receive Request */
#define DRCMR67 __REG(0x4000110C) /* Request to Channel Map Register for SSP3 transmit Request */
#define DRCMR68 __REG(0x40001110) /* Request to Channel Map Register for Camera FIFO 0 Request */ #define DRCMR68 __REG(0x40001110) /* Request to Channel Map Register for Camera FIFO 0 Request */
#define DRCMR69 __REG(0x40001114) /* Request to Channel Map Register for Camera FIFO 1 Request */ #define DRCMR69 __REG(0x40001114) /* Request to Channel Map Register for Camera FIFO 1 Request */
#define DRCMR70 __REG(0x40001118) /* Request to Channel Map Register for Camera FIFO 2 Request */ #define DRCMR70 __REG(0x40001118) /* Request to Channel Map Register for Camera FIFO 2 Request */
......
...@@ -66,4 +66,5 @@ struct pxafb_mach_info { ...@@ -66,4 +66,5 @@ struct pxafb_mach_info {
}; };
void set_pxa_fb_info(struct pxafb_mach_info *hard_pxa_fb_info); void set_pxa_fb_info(struct pxafb_mach_info *hard_pxa_fb_info);
void set_pxa_fb_parent(struct device *parent_dev);
unsigned long pxafb_get_hsync_time(struct device *dev); unsigned long pxafb_get_hsync_time(struct device *dev);
...@@ -92,6 +92,13 @@ extern unsigned int s3c2410_gpio_getpin(unsigned int pin); ...@@ -92,6 +92,13 @@ extern unsigned int s3c2410_gpio_getpin(unsigned int pin);
extern unsigned int s3c2410_modify_misccr(unsigned int clr, unsigned int chg); extern unsigned int s3c2410_modify_misccr(unsigned int clr, unsigned int chg);
#ifdef CONFIG_CPU_S3C2440
extern int s3c2440_set_dsc(unsigned int pin, unsigned int value);
#endif /* CONFIG_CPU_S3C2440 */
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */
#include <asm/sizes.h> #include <asm/sizes.h>
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* 06-Dec-1997 RMK Created. * 06-Dec-1997 RMK Created.
* 02-Sep-2003 BJD Modified for S3C2410 * 02-Sep-2003 BJD Modified for S3C2410
* 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA * 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
* * 13-Oct-2005 BJD Fixed problems with LDRH/STRH offset range
*/ */
#ifndef __ASM_ARM_ARCH_IO_H #ifndef __ASM_ARM_ARCH_IO_H
...@@ -97,7 +97,7 @@ DECLARE_IO(int,l,"") ...@@ -97,7 +97,7 @@ DECLARE_IO(int,l,"")
else \ else \
__asm__ __volatile__( \ __asm__ __volatile__( \
"strb %0, [%1, #0] @ outbc" \ "strb %0, [%1, #0] @ outbc" \
: : "r" (value), "r" ((port))); \ : : "r" (value), "r" ((port))); \
}) })
#define __inbc(port) \ #define __inbc(port) \
...@@ -110,35 +110,61 @@ DECLARE_IO(int,l,"") ...@@ -110,35 +110,61 @@ DECLARE_IO(int,l,"")
else \ else \
__asm__ __volatile__( \ __asm__ __volatile__( \
"ldrb %0, [%1, #0] @ inbc" \ "ldrb %0, [%1, #0] @ inbc" \
: "=r" (result) : "r" ((port))); \ : "=r" (result) : "r" ((port))); \
result; \ result; \
}) })
#define __outwc(value,port) \ #define __outwc(value,port) \
({ \ ({ \
unsigned long v = value; \ unsigned long v = value; \
if (__PORT_PCIO((port))) \ if (__PORT_PCIO((port))) { \
__asm__ __volatile__( \ if ((port) < 256 && (port) > -256) \
"strh %0, [%1, %2] @ outwc" \ __asm__ __volatile__( \
: : "r" (v), "r" (PCIO_BASE), "Jr" ((port))); \ "strh %0, [%1, %2] @ outwc" \
else \ : : "r" (v), "r" (PCIO_BASE), "Jr" ((port))); \
else if ((port) > 0) \
__asm__ __volatile__( \
"strh %0, [%1, %2] @ outwc" \
: : "r" (v), \
"r" (PCIO_BASE + ((port) & ~0xff)), \
"Jr" (((port) & 0xff))); \
else \
__asm__ __volatile__( \
"strh %0, [%1, #0] @ outwc" \
: : "r" (v), \
"r" (PCIO_BASE + (port))); \
} else \
__asm__ __volatile__( \ __asm__ __volatile__( \
"strh %0, [%1, #0] @ outwc" \ "strh %0, [%1, #0] @ outwc" \
: : "r" (v), "r" ((port))); \ : : "r" (v), "r" ((port))); \
}) })
#define __inwc(port) \ #define __inwc(port) \
({ \ ({ \
unsigned short result; \ unsigned short result; \
if (__PORT_PCIO((port))) \ if (__PORT_PCIO((port))) { \
__asm__ __volatile__( \ if ((port) < 256 && (port) > -256 ) \
"ldrh %0, [%1, %2] @ inwc" \ __asm__ __volatile__( \
: "=r" (result) : "r" (PCIO_BASE), "Jr" ((port))); \ "ldrh %0, [%1, %2] @ inwc" \
else \ : "=r" (result) \
: "r" (PCIO_BASE), \
"Jr" ((port))); \
else if ((port) > 0) \
__asm__ __volatile__( \
"ldrh %0, [%1, %2] @ inwc" \
: "=r" (result) \
: "r" (PCIO_BASE + ((port) & ~0xff)), \
"Jr" (((port) & 0xff))); \
else \
__asm__ __volatile__( \
"ldrh %0, [%1, #0] @ inwc" \
: "=r" (result) \
: "r" (PCIO_BASE + ((port)))); \
} else \
__asm__ __volatile__( \ __asm__ __volatile__( \
"ldrh %0, [%1, #0] @ inwc" \ "ldrh %0, [%1, #0] @ inwc" \
: "=r" (result) : "r" ((port))); \ : "=r" (result) : "r" ((port))); \
result; \ result; \
}) })
#define __outlc(value,port) \ #define __outlc(value,port) \
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
#include <linux/config.h> #include <linux/config.h>
#include <asm/cputable.h> #include <asm/cputable.h>
#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */ #define CLOCK_TICK_RATE 1024000 /* Underlying HZ */
typedef unsigned long cycles_t; typedef unsigned long cycles_t;
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#define PPC_FEATURE_HAS_SPE 0x00800000 #define PPC_FEATURE_HAS_SPE 0x00800000
#define PPC_FEATURE_HAS_EFP_SINGLE 0x00400000 #define PPC_FEATURE_HAS_EFP_SINGLE 0x00400000
#define PPC_FEATURE_HAS_EFP_DOUBLE 0x00200000 #define PPC_FEATURE_HAS_EFP_DOUBLE 0x00200000
#define PPC_FEATURE_NO_TB 0x00100000
#ifdef __KERNEL__ #ifdef __KERNEL__
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册