dect
/
linux-2.6
Archived
13
0
Fork 0

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6

This commit is contained in:
Larry Finger 2010-08-26 15:11:25 -05:00
commit 0a2f38193d
159 changed files with 2258 additions and 5593 deletions

View File

@ -1676,8 +1676,7 @@ F: kernel/cgroup*
F: mm/*cgroup*
CORETEMP HARDWARE MONITORING DRIVER
M: Rudolf Marek <r.marek@assembler.cz>
M: Huaxu Wan <huaxu.wan@intel.com>
M: Fenghua Yu <fenghua.yu@intel.com>
L: lm-sensors@lm-sensors.org
S: Maintained
F: Documentation/hwmon/coretemp

View File

@ -279,13 +279,13 @@ static void __init eukrea_cpuimx27_init(void)
#if defined(CONFIG_USB_ULPI)
if (otg_mode_host) {
otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
mxc_register_device(&mxc_otg_host, &otg_pdata);
}
usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
mxc_register_device(&mxc_usbh2, &usbh2_pdata);
#endif

View File

@ -419,13 +419,13 @@ static void __init pca100_init(void)
#if defined(CONFIG_USB_ULPI)
if (otg_mode_host) {
otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
mxc_register_device(&mxc_otg_host, &otg_pdata);
}
usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
mxc_register_device(&mxc_usbh2, &usbh2_pdata);
#endif

View File

@ -138,7 +138,7 @@ static void __init eukrea_cpuimx25_init(void)
#if defined(CONFIG_USB_ULPI)
if (otg_mode_host) {
otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
mxc_register_device(&mxc_otg, &otg_pdata);
}

View File

@ -192,7 +192,7 @@ static void __init mxc_board_init(void)
#if defined(CONFIG_USB_ULPI)
if (otg_mode_host) {
otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
mxc_register_device(&mxc_otg_host, &otg_pdata);
}

View File

@ -164,7 +164,7 @@ drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/
all: zImage
# With make 3.82 we cannot mix normal and wildcard targets
BOOT_TARGETS1 := zImage zImage.initrd uImaged
BOOT_TARGETS1 := zImage zImage.initrd uImage
BOOT_TARGETS2 := zImage% dtbImage% treeImage.% cuImage.% simpleImage.%
PHONY += $(BOOT_TARGETS1) $(BOOT_TARGETS2)

View File

@ -163,6 +163,14 @@
interrupts = <0x1e 4>;
};
SATA0: sata@bffd1000 {
compatible = "amcc,sata-460ex";
reg = <4 0xbffd1000 0x800 4 0xbffd0800 0x400>;
interrupt-parent = <&UIC3>;
interrupts = <0x0 0x4 /* SATA */
0x5 0x4>; /* AHBDMA */
};
POB0: opb {
compatible = "ibm,opb-460ex", "ibm,opb";
#address-cells = <1>;

View File

@ -433,7 +433,7 @@ typedef struct {
* with. However gcc is not clever enough to compute the
* modulus (2^n-1) without a second multiply.
*/
#define vsid_scrample(protovsid, size) \
#define vsid_scramble(protovsid, size) \
((((protovsid) * VSID_MULTIPLIER_##size) % VSID_MODULUS_##size))
#else /* 1 */

View File

@ -951,7 +951,14 @@
#ifdef CONFIG_PPC64
extern void ppc64_runlatch_on(void);
extern void ppc64_runlatch_off(void);
extern void __ppc64_runlatch_off(void);
#define ppc64_runlatch_off() \
do { \
if (cpu_has_feature(CPU_FTR_CTRL) && \
test_thread_flag(TIF_RUNLATCH)) \
__ppc64_runlatch_off(); \
} while (0)
extern unsigned long scom970_read(unsigned int address);
extern void scom970_write(unsigned int address, unsigned long value);

View File

@ -21,15 +21,20 @@
/*
* the semaphore definition
*/
struct rw_semaphore {
/* XXX this should be able to be an atomic_t -- paulus */
signed int count;
#define RWSEM_UNLOCKED_VALUE 0x00000000
#define RWSEM_ACTIVE_BIAS 0x00000001
#define RWSEM_ACTIVE_MASK 0x0000ffff
#define RWSEM_WAITING_BIAS (-0x00010000)
#ifdef CONFIG_PPC64
# define RWSEM_ACTIVE_MASK 0xffffffffL
#else
# define RWSEM_ACTIVE_MASK 0x0000ffffL
#endif
#define RWSEM_UNLOCKED_VALUE 0x00000000L
#define RWSEM_ACTIVE_BIAS 0x00000001L
#define RWSEM_WAITING_BIAS (-RWSEM_ACTIVE_MASK-1)
#define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS
#define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
struct rw_semaphore {
long count;
spinlock_t wait_lock;
struct list_head wait_list;
#ifdef CONFIG_DEBUG_LOCK_ALLOC
@ -43,9 +48,13 @@ struct rw_semaphore {
# define __RWSEM_DEP_MAP_INIT(lockname)
#endif
#define __RWSEM_INITIALIZER(name) \
{ RWSEM_UNLOCKED_VALUE, __SPIN_LOCK_UNLOCKED((name).wait_lock), \
LIST_HEAD_INIT((name).wait_list) __RWSEM_DEP_MAP_INIT(name) }
#define __RWSEM_INITIALIZER(name) \
{ \
RWSEM_UNLOCKED_VALUE, \
__SPIN_LOCK_UNLOCKED((name).wait_lock), \
LIST_HEAD_INIT((name).wait_list) \
__RWSEM_DEP_MAP_INIT(name) \
}
#define DECLARE_RWSEM(name) \
struct rw_semaphore name = __RWSEM_INITIALIZER(name)
@ -70,13 +79,13 @@ extern void __init_rwsem(struct rw_semaphore *sem, const char *name,
*/
static inline void __down_read(struct rw_semaphore *sem)
{
if (unlikely(atomic_inc_return((atomic_t *)(&sem->count)) <= 0))
if (unlikely(atomic_long_inc_return((atomic_long_t *)&sem->count) <= 0))
rwsem_down_read_failed(sem);
}
static inline int __down_read_trylock(struct rw_semaphore *sem)
{
int tmp;
long tmp;
while ((tmp = sem->count) >= 0) {
if (tmp == cmpxchg(&sem->count, tmp,
@ -92,10 +101,10 @@ static inline int __down_read_trylock(struct rw_semaphore *sem)
*/
static inline void __down_write_nested(struct rw_semaphore *sem, int subclass)
{
int tmp;
long tmp;
tmp = atomic_add_return(RWSEM_ACTIVE_WRITE_BIAS,
(atomic_t *)(&sem->count));
tmp = atomic_long_add_return(RWSEM_ACTIVE_WRITE_BIAS,
(atomic_long_t *)&sem->count);
if (unlikely(tmp != RWSEM_ACTIVE_WRITE_BIAS))
rwsem_down_write_failed(sem);
}
@ -107,7 +116,7 @@ static inline void __down_write(struct rw_semaphore *sem)
static inline int __down_write_trylock(struct rw_semaphore *sem)
{
int tmp;
long tmp;
tmp = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE,
RWSEM_ACTIVE_WRITE_BIAS);
@ -119,9 +128,9 @@ static inline int __down_write_trylock(struct rw_semaphore *sem)
*/
static inline void __up_read(struct rw_semaphore *sem)
{
int tmp;
long tmp;
tmp = atomic_dec_return((atomic_t *)(&sem->count));
tmp = atomic_long_dec_return((atomic_long_t *)&sem->count);
if (unlikely(tmp < -1 && (tmp & RWSEM_ACTIVE_MASK) == 0))
rwsem_wake(sem);
}
@ -131,17 +140,17 @@ static inline void __up_read(struct rw_semaphore *sem)
*/
static inline void __up_write(struct rw_semaphore *sem)
{
if (unlikely(atomic_sub_return(RWSEM_ACTIVE_WRITE_BIAS,
(atomic_t *)(&sem->count)) < 0))
if (unlikely(atomic_long_sub_return(RWSEM_ACTIVE_WRITE_BIAS,
(atomic_long_t *)&sem->count) < 0))
rwsem_wake(sem);
}
/*
* implement atomic add functionality
*/
static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
static inline void rwsem_atomic_add(long delta, struct rw_semaphore *sem)
{
atomic_add(delta, (atomic_t *)(&sem->count));
atomic_long_add(delta, (atomic_long_t *)&sem->count);
}
/*
@ -149,9 +158,10 @@ static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
*/
static inline void __downgrade_write(struct rw_semaphore *sem)
{
int tmp;
long tmp;
tmp = atomic_add_return(-RWSEM_WAITING_BIAS, (atomic_t *)(&sem->count));
tmp = atomic_long_add_return(-RWSEM_WAITING_BIAS,
(atomic_long_t *)&sem->count);
if (tmp < 0)
rwsem_downgrade_wake(sem);
}
@ -159,14 +169,14 @@ static inline void __downgrade_write(struct rw_semaphore *sem)
/*
* implement exchange and add functionality
*/
static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem)
static inline long rwsem_atomic_update(long delta, struct rw_semaphore *sem)
{
return atomic_add_return(delta, (atomic_t *)(&sem->count));
return atomic_long_add_return(delta, (atomic_long_t *)&sem->count);
}
static inline int rwsem_is_locked(struct rw_semaphore *sem)
{
return (sem->count != 0);
return sem->count != 0;
}
#endif /* __KERNEL__ */

View File

@ -326,3 +326,6 @@ SYSCALL_SPU(perf_event_open)
COMPAT_SYS_SPU(preadv)
COMPAT_SYS_SPU(pwritev)
COMPAT_SYS(rt_tgsigqueueinfo)
SYSCALL(fanotify_init)
COMPAT_SYS(fanotify_mark)
SYSCALL_SPU(prlimit64)

View File

@ -345,10 +345,13 @@
#define __NR_preadv 320
#define __NR_pwritev 321
#define __NR_rt_tgsigqueueinfo 322
#define __NR_fanotify_init 323
#define __NR_fanotify_mark 324
#define __NR_prlimit64 325
#ifdef __KERNEL__
#define __NR_syscalls 323
#define __NR_syscalls 326
#define __NR__exit __NR_exit
#define NR_syscalls __NR_syscalls

View File

@ -1826,7 +1826,6 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_features = CPU_FTRS_47X,
.cpu_user_features = COMMON_USER_BOOKE |
PPC_FEATURE_HAS_FPU,
.cpu_user_features = COMMON_USER_BOOKE,
.mmu_features = MMU_FTR_TYPE_47x |
MMU_FTR_USE_TLBIVAX_BCAST | MMU_FTR_LOCK_BCAST_INVAL,
.icache_bsize = 32,

View File

@ -402,6 +402,18 @@ void default_machine_crash_shutdown(struct pt_regs *regs)
*/
hard_irq_disable();
/*
* Make a note of crashing cpu. Will be used in machine_kexec
* such that another IPI will not be sent.
*/
crashing_cpu = smp_processor_id();
crash_save_cpu(regs, crashing_cpu);
crash_kexec_prepare_cpus(crashing_cpu);
cpu_set(crashing_cpu, cpus_in_crash);
#if defined(CONFIG_PPC_STD_MMU_64) && defined(CONFIG_SMP)
crash_kexec_wait_realmode(crashing_cpu);
#endif
for_each_irq(i) {
struct irq_desc *desc = irq_to_desc(i);
@ -438,18 +450,8 @@ void default_machine_crash_shutdown(struct pt_regs *regs)
crash_shutdown_cpu = -1;
__debugger_fault_handler = old_handler;
/*
* Make a note of crashing cpu. Will be used in machine_kexec
* such that another IPI will not be sent.
*/
crashing_cpu = smp_processor_id();
crash_save_cpu(regs, crashing_cpu);
crash_kexec_prepare_cpus(crashing_cpu);
cpu_set(crashing_cpu, cpus_in_crash);
crash_kexec_stop_spus();
#if defined(CONFIG_PPC_STD_MMU_64) && defined(CONFIG_SMP)
crash_kexec_wait_realmode(crashing_cpu);
#endif
if (ppc_md.kexec_cpu_down)
ppc_md.kexec_cpu_down(1, 0);
}

View File

@ -113,6 +113,10 @@ _ENTRY(_start);
stw r5, 0(r4) /* Save abatron_pteptrs at a fixed location */
stw r6, 0(r5)
/* Clear the Machine Check Syndrome Register */
li r0,0
mtspr SPRN_MCSR,r0
/* Let's move on */
lis r4,start_kernel@h
ori r4,r4,start_kernel@l

View File

@ -572,9 +572,6 @@ __secondary_start:
/* Set thread priority to MEDIUM */
HMT_MEDIUM
/* Do early setup for that CPU (stab, slb, hash table pointer) */
bl .early_setup_secondary
/* Initialize the kernel stack. Just a repeat for iSeries. */
LOAD_REG_ADDR(r3, current_set)
sldi r28,r24,3 /* get current_set[cpu#] */
@ -582,6 +579,9 @@ __secondary_start:
addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
std r1,PACAKSAVE(r13)
/* Do early setup for that CPU (stab, slb, hash table pointer) */
bl .early_setup_secondary
/* Clear backchain so we get nice backtraces */
li r7,0
mtlr r7

View File

@ -94,9 +94,9 @@ void cpu_idle(void)
HMT_medium();
ppc64_runlatch_on();
tick_nohz_restart_sched_tick();
preempt_enable_no_resched();
if (cpu_should_die())
cpu_die();
preempt_enable_no_resched();
schedule();
preempt_disable();
}

View File

@ -67,6 +67,7 @@
#include <asm/machdep.h>
#include <asm/udbg.h>
#include <asm/dbell.h>
#include <asm/smp.h>
#ifdef CONFIG_PPC64
#include <asm/paca.h>
@ -446,22 +447,23 @@ struct thread_info *mcheckirq_ctx[NR_CPUS] __read_mostly;
void exc_lvl_ctx_init(void)
{
struct thread_info *tp;
int i;
int i, hw_cpu;
for_each_possible_cpu(i) {
memset((void *)critirq_ctx[i], 0, THREAD_SIZE);
tp = critirq_ctx[i];
hw_cpu = get_hard_smp_processor_id(i);
memset((void *)critirq_ctx[hw_cpu], 0, THREAD_SIZE);
tp = critirq_ctx[hw_cpu];
tp->cpu = i;
tp->preempt_count = 0;
#ifdef CONFIG_BOOKE
memset((void *)dbgirq_ctx[i], 0, THREAD_SIZE);
tp = dbgirq_ctx[i];
memset((void *)dbgirq_ctx[hw_cpu], 0, THREAD_SIZE);
tp = dbgirq_ctx[hw_cpu];
tp->cpu = i;
tp->preempt_count = 0;
memset((void *)mcheckirq_ctx[i], 0, THREAD_SIZE);
tp = mcheckirq_ctx[i];
memset((void *)mcheckirq_ctx[hw_cpu], 0, THREAD_SIZE);
tp = mcheckirq_ctx[hw_cpu];
tp->cpu = i;
tp->preempt_count = HARDIRQ_OFFSET;
#endif

View File

@ -336,7 +336,7 @@ static void __devinit __of_scan_bus(struct device_node *node,
if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {
struct device_node *child = pci_device_to_OF_node(dev);
if (dev)
if (child)
of_scan_pci_bridge(child, dev);
}
}

View File

@ -728,7 +728,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
p->thread.regs = childregs;
if (clone_flags & CLONE_SETTLS) {
#ifdef CONFIG_PPC64
if (!test_thread_flag(TIF_32BIT))
if (!is_32bit_task())
childregs->gpr[13] = childregs->gpr[6];
else
#endif
@ -823,7 +823,7 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp)
regs->nip = start;
regs->msr = MSR_USER;
#else
if (!test_thread_flag(TIF_32BIT)) {
if (!is_32bit_task()) {
unsigned long entry, toc;
/* start is a relocated pointer to the function descriptor for
@ -995,7 +995,7 @@ int sys_clone(unsigned long clone_flags, unsigned long usp,
if (usp == 0)
usp = regs->gpr[1]; /* stack pointer for child */
#ifdef CONFIG_PPC64
if (test_thread_flag(TIF_32BIT)) {
if (is_32bit_task()) {
parent_tidp = TRUNC_PTR(parent_tidp);
child_tidp = TRUNC_PTR(child_tidp);
}
@ -1199,19 +1199,17 @@ void ppc64_runlatch_on(void)
}
}
void ppc64_runlatch_off(void)
void __ppc64_runlatch_off(void)
{
unsigned long ctrl;
if (cpu_has_feature(CPU_FTR_CTRL) && test_thread_flag(TIF_RUNLATCH)) {
HMT_medium();
HMT_medium();
clear_thread_flag(TIF_RUNLATCH);
clear_thread_flag(TIF_RUNLATCH);
ctrl = mfspr(SPRN_CTRLF);
ctrl &= ~CTRL_RUNLATCH;
mtspr(SPRN_CTRLT, ctrl);
}
ctrl = mfspr(SPRN_CTRLF);
ctrl &= ~CTRL_RUNLATCH;
mtspr(SPRN_CTRLT, ctrl);
}
#endif

View File

@ -258,17 +258,18 @@ static void __init irqstack_early_init(void)
#if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
static void __init exc_lvl_early_init(void)
{
unsigned int i;
unsigned int i, hw_cpu;
/* interrupt stacks must be in lowmem, we get that for free on ppc32
* as the memblock is limited to lowmem by MEMBLOCK_REAL_LIMIT */
for_each_possible_cpu(i) {
critirq_ctx[i] = (struct thread_info *)
hw_cpu = get_hard_smp_processor_id(i);
critirq_ctx[hw_cpu] = (struct thread_info *)
__va(memblock_alloc(THREAD_SIZE, THREAD_SIZE));
#ifdef CONFIG_BOOKE
dbgirq_ctx[i] = (struct thread_info *)
dbgirq_ctx[hw_cpu] = (struct thread_info *)
__va(memblock_alloc(THREAD_SIZE, THREAD_SIZE));
mcheckirq_ctx[i] = (struct thread_info *)
mcheckirq_ctx[hw_cpu] = (struct thread_info *)
__va(memblock_alloc(THREAD_SIZE, THREAD_SIZE));
#endif
}

View File

@ -95,7 +95,7 @@ int ucache_bsize;
#ifdef CONFIG_SMP
static int smt_enabled_cmdline;
static char *smt_enabled_cmdline;
/* Look for ibm,smt-enabled OF option */
static void check_smt_enabled(void)
@ -103,37 +103,46 @@ static void check_smt_enabled(void)
struct device_node *dn;
const char *smt_option;
/* Default to enabling all threads */
smt_enabled_at_boot = threads_per_core;
/* Allow the command line to overrule the OF option */
if (smt_enabled_cmdline)
return;
if (smt_enabled_cmdline) {
if (!strcmp(smt_enabled_cmdline, "on"))
smt_enabled_at_boot = threads_per_core;
else if (!strcmp(smt_enabled_cmdline, "off"))
smt_enabled_at_boot = 0;
else {
long smt;
int rc;
dn = of_find_node_by_path("/options");
rc = strict_strtol(smt_enabled_cmdline, 10, &smt);
if (!rc)
smt_enabled_at_boot =
min(threads_per_core, (int)smt);
}
} else {
dn = of_find_node_by_path("/options");
if (dn) {
smt_option = of_get_property(dn, "ibm,smt-enabled",
NULL);
if (dn) {
smt_option = of_get_property(dn, "ibm,smt-enabled", NULL);
if (smt_option) {
if (!strcmp(smt_option, "on"))
smt_enabled_at_boot = threads_per_core;
else if (!strcmp(smt_option, "off"))
smt_enabled_at_boot = 0;
}
if (smt_option) {
if (!strcmp(smt_option, "on"))
smt_enabled_at_boot = 1;
else if (!strcmp(smt_option, "off"))
smt_enabled_at_boot = 0;
}
}
of_node_put(dn);
}
}
}
/* Look for smt-enabled= cmdline option */
static int __init early_smt_enabled(char *p)
{
smt_enabled_cmdline = 1;
if (!p)
return 0;
if (!strcmp(p, "on") || !strcmp(p, "1"))
smt_enabled_at_boot = 1;
else if (!strcmp(p, "off") || !strcmp(p, "0"))
smt_enabled_at_boot = 0;
smt_enabled_cmdline = p;
return 0;
}
early_param("smt-enabled", early_smt_enabled);
@ -380,8 +389,8 @@ void __init setup_system(void)
*/
xmon_setup();
check_smt_enabled();
smp_setup_cpu_maps();
check_smt_enabled();
#ifdef CONFIG_SMP
/* Release secondary cpus out of their spinloops at 0x60 now that

View File

@ -427,11 +427,11 @@ int __cpuinit __cpu_up(unsigned int cpu)
#endif
if (!cpu_callin_map[cpu]) {
printk("Processor %u is stuck.\n", cpu);
printk(KERN_ERR "Processor %u is stuck.\n", cpu);
return -ENOENT;
}
printk("Processor %u found.\n", cpu);
DBG("Processor %u found.\n", cpu);
if (smp_ops->give_timebase)
smp_ops->give_timebase();

View File

@ -616,3 +616,11 @@ asmlinkage long compat_sys_sync_file_range2(int fd, unsigned int flags,
return sys_sync_file_range(fd, offset, nbytes, flags);
}
asmlinkage long compat_sys_fanotify_mark(int fanotify_fd, unsigned int flags,
unsigned mask_hi, unsigned mask_lo,
int dfd, const char __user *pathname)
{
u64 mask = ((u64)mask_hi << 32) | mask_lo;
return sys_fanotify_mark(fanotify_fd, flags, mask, dfd, pathname);
}

View File

@ -1059,7 +1059,7 @@ static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev)
if (!dma_window)
return NULL;
tbl = kmalloc(sizeof(*tbl), GFP_KERNEL);
tbl = kzalloc(sizeof(*tbl), GFP_KERNEL);
if (tbl == NULL)
return NULL;
@ -1072,6 +1072,7 @@ static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev)
tbl->it_offset = offset >> IOMMU_PAGE_SHIFT;
tbl->it_busno = 0;
tbl->it_type = TCE_VB;
tbl->it_blocksize = 16;
return iommu_init_table(tbl, -1);
}

View File

@ -79,7 +79,9 @@
#endif /* CONFIG_PPC_STD_MMU_64 */
phys_addr_t memstart_addr = ~0;
EXPORT_SYMBOL_GPL(memstart_addr);
phys_addr_t kernstart_addr;
EXPORT_SYMBOL_GPL(kernstart_addr);
void free_initmem(void)
{

View File

@ -200,6 +200,7 @@ _GLOBAL(_tlbivax_bcast)
rlwimi r5,r4,0,16,31
wrteei 0
mtspr SPRN_MMUCR,r5
isync
/* tlbivax 0,r3 - use .long to avoid binutils deps */
.long 0x7c000624 | (r3 << 11)
isync

View File

@ -106,8 +106,7 @@ config MMIO_NVRAM
config MPIC_U3_HT_IRQS
bool
depends on PPC_MAPLE
default y
default n
config MPIC_BROKEN_REGREAD
bool

View File

@ -477,7 +477,7 @@ cell_iommu_setup_window(struct cbe_iommu *iommu, struct device_node *np,
ioid = cell_iommu_get_ioid(np);
window = kmalloc_node(sizeof(*window), GFP_KERNEL, iommu->nid);
window = kzalloc_node(sizeof(*window), GFP_KERNEL, iommu->nid);
BUG_ON(window == NULL);
window->offset = offset;

View File

@ -184,7 +184,7 @@ static void pci_dma_dev_setup_iseries(struct pci_dev *pdev)
BUG_ON(lsn == NULL);
tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
tbl = kzalloc(sizeof(struct iommu_table), GFP_KERNEL);
iommu_table_getparms_iSeries(pdn->busno, *lsn, 0, tbl);

View File

@ -2873,12 +2873,11 @@ set_initial_features(void)
/* Switch airport off */
for_each_node_by_name(np, "radio") {
if (np && np->parent == macio_chips[0].of_node) {
if (np->parent == macio_chips[0].of_node) {
macio_chips[0].flags |= MACIO_FLAG_AIRPORT_ON;
core99_airport_enable(np, 0, 0);
}
}
of_node_put(np);
}
/* On all machines that support sound PM, switch sound off */

View File

@ -1155,13 +1155,11 @@ void __init pmac_pcibios_after_init(void)
pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, nd, 0, 0);
}
}
of_node_put(nd);
for_each_node_by_name(nd, "ethernet") {
if (nd->parent && of_device_is_compatible(nd, "gmac")
&& of_device_is_compatible(nd->parent, "uni-north"))
pmac_call_feature(PMAC_FTR_GMAC_ENABLE, nd, 0, 0);
}
of_node_put(nd);
}
void pmac_pci_fixup_cardbus(struct pci_dev* dev)

View File

@ -403,7 +403,7 @@ static void pci_dma_bus_setup_pSeries(struct pci_bus *bus)
pci->phb->dma_window_size = 0x8000000ul;
pci->phb->dma_window_base_cur = 0x8000000ul;
tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
tbl = kzalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
pci->phb->node);
iommu_table_setparms(pci->phb, dn, tbl);
@ -448,7 +448,7 @@ static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus)
pdn->full_name, ppci->iommu_table);
if (!ppci->iommu_table) {
tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
tbl = kzalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
ppci->phb->node);
iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window,
bus->number);
@ -478,7 +478,7 @@ static void pci_dma_dev_setup_pSeries(struct pci_dev *dev)
struct pci_controller *phb = PCI_DN(dn)->phb;
pr_debug(" --> first child, no bridge. Allocating iommu table.\n");
tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
tbl = kzalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
phb->node);
iommu_table_setparms(phb, dn, tbl);
PCI_DN(dn)->iommu_table = iommu_init_table(tbl, phb->node);
@ -544,7 +544,7 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev)
pci = PCI_DN(pdn);
if (!pci->iommu_table) {
tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
tbl = kzalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
pci->phb->node);
iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window,
pci->phb->bus->number);

View File

@ -182,10 +182,13 @@ static int smp_pSeries_cpu_bootable(unsigned int nr)
/* Special case - we inhibit secondary thread startup
* during boot if the user requests it.
*/
if (system_state < SYSTEM_RUNNING &&
cpu_has_feature(CPU_FTR_SMT) &&
!smt_enabled_at_boot && cpu_thread_in_core(nr) != 0)
return 0;
if (system_state < SYSTEM_RUNNING && cpu_has_feature(CPU_FTR_SMT)) {
if (!smt_enabled_at_boot && cpu_thread_in_core(nr) != 0)
return 0;
if (smt_enabled_at_boot
&& cpu_thread_in_core(nr) >= smt_enabled_at_boot)
return 0;
}
return 1;
}

View File

@ -928,8 +928,10 @@ void xics_migrate_irqs_away(void)
if (xics_status[0] != hw_cpu)
goto unlock;
printk(KERN_WARNING "IRQ %u affinity broken off cpu %u\n",
virq, cpu);
/* This is expected during cpu offline. */
if (cpu_online(cpu))
printk(KERN_WARNING "IRQ %u affinity broken off cpu %u\n",
virq, cpu);
/* Reset affinity to all cpus */
cpumask_setall(irq_to_desc(virq)->affinity);

View File

@ -97,6 +97,7 @@ static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
{
pte_t pte = huge_ptep_get(ptep);
mm->context.flush_mm = 1;
pmd_clear((pmd_t *) ptep);
return pte;
}
@ -167,7 +168,8 @@ static inline void huge_ptep_invalidate(struct mm_struct *mm,
({ \
pte_t __pte = huge_ptep_get(__ptep); \
if (pte_write(__pte)) { \
if (atomic_read(&(__mm)->mm_users) > 1 || \
(__mm)->context.flush_mm = 1; \
if (atomic_read(&(__mm)->context.attach_count) > 1 || \
(__mm) != current->active_mm) \
huge_ptep_invalidate(__mm, __addr, __ptep); \
set_huge_pte_at(__mm, __addr, __ptep, \

View File

@ -2,6 +2,8 @@
#define __MMU_H
typedef struct {
atomic_t attach_count;
unsigned int flush_mm;
spinlock_t list_lock;
struct list_head crst_list;
struct list_head pgtable_list;

View File

@ -11,11 +11,14 @@
#include <asm/pgalloc.h>
#include <asm/uaccess.h>
#include <asm/tlbflush.h>
#include <asm-generic/mm_hooks.h>
static inline int init_new_context(struct task_struct *tsk,
struct mm_struct *mm)
{
atomic_set(&mm->context.attach_count, 0);
mm->context.flush_mm = 0;
mm->context.asce_bits = _ASCE_TABLE_LENGTH | _ASCE_USER_BITS;
#ifdef CONFIG_64BIT
mm->context.asce_bits |= _ASCE_TYPE_REGION3;
@ -76,6 +79,12 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
{
cpumask_set_cpu(smp_processor_id(), mm_cpumask(next));
update_mm(next, tsk);
atomic_dec(&prev->context.attach_count);
WARN_ON(atomic_read(&prev->context.attach_count) < 0);
atomic_inc(&next->context.attach_count);
/* Check for TLBs not flushed yet */
if (next->context.flush_mm)
__tlb_flush_mm(next);
}
#define enter_lazy_tlb(mm,tsk) do { } while (0)

View File

@ -880,7 +880,8 @@ static inline void ptep_invalidate(struct mm_struct *mm,
#define ptep_get_and_clear(__mm, __address, __ptep) \
({ \
pte_t __pte = *(__ptep); \
if (atomic_read(&(__mm)->mm_users) > 1 || \
(__mm)->context.flush_mm = 1; \
if (atomic_read(&(__mm)->context.attach_count) > 1 || \
(__mm) != current->active_mm) \
ptep_invalidate(__mm, __address, __ptep); \
else \
@ -923,7 +924,8 @@ static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm,
({ \
pte_t __pte = *(__ptep); \
if (pte_write(__pte)) { \
if (atomic_read(&(__mm)->mm_users) > 1 || \
(__mm)->context.flush_mm = 1; \
if (atomic_read(&(__mm)->context.attach_count) > 1 || \
(__mm) != current->active_mm) \
ptep_invalidate(__mm, __addr, __ptep); \
set_pte_at(__mm, __addr, __ptep, pte_wrprotect(__pte)); \

View File

@ -50,8 +50,7 @@ static inline struct mmu_gather *tlb_gather_mmu(struct mm_struct *mm,
struct mmu_gather *tlb = &get_cpu_var(mmu_gathers);
tlb->mm = mm;
tlb->fullmm = full_mm_flush || (num_online_cpus() == 1) ||
(atomic_read(&mm->mm_users) <= 1 && mm == current->active_mm);
tlb->fullmm = full_mm_flush;
tlb->nr_ptes = 0;
tlb->nr_pxds = TLB_NR_PTRS;
if (tlb->fullmm)

View File

@ -94,8 +94,12 @@ static inline void __tlb_flush_mm(struct mm_struct * mm)
static inline void __tlb_flush_mm_cond(struct mm_struct * mm)
{
if (atomic_read(&mm->mm_users) <= 1 && mm == current->active_mm)
spin_lock(&mm->page_table_lock);
if (mm->context.flush_mm) {
__tlb_flush_mm(mm);
mm->context.flush_mm = 0;
}
spin_unlock(&mm->page_table_lock);
}
/*

View File

@ -42,8 +42,8 @@ long sys_clone(unsigned long newsp, unsigned long clone_flags,
int __user *parent_tidptr, int __user *child_tidptr);
long sys_vfork(void);
void execve_tail(void);
long sys_execve(const char __user *name, char __user * __user *argv,
char __user * __user *envp);
long sys_execve(const char __user *name, const char __user *const __user *argv,
const char __user *const __user *envp);
long sys_sigsuspend(int history0, int history1, old_sigset_t mask);
long sys_sigaction(int sig, const struct old_sigaction __user *act,
struct old_sigaction __user *oact);

View File

@ -583,6 +583,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
sf->gprs[9] = (unsigned long) sf;
cpu_lowcore->save_area[15] = (unsigned long) sf;
__ctl_store(cpu_lowcore->cregs_save_area, 0, 15);
atomic_inc(&init_mm.context.attach_count);
asm volatile(
" stam 0,15,0(%0)"
: : "a" (&cpu_lowcore->access_regs_save_area) : "memory");
@ -659,6 +660,7 @@ void __cpu_die(unsigned int cpu)
while (sigp_p(0, cpu, sigp_set_prefix) == sigp_busy)
udelay(10);
smp_free_lowcore(cpu);
atomic_dec(&init_mm.context.attach_count);
pr_info("Processor %d stopped\n", cpu);
}

View File

@ -74,6 +74,8 @@ void __init paging_init(void)
__ctl_load(S390_lowcore.kernel_asce, 13, 13);
__raw_local_irq_ssm(ssm_mask);
atomic_set(&init_mm.context.attach_count, 1);
sparse_memory_present_with_active_regions(MAX_NUMNODES);
sparse_init();
memset(max_zone_pfns, 0, sizeof(max_zone_pfns));

View File

@ -20,14 +20,14 @@
#define atomic64_set(v, i) (((v)->counter) = i)
extern void atomic_add(int, atomic_t *);
extern void atomic64_add(int, atomic64_t *);
extern void atomic64_add(long, atomic64_t *);
extern void atomic_sub(int, atomic_t *);
extern void atomic64_sub(int, atomic64_t *);
extern void atomic64_sub(long, atomic64_t *);
extern int atomic_add_ret(int, atomic_t *);
extern long atomic64_add_ret(int, atomic64_t *);
extern long atomic64_add_ret(long, atomic64_t *);
extern int atomic_sub_ret(int, atomic_t *);
extern long atomic64_sub_ret(int, atomic64_t *);
extern long atomic64_sub_ret(long, atomic64_t *);
#define atomic_dec_return(v) atomic_sub_ret(1, v)
#define atomic64_dec_return(v) atomic64_sub_ret(1, v)

View File

@ -8,6 +8,9 @@
#define BACKOFF_SETUP(reg) \
mov 1, reg
#define BACKOFF_LABEL(spin_label, continue_label) \
spin_label
#define BACKOFF_SPIN(reg, tmp, label) \
mov reg, tmp; \
88: brnz,pt tmp, 88b; \
@ -22,9 +25,11 @@
#else
#define BACKOFF_SETUP(reg)
#define BACKOFF_SPIN(reg, tmp, label) \
ba,pt %xcc, label; \
nop;
#define BACKOFF_LABEL(spin_label, continue_label) \
continue_label
#define BACKOFF_SPIN(reg, tmp, label)
#endif

View File

@ -185,9 +185,8 @@ extern int prom_getunumber(int syndrome_code,
char *buf, int buflen);
/* Retain physical memory to the caller across soft resets. */
extern unsigned long prom_retain(const char *name,
unsigned long pa_low, unsigned long pa_high,
long size, long align);
extern int prom_retain(const char *name, unsigned long size,
unsigned long align, unsigned long *paddr);
/* Load explicit I/D TLB entries into the calling processor. */
extern long prom_itlb_load(unsigned long index,
@ -287,26 +286,6 @@ extern void prom_sun4v_guest_soft_state(void);
extern int prom_ihandle2path(int handle, char *buffer, int bufsize);
/* Client interface level routines. */
extern long p1275_cmd(const char *, long, ...);
#if 0
#define P1275_SIZE(x) ((((long)((x) / 32)) << 32) | (x))
#else
#define P1275_SIZE(x) x
#endif
/* We support at most 16 input and 1 output argument */
#define P1275_ARG_NUMBER 0
#define P1275_ARG_IN_STRING 1
#define P1275_ARG_OUT_BUF 2
#define P1275_ARG_OUT_32B 3
#define P1275_ARG_IN_FUNCTION 4
#define P1275_ARG_IN_BUF 5
#define P1275_ARG_IN_64B 6
#define P1275_IN(x) ((x) & 0xf)
#define P1275_OUT(x) (((x) << 4) & 0xf0)
#define P1275_INOUT(i,o) (P1275_IN(i)|P1275_OUT(o))
#define P1275_ARG(n,x) ((x) << ((n)*3 + 8))
extern void p1275_cmd_direct(unsigned long *);
#endif /* !(__SPARC64_OPLIB_H) */

View File

@ -1,12 +0,0 @@
/* rwsem-const.h: RW semaphore counter constants. */
#ifndef _SPARC64_RWSEM_CONST_H
#define _SPARC64_RWSEM_CONST_H
#define RWSEM_UNLOCKED_VALUE 0x00000000
#define RWSEM_ACTIVE_BIAS 0x00000001
#define RWSEM_ACTIVE_MASK 0x0000ffff
#define RWSEM_WAITING_BIAS (-0x00010000)
#define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS
#define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
#endif /* _SPARC64_RWSEM_CONST_H */

View File

@ -15,16 +15,21 @@
#include <linux/list.h>
#include <linux/spinlock.h>
#include <asm/rwsem-const.h>
struct rwsem_waiter;
struct rw_semaphore {
signed int count;
spinlock_t wait_lock;
struct list_head wait_list;
signed long count;
#define RWSEM_UNLOCKED_VALUE 0x00000000L
#define RWSEM_ACTIVE_BIAS 0x00000001L
#define RWSEM_ACTIVE_MASK 0xffffffffL
#define RWSEM_WAITING_BIAS (-RWSEM_ACTIVE_MASK-1)
#define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS
#define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
spinlock_t wait_lock;
struct list_head wait_list;
#ifdef CONFIG_DEBUG_LOCK_ALLOC
struct lockdep_map dep_map;
struct lockdep_map dep_map;
#endif
};
@ -41,6 +46,11 @@ struct rw_semaphore {
#define DECLARE_RWSEM(name) \
struct rw_semaphore name = __RWSEM_INITIALIZER(name)
extern struct rw_semaphore *rwsem_down_read_failed(struct rw_semaphore *sem);
extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem);
extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem);
extern struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem);
extern void __init_rwsem(struct rw_semaphore *sem, const char *name,
struct lock_class_key *key);
@ -51,27 +61,103 @@ do { \
__init_rwsem((sem), #sem, &__key); \
} while (0)
extern void __down_read(struct rw_semaphore *sem);
extern int __down_read_trylock(struct rw_semaphore *sem);
extern void __down_write(struct rw_semaphore *sem);
extern int __down_write_trylock(struct rw_semaphore *sem);
extern void __up_read(struct rw_semaphore *sem);
extern void __up_write(struct rw_semaphore *sem);
extern void __downgrade_write(struct rw_semaphore *sem);
/*
* lock for reading
*/
static inline void __down_read(struct rw_semaphore *sem)
{
if (unlikely(atomic64_inc_return((atomic64_t *)(&sem->count)) <= 0L))
rwsem_down_read_failed(sem);
}
static inline int __down_read_trylock(struct rw_semaphore *sem)
{
long tmp;
while ((tmp = sem->count) >= 0L) {
if (tmp == cmpxchg(&sem->count, tmp,
tmp + RWSEM_ACTIVE_READ_BIAS)) {
return 1;
}
}
return 0;
}
/*
* lock for writing
*/
static inline void __down_write_nested(struct rw_semaphore *sem, int subclass)
{
__down_write(sem);
long tmp;
tmp = atomic64_add_return(RWSEM_ACTIVE_WRITE_BIAS,
(atomic64_t *)(&sem->count));
if (unlikely(tmp != RWSEM_ACTIVE_WRITE_BIAS))
rwsem_down_write_failed(sem);
}
static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem)
static inline void __down_write(struct rw_semaphore *sem)
{
return atomic_add_return(delta, (atomic_t *)(&sem->count));
__down_write_nested(sem, 0);
}
static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
static inline int __down_write_trylock(struct rw_semaphore *sem)
{
atomic_add(delta, (atomic_t *)(&sem->count));
long tmp;
tmp = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE,
RWSEM_ACTIVE_WRITE_BIAS);
return tmp == RWSEM_UNLOCKED_VALUE;
}
/*
* unlock after reading
*/
static inline void __up_read(struct rw_semaphore *sem)
{
long tmp;
tmp = atomic64_dec_return((atomic64_t *)(&sem->count));
if (unlikely(tmp < -1L && (tmp & RWSEM_ACTIVE_MASK) == 0L))
rwsem_wake(sem);
}
/*
* unlock after writing
*/
static inline void __up_write(struct rw_semaphore *sem)
{
if (unlikely(atomic64_sub_return(RWSEM_ACTIVE_WRITE_BIAS,
(atomic64_t *)(&sem->count)) < 0L))
rwsem_wake(sem);
}
/*
* implement atomic add functionality
*/
static inline void rwsem_atomic_add(long delta, struct rw_semaphore *sem)
{
atomic64_add(delta, (atomic64_t *)(&sem->count));
}
/*
* downgrade write lock to read lock
*/
static inline void __downgrade_write(struct rw_semaphore *sem)
{
long tmp;
tmp = atomic64_add_return(-RWSEM_WAITING_BIAS, (atomic64_t *)(&sem->count));
if (tmp < 0L)
rwsem_downgrade_wake(sem);
}
/*
* implement exchange and add functionality
*/
static inline long rwsem_atomic_update(long delta, struct rw_semaphore *sem)
{
return atomic64_add_return(delta, (atomic64_t *)(&sem->count));
}
static inline int rwsem_is_locked(struct rw_semaphore *sem)

View File

@ -106,6 +106,7 @@ do { __asm__ __volatile__("ba,pt %%xcc, 1f\n\t" \
*/
#define write_pic(__p) \
__asm__ __volatile__("ba,pt %%xcc, 99f\n\t" \
" nop\n\t" \
".align 64\n" \
"99:wr %0, 0x0, %%pic\n\t" \
"rd %%pic, %%g0" : : "r" (__p))

View File

@ -15,7 +15,7 @@ lib-$(CONFIG_SPARC32) += divdi3.o udivdi3.o
lib-$(CONFIG_SPARC32) += copy_user.o locks.o
lib-y += atomic_$(BITS).o
lib-$(CONFIG_SPARC32) += lshrdi3.o ashldi3.o
lib-y += rwsem_$(BITS).o
lib-$(CONFIG_SPARC32) += rwsem_32.o
lib-$(CONFIG_SPARC32) += muldi3.o bitext.o cmpdi2.o
lib-$(CONFIG_SPARC64) += copy_page.o clear_page.o bzero.o

View File

@ -21,7 +21,7 @@ atomic_add: /* %o0 = increment, %o1 = atomic_ptr */
add %g1, %o0, %g7
cas [%o1], %g1, %g7
cmp %g1, %g7
bne,pn %icc, 2f
bne,pn %icc, BACKOFF_LABEL(2f, 1b)
nop
retl
nop
@ -36,7 +36,7 @@ atomic_sub: /* %o0 = decrement, %o1 = atomic_ptr */
sub %g1, %o0, %g7
cas [%o1], %g1, %g7
cmp %g1, %g7
bne,pn %icc, 2f
bne,pn %icc, BACKOFF_LABEL(2f, 1b)
nop
retl
nop
@ -51,11 +51,10 @@ atomic_add_ret: /* %o0 = increment, %o1 = atomic_ptr */
add %g1, %o0, %g7
cas [%o1], %g1, %g7
cmp %g1, %g7
bne,pn %icc, 2f
add %g7, %o0, %g7
sra %g7, 0, %o0
bne,pn %icc, BACKOFF_LABEL(2f, 1b)
add %g1, %o0, %g1
retl
nop
sra %g1, 0, %o0
2: BACKOFF_SPIN(%o2, %o3, 1b)
.size atomic_add_ret, .-atomic_add_ret
@ -67,11 +66,10 @@ atomic_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */
sub %g1, %o0, %g7
cas [%o1], %g1, %g7
cmp %g1, %g7
bne,pn %icc, 2f
sub %g7, %o0, %g7
sra %g7, 0, %o0
bne,pn %icc, BACKOFF_LABEL(2f, 1b)
sub %g1, %o0, %g1
retl
nop
sra %g1, 0, %o0
2: BACKOFF_SPIN(%o2, %o3, 1b)
.size atomic_sub_ret, .-atomic_sub_ret
@ -83,7 +81,7 @@ atomic64_add: /* %o0 = increment, %o1 = atomic_ptr */
add %g1, %o0, %g7
casx [%o1], %g1, %g7
cmp %g1, %g7
bne,pn %xcc, 2f
bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
nop
retl
nop
@ -98,7 +96,7 @@ atomic64_sub: /* %o0 = decrement, %o1 = atomic_ptr */
sub %g1, %o0, %g7
casx [%o1], %g1, %g7
cmp %g1, %g7
bne,pn %xcc, 2f
bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
nop
retl
nop
@ -113,11 +111,10 @@ atomic64_add_ret: /* %o0 = increment, %o1 = atomic_ptr */
add %g1, %o0, %g7
casx [%o1], %g1, %g7
cmp %g1, %g7
bne,pn %xcc, 2f
add %g7, %o0, %g7
mov %g7, %o0
retl
bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
nop
retl
add %g1, %o0, %o0
2: BACKOFF_SPIN(%o2, %o3, 1b)
.size atomic64_add_ret, .-atomic64_add_ret
@ -129,10 +126,9 @@ atomic64_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */
sub %g1, %o0, %g7
casx [%o1], %g1, %g7
cmp %g1, %g7
bne,pn %xcc, 2f
sub %g7, %o0, %g7
mov %g7, %o0
retl
bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
nop
retl
sub %g1, %o0, %o0
2: BACKOFF_SPIN(%o2, %o3, 1b)
.size atomic64_sub_ret, .-atomic64_sub_ret

View File

@ -22,7 +22,7 @@ test_and_set_bit: /* %o0=nr, %o1=addr */
or %g7, %o2, %g1
casx [%o1], %g7, %g1
cmp %g7, %g1
bne,pn %xcc, 2f
bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
and %g7, %o2, %g2
clr %o0
movrne %g2, 1, %o0
@ -45,7 +45,7 @@ test_and_clear_bit: /* %o0=nr, %o1=addr */
andn %g7, %o2, %g1
casx [%o1], %g7, %g1
cmp %g7, %g1
bne,pn %xcc, 2f
bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
and %g7, %o2, %g2
clr %o0
movrne %g2, 1, %o0
@ -68,7 +68,7 @@ test_and_change_bit: /* %o0=nr, %o1=addr */
xor %g7, %o2, %g1
casx [%o1], %g7, %g1
cmp %g7, %g1
bne,pn %xcc, 2f
bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
and %g7, %o2, %g2
clr %o0
movrne %g2, 1, %o0
@ -91,7 +91,7 @@ set_bit: /* %o0=nr, %o1=addr */
or %g7, %o2, %g1
casx [%o1], %g7, %g1
cmp %g7, %g1
bne,pn %xcc, 2f
bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
nop
retl
nop
@ -112,7 +112,7 @@ clear_bit: /* %o0=nr, %o1=addr */
andn %g7, %o2, %g1
casx [%o1], %g7, %g1
cmp %g7, %g1
bne,pn %xcc, 2f
bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
nop
retl
nop
@ -133,7 +133,7 @@ change_bit: /* %o0=nr, %o1=addr */
xor %g7, %o2, %g1
casx [%o1], %g7, %g1
cmp %g7, %g1
bne,pn %xcc, 2f
bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
nop
retl
nop

View File

@ -1,163 +0,0 @@
/* rwsem.S: RW semaphore assembler.
*
* Written by David S. Miller (davem@redhat.com), 2001.
* Derived from asm-i386/rwsem.h
*/
#include <asm/rwsem-const.h>
.section .sched.text, "ax"
.globl __down_read
__down_read:
1: lduw [%o0], %g1
add %g1, 1, %g7
cas [%o0], %g1, %g7
cmp %g1, %g7
bne,pn %icc, 1b
add %g7, 1, %g7
cmp %g7, 0
bl,pn %icc, 3f
nop
2:
retl
nop
3:
save %sp, -192, %sp
call rwsem_down_read_failed
mov %i0, %o0
ret
restore
.size __down_read, .-__down_read
.globl __down_read_trylock
__down_read_trylock:
1: lduw [%o0], %g1
add %g1, 1, %g7
cmp %g7, 0
bl,pn %icc, 2f
mov 0, %o1
cas [%o0], %g1, %g7
cmp %g1, %g7
bne,pn %icc, 1b
mov 1, %o1
2: retl
mov %o1, %o0
.size __down_read_trylock, .-__down_read_trylock
.globl __down_write
__down_write:
sethi %hi(RWSEM_ACTIVE_WRITE_BIAS), %g1
or %g1, %lo(RWSEM_ACTIVE_WRITE_BIAS), %g1
1:
lduw [%o0], %g3
add %g3, %g1, %g7
cas [%o0], %g3, %g7
cmp %g3, %g7
bne,pn %icc, 1b
cmp %g7, 0
bne,pn %icc, 3f
nop
2: retl
nop
3:
save %sp, -192, %sp
call rwsem_down_write_failed
mov %i0, %o0
ret
restore
.size __down_write, .-__down_write
.globl __down_write_trylock
__down_write_trylock:
sethi %hi(RWSEM_ACTIVE_WRITE_BIAS), %g1
or %g1, %lo(RWSEM_ACTIVE_WRITE_BIAS), %g1
1:
lduw [%o0], %g3
cmp %g3, 0
bne,pn %icc, 2f
mov 0, %o1
add %g3, %g1, %g7
cas [%o0], %g3, %g7
cmp %g3, %g7
bne,pn %icc, 1b
mov 1, %o1
2: retl
mov %o1, %o0
.size __down_write_trylock, .-__down_write_trylock
.globl __up_read
__up_read:
1:
lduw [%o0], %g1
sub %g1, 1, %g7
cas [%o0], %g1, %g7
cmp %g1, %g7
bne,pn %icc, 1b
cmp %g7, 0
bl,pn %icc, 3f
nop
2: retl
nop
3: sethi %hi(RWSEM_ACTIVE_MASK), %g1
sub %g7, 1, %g7
or %g1, %lo(RWSEM_ACTIVE_MASK), %g1
andcc %g7, %g1, %g0
bne,pn %icc, 2b
nop
save %sp, -192, %sp
call rwsem_wake
mov %i0, %o0
ret
restore
.size __up_read, .-__up_read
.globl __up_write
__up_write:
sethi %hi(RWSEM_ACTIVE_WRITE_BIAS), %g1
or %g1, %lo(RWSEM_ACTIVE_WRITE_BIAS), %g1
1:
lduw [%o0], %g3
sub %g3, %g1, %g7
cas [%o0], %g3, %g7
cmp %g3, %g7
bne,pn %icc, 1b
sub %g7, %g1, %g7
cmp %g7, 0
bl,pn %icc, 3f
nop
2:
retl
nop
3:
save %sp, -192, %sp
call rwsem_wake
mov %i0, %o0
ret
restore
.size __up_write, .-__up_write
.globl __downgrade_write
__downgrade_write:
sethi %hi(RWSEM_WAITING_BIAS), %g1
or %g1, %lo(RWSEM_WAITING_BIAS), %g1
1:
lduw [%o0], %g3
sub %g3, %g1, %g7
cas [%o0], %g3, %g7
cmp %g3, %g7
bne,pn %icc, 1b
sub %g7, %g1, %g7
cmp %g7, 0
bl,pn %icc, 3f
nop
2:
retl
nop
3:
save %sp, -192, %sp
call rwsem_downgrade_wake
mov %i0, %o0
ret
restore
.size __downgrade_write, .-__downgrade_write

View File

@ -9,18 +9,18 @@
#include <asm/thread_info.h>
.text
.globl prom_cif_interface
prom_cif_interface:
sethi %hi(p1275buf), %o0
or %o0, %lo(p1275buf), %o0
ldx [%o0 + 0x010], %o1 ! prom_cif_stack
save %o1, -192, %sp
ldx [%i0 + 0x008], %l2 ! prom_cif_handler
.globl prom_cif_direct
prom_cif_direct:
sethi %hi(p1275buf), %o1
or %o1, %lo(p1275buf), %o1
ldx [%o1 + 0x0010], %o2 ! prom_cif_stack
save %o2, -192, %sp
ldx [%i1 + 0x0008], %l2 ! prom_cif_handler
mov %g4, %l0
mov %g5, %l1
mov %g6, %l3
call %l2
add %i0, 0x018, %o0 ! prom_args
mov %i0, %o0 ! prom_args
mov %l0, %g4
mov %l1, %g5
mov %l3, %g6

View File

@ -21,14 +21,22 @@ extern int prom_stdin, prom_stdout;
inline int
prom_nbgetchar(void)
{
unsigned long args[7];
char inc;
if (p1275_cmd("read", P1275_ARG(1,P1275_ARG_OUT_BUF)|
P1275_INOUT(3,1),
prom_stdin, &inc, P1275_SIZE(1)) == 1)
args[0] = (unsigned long) "read";
args[1] = 3;
args[2] = 1;
args[3] = (unsigned int) prom_stdin;
args[4] = (unsigned long) &inc;
args[5] = 1;
args[6] = (unsigned long) -1;
p1275_cmd_direct(args);
if (args[6] == 1)
return inc;
else
return -1;
return -1;
}
/* Non blocking put character to console device, returns -1 if
@ -37,12 +45,22 @@ prom_nbgetchar(void)
inline int
prom_nbputchar(char c)
{
unsigned long args[7];
char outc;
outc = c;
if (p1275_cmd("write", P1275_ARG(1,P1275_ARG_IN_BUF)|
P1275_INOUT(3,1),
prom_stdout, &outc, P1275_SIZE(1)) == 1)
args[0] = (unsigned long) "write";
args[1] = 3;
args[2] = 1;
args[3] = (unsigned int) prom_stdout;
args[4] = (unsigned long) &outc;
args[5] = 1;
args[6] = (unsigned long) -1;
p1275_cmd_direct(args);
if (args[6] == 1)
return 0;
else
return -1;
@ -67,7 +85,15 @@ prom_putchar(char c)
void
prom_puts(const char *s, int len)
{
p1275_cmd("write", P1275_ARG(1,P1275_ARG_IN_BUF)|
P1275_INOUT(3,1),
prom_stdout, s, P1275_SIZE(len));
unsigned long args[7];
args[0] = (unsigned long) "write";
args[1] = 3;
args[2] = 1;
args[3] = (unsigned int) prom_stdout;
args[4] = (unsigned long) s;
args[5] = len;
args[6] = (unsigned long) -1;
p1275_cmd_direct(args);
}

View File

@ -18,16 +18,32 @@
int
prom_devopen(const char *dstr)
{
return p1275_cmd ("open", P1275_ARG(0,P1275_ARG_IN_STRING)|
P1275_INOUT(1,1),
dstr);
unsigned long args[5];
args[0] = (unsigned long) "open";
args[1] = 1;
args[2] = 1;
args[3] = (unsigned long) dstr;
args[4] = (unsigned long) -1;
p1275_cmd_direct(args);
return (int) args[4];
}
/* Close the device described by device handle 'dhandle'. */
int
prom_devclose(int dhandle)
{
p1275_cmd ("close", P1275_INOUT(1,0), dhandle);
unsigned long args[4];
args[0] = (unsigned long) "close";
args[1] = 1;
args[2] = 0;
args[3] = (unsigned int) dhandle;
p1275_cmd_direct(args);
return 0;
}
@ -37,5 +53,15 @@ prom_devclose(int dhandle)
void
prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo)
{
p1275_cmd ("seek", P1275_INOUT(3,1), dhandle, seekhi, seeklo);
unsigned long args[7];
args[0] = (unsigned long) "seek";
args[1] = 3;
args[2] = 1;
args[3] = (unsigned int) dhandle;
args[4] = seekhi;
args[5] = seeklo;
args[6] = (unsigned long) -1;
p1275_cmd_direct(args);
}

View File

@ -20,10 +20,17 @@
int prom_service_exists(const char *service_name)
{
int err = p1275_cmd("test", P1275_ARG(0, P1275_ARG_IN_STRING) |
P1275_INOUT(1, 1), service_name);
unsigned long args[5];
if (err)
args[0] = (unsigned long) "test";
args[1] = 1;
args[2] = 1;
args[3] = (unsigned long) service_name;
args[4] = (unsigned long) -1;
p1275_cmd_direct(args);
if (args[4])
return 0;
return 1;
}
@ -31,30 +38,47 @@ int prom_service_exists(const char *service_name)
void prom_sun4v_guest_soft_state(void)
{
const char *svc = "SUNW,soft-state-supported";
unsigned long args[3];
if (!prom_service_exists(svc))
return;
p1275_cmd(svc, P1275_INOUT(0, 0));
args[0] = (unsigned long) svc;
args[1] = 0;
args[2] = 0;
p1275_cmd_direct(args);
}
/* Reset and reboot the machine with the command 'bcommand'. */
void prom_reboot(const char *bcommand)
{
unsigned long args[4];
#ifdef CONFIG_SUN_LDOMS
if (ldom_domaining_enabled)
ldom_reboot(bcommand);
#endif
p1275_cmd("boot", P1275_ARG(0, P1275_ARG_IN_STRING) |
P1275_INOUT(1, 0), bcommand);
args[0] = (unsigned long) "boot";
args[1] = 1;
args[2] = 0;
args[3] = (unsigned long) bcommand;
p1275_cmd_direct(args);
}
/* Forth evaluate the expression contained in 'fstring'. */
void prom_feval(const char *fstring)
{
unsigned long args[5];
if (!fstring || fstring[0] == 0)
return;
p1275_cmd("interpret", P1275_ARG(0, P1275_ARG_IN_STRING) |
P1275_INOUT(1, 1), fstring);
args[0] = (unsigned long) "interpret";
args[1] = 1;
args[2] = 1;
args[3] = (unsigned long) fstring;
args[4] = (unsigned long) -1;
p1275_cmd_direct(args);
}
EXPORT_SYMBOL(prom_feval);
@ -68,6 +92,7 @@ extern void smp_release(void);
*/
void prom_cmdline(void)
{
unsigned long args[3];
unsigned long flags;
local_irq_save(flags);
@ -76,7 +101,11 @@ void prom_cmdline(void)
smp_capture();
#endif
p1275_cmd("enter", P1275_INOUT(0, 0));
args[0] = (unsigned long) "enter";
args[1] = 0;
args[2] = 0;
p1275_cmd_direct(args);
#ifdef CONFIG_SMP
smp_release();
@ -90,22 +119,32 @@ void prom_cmdline(void)
*/
void notrace prom_halt(void)
{
unsigned long args[3];
#ifdef CONFIG_SUN_LDOMS
if (ldom_domaining_enabled)
ldom_power_off();
#endif
again:
p1275_cmd("exit", P1275_INOUT(0, 0));
args[0] = (unsigned long) "exit";
args[1] = 0;
args[2] = 0;
p1275_cmd_direct(args);
goto again; /* PROM is out to get me -DaveM */
}
void prom_halt_power_off(void)
{
unsigned long args[3];
#ifdef CONFIG_SUN_LDOMS
if (ldom_domaining_enabled)
ldom_power_off();
#endif
p1275_cmd("SUNW,power-off", P1275_INOUT(0, 0));
args[0] = (unsigned long) "SUNW,power-off";
args[1] = 0;
args[2] = 0;
p1275_cmd_direct(args);
/* if nothing else helps, we just halt */
prom_halt();
@ -114,10 +153,15 @@ void prom_halt_power_off(void)
/* Set prom sync handler to call function 'funcp'. */
void prom_setcallback(callback_func_t funcp)
{
unsigned long args[5];
if (!funcp)
return;
p1275_cmd("set-callback", P1275_ARG(0, P1275_ARG_IN_FUNCTION) |
P1275_INOUT(1, 1), funcp);
args[0] = (unsigned long) "set-callback";
args[1] = 1;
args[2] = 1;
args[3] = (unsigned long) funcp;
args[4] = (unsigned long) -1;
p1275_cmd_direct(args);
}
/* Get the idprom and stuff it into buffer 'idbuf'. Returns the
@ -173,57 +217,61 @@ static int prom_get_memory_ihandle(void)
}
/* Load explicit I/D TLB entries. */
static long tlb_load(const char *type, unsigned long index,
unsigned long tte_data, unsigned long vaddr)
{
unsigned long args[9];
args[0] = (unsigned long) prom_callmethod_name;
args[1] = 5;
args[2] = 1;
args[3] = (unsigned long) type;
args[4] = (unsigned int) prom_get_mmu_ihandle();
args[5] = vaddr;
args[6] = tte_data;
args[7] = index;
args[8] = (unsigned long) -1;
p1275_cmd_direct(args);
return (long) args[8];
}
long prom_itlb_load(unsigned long index,
unsigned long tte_data,
unsigned long vaddr)
{
return p1275_cmd(prom_callmethod_name,
(P1275_ARG(0, P1275_ARG_IN_STRING) |
P1275_ARG(2, P1275_ARG_IN_64B) |
P1275_ARG(3, P1275_ARG_IN_64B) |
P1275_INOUT(5, 1)),
"SUNW,itlb-load",
prom_get_mmu_ihandle(),
/* And then our actual args are pushed backwards. */
vaddr,
tte_data,
index);
return tlb_load("SUNW,itlb-load", index, tte_data, vaddr);
}
long prom_dtlb_load(unsigned long index,
unsigned long tte_data,
unsigned long vaddr)
{
return p1275_cmd(prom_callmethod_name,
(P1275_ARG(0, P1275_ARG_IN_STRING) |
P1275_ARG(2, P1275_ARG_IN_64B) |
P1275_ARG(3, P1275_ARG_IN_64B) |
P1275_INOUT(5, 1)),
"SUNW,dtlb-load",
prom_get_mmu_ihandle(),
/* And then our actual args are pushed backwards. */
vaddr,
tte_data,
index);
return tlb_load("SUNW,dtlb-load", index, tte_data, vaddr);
}
int prom_map(int mode, unsigned long size,
unsigned long vaddr, unsigned long paddr)
{
int ret = p1275_cmd(prom_callmethod_name,
(P1275_ARG(0, P1275_ARG_IN_STRING) |
P1275_ARG(3, P1275_ARG_IN_64B) |
P1275_ARG(4, P1275_ARG_IN_64B) |
P1275_ARG(6, P1275_ARG_IN_64B) |
P1275_INOUT(7, 1)),
prom_map_name,
prom_get_mmu_ihandle(),
mode,
size,
vaddr,
0,
paddr);
unsigned long args[11];
int ret;
args[0] = (unsigned long) prom_callmethod_name;
args[1] = 7;
args[2] = 1;
args[3] = (unsigned long) prom_map_name;
args[4] = (unsigned int) prom_get_mmu_ihandle();
args[5] = (unsigned int) mode;
args[6] = size;
args[7] = vaddr;
args[8] = 0;
args[9] = paddr;
args[10] = (unsigned long) -1;
p1275_cmd_direct(args);
ret = (int) args[10];
if (ret == 0)
ret = -1;
return ret;
@ -231,40 +279,51 @@ int prom_map(int mode, unsigned long size,
void prom_unmap(unsigned long size, unsigned long vaddr)
{
p1275_cmd(prom_callmethod_name,
(P1275_ARG(0, P1275_ARG_IN_STRING) |
P1275_ARG(2, P1275_ARG_IN_64B) |
P1275_ARG(3, P1275_ARG_IN_64B) |
P1275_INOUT(4, 0)),
prom_unmap_name,
prom_get_mmu_ihandle(),
size,
vaddr);
unsigned long args[7];
args[0] = (unsigned long) prom_callmethod_name;
args[1] = 4;
args[2] = 0;
args[3] = (unsigned long) prom_unmap_name;
args[4] = (unsigned int) prom_get_mmu_ihandle();
args[5] = size;
args[6] = vaddr;
p1275_cmd_direct(args);
}
/* Set aside physical memory which is not touched or modified
* across soft resets.
*/
unsigned long prom_retain(const char *name,
unsigned long pa_low, unsigned long pa_high,
long size, long align)
int prom_retain(const char *name, unsigned long size,
unsigned long align, unsigned long *paddr)
{
/* XXX I don't think we return multiple values correctly.
* XXX OBP supposedly returns pa_low/pa_high here, how does
* XXX it work?
*/
unsigned long args[11];
/* If align is zero, the pa_low/pa_high args are passed,
* else they are not.
args[0] = (unsigned long) prom_callmethod_name;
args[1] = 5;
args[2] = 3;
args[3] = (unsigned long) "SUNW,retain";
args[4] = (unsigned int) prom_get_memory_ihandle();
args[5] = align;
args[6] = size;
args[7] = (unsigned long) name;
args[8] = (unsigned long) -1;
args[9] = (unsigned long) -1;
args[10] = (unsigned long) -1;
p1275_cmd_direct(args);
if (args[8])
return (int) args[8];
/* Next we get "phys_high" then "phys_low". On 64-bit
* the phys_high cell is don't care since the phys_low
* cell has the full value.
*/
if (align == 0)
return p1275_cmd("SUNW,retain",
(P1275_ARG(0, P1275_ARG_IN_BUF) | P1275_INOUT(5, 2)),
name, pa_low, pa_high, size, align);
else
return p1275_cmd("SUNW,retain",
(P1275_ARG(0, P1275_ARG_IN_BUF) | P1275_INOUT(3, 2)),
name, size, align);
*paddr = args[10];
return 0;
}
/* Get "Unumber" string for the SIMM at the given
@ -277,62 +336,129 @@ int prom_getunumber(int syndrome_code,
unsigned long phys_addr,
char *buf, int buflen)
{
return p1275_cmd(prom_callmethod_name,
(P1275_ARG(0, P1275_ARG_IN_STRING) |
P1275_ARG(3, P1275_ARG_OUT_BUF) |
P1275_ARG(6, P1275_ARG_IN_64B) |
P1275_INOUT(8, 2)),
"SUNW,get-unumber", prom_get_memory_ihandle(),
buflen, buf, P1275_SIZE(buflen),
0, phys_addr, syndrome_code);
unsigned long args[12];
args[0] = (unsigned long) prom_callmethod_name;
args[1] = 7;
args[2] = 2;
args[3] = (unsigned long) "SUNW,get-unumber";
args[4] = (unsigned int) prom_get_memory_ihandle();
args[5] = buflen;
args[6] = (unsigned long) buf;
args[7] = 0;
args[8] = phys_addr;
args[9] = (unsigned int) syndrome_code;
args[10] = (unsigned long) -1;
args[11] = (unsigned long) -1;
p1275_cmd_direct(args);
return (int) args[10];
}
/* Power management extensions. */
void prom_sleepself(void)
{
p1275_cmd("SUNW,sleep-self", P1275_INOUT(0, 0));
unsigned long args[3];
args[0] = (unsigned long) "SUNW,sleep-self";
args[1] = 0;
args[2] = 0;
p1275_cmd_direct(args);
}
int prom_sleepsystem(void)
{
return p1275_cmd("SUNW,sleep-system", P1275_INOUT(0, 1));
unsigned long args[4];
args[0] = (unsigned long) "SUNW,sleep-system";
args[1] = 0;
args[2] = 1;
args[3] = (unsigned long) -1;
p1275_cmd_direct(args);
return (int) args[3];
}
int prom_wakeupsystem(void)
{
return p1275_cmd("SUNW,wakeup-system", P1275_INOUT(0, 1));
unsigned long args[4];
args[0] = (unsigned long) "SUNW,wakeup-system";
args[1] = 0;
args[2] = 1;
args[3] = (unsigned long) -1;
p1275_cmd_direct(args);
return (int) args[3];
}
#ifdef CONFIG_SMP
void prom_startcpu(int cpunode, unsigned long pc, unsigned long arg)
{
p1275_cmd("SUNW,start-cpu", P1275_INOUT(3, 0), cpunode, pc, arg);
unsigned long args[6];
args[0] = (unsigned long) "SUNW,start-cpu";
args[1] = 3;
args[2] = 0;
args[3] = (unsigned int) cpunode;
args[4] = pc;
args[5] = arg;
p1275_cmd_direct(args);
}
void prom_startcpu_cpuid(int cpuid, unsigned long pc, unsigned long arg)
{
p1275_cmd("SUNW,start-cpu-by-cpuid", P1275_INOUT(3, 0),
cpuid, pc, arg);
unsigned long args[6];
args[0] = (unsigned long) "SUNW,start-cpu-by-cpuid";
args[1] = 3;
args[2] = 0;
args[3] = (unsigned int) cpuid;
args[4] = pc;
args[5] = arg;
p1275_cmd_direct(args);
}
void prom_stopcpu_cpuid(int cpuid)
{
p1275_cmd("SUNW,stop-cpu-by-cpuid", P1275_INOUT(1, 0),
cpuid);
unsigned long args[4];
args[0] = (unsigned long) "SUNW,stop-cpu-by-cpuid";
args[1] = 1;
args[2] = 0;
args[3] = (unsigned int) cpuid;
p1275_cmd_direct(args);
}
void prom_stopself(void)
{
p1275_cmd("SUNW,stop-self", P1275_INOUT(0, 0));
unsigned long args[3];
args[0] = (unsigned long) "SUNW,stop-self";
args[1] = 0;
args[2] = 0;
p1275_cmd_direct(args);
}
void prom_idleself(void)
{
p1275_cmd("SUNW,idle-self", P1275_INOUT(0, 0));
unsigned long args[3];
args[0] = (unsigned long) "SUNW,idle-self";
args[1] = 0;
args[2] = 0;
p1275_cmd_direct(args);
}
void prom_resumecpu(int cpunode)
{
p1275_cmd("SUNW,resume-cpu", P1275_INOUT(1, 0), cpunode);
unsigned long args[4];
args[0] = (unsigned long) "SUNW,resume-cpu";
args[1] = 1;
args[2] = 0;
args[3] = (unsigned int) cpunode;
p1275_cmd_direct(args);
}
#endif

View File

@ -22,13 +22,11 @@ struct {
long prom_callback; /* 0x00 */
void (*prom_cif_handler)(long *); /* 0x08 */
unsigned long prom_cif_stack; /* 0x10 */
unsigned long prom_args [23]; /* 0x18 */
char prom_buffer [3000];
} p1275buf;
extern void prom_world(int);
extern void prom_cif_interface(void);
extern void prom_cif_direct(unsigned long *args);
extern void prom_cif_callback(void);
/*
@ -36,114 +34,20 @@ extern void prom_cif_callback(void);
*/
DEFINE_RAW_SPINLOCK(prom_entry_lock);
long p1275_cmd(const char *service, long fmt, ...)
void p1275_cmd_direct(unsigned long *args)
{
char *p, *q;
unsigned long flags;
int nargs, nrets, i;
va_list list;
long attrs, x;
p = p1275buf.prom_buffer;
raw_local_save_flags(flags);
raw_local_irq_restore(PIL_NMI);
raw_spin_lock(&prom_entry_lock);
p1275buf.prom_args[0] = (unsigned long)p; /* service */
strcpy (p, service);
p = (char *)(((long)(strchr (p, 0) + 8)) & ~7);
p1275buf.prom_args[1] = nargs = (fmt & 0x0f); /* nargs */
p1275buf.prom_args[2] = nrets = ((fmt & 0xf0) >> 4); /* nrets */
attrs = fmt >> 8;
va_start(list, fmt);
for (i = 0; i < nargs; i++, attrs >>= 3) {
switch (attrs & 0x7) {
case P1275_ARG_NUMBER:
p1275buf.prom_args[i + 3] =
(unsigned)va_arg(list, long);
break;
case P1275_ARG_IN_64B:
p1275buf.prom_args[i + 3] =
va_arg(list, unsigned long);
break;
case P1275_ARG_IN_STRING:
strcpy (p, va_arg(list, char *));
p1275buf.prom_args[i + 3] = (unsigned long)p;
p = (char *)(((long)(strchr (p, 0) + 8)) & ~7);
break;
case P1275_ARG_OUT_BUF:
(void) va_arg(list, char *);
p1275buf.prom_args[i + 3] = (unsigned long)p;
x = va_arg(list, long);
i++; attrs >>= 3;
p = (char *)(((long)(p + (int)x + 7)) & ~7);
p1275buf.prom_args[i + 3] = x;
break;
case P1275_ARG_IN_BUF:
q = va_arg(list, char *);
p1275buf.prom_args[i + 3] = (unsigned long)p;
x = va_arg(list, long);
i++; attrs >>= 3;
memcpy (p, q, (int)x);
p = (char *)(((long)(p + (int)x + 7)) & ~7);
p1275buf.prom_args[i + 3] = x;
break;
case P1275_ARG_OUT_32B:
(void) va_arg(list, char *);
p1275buf.prom_args[i + 3] = (unsigned long)p;
p += 32;
break;
case P1275_ARG_IN_FUNCTION:
p1275buf.prom_args[i + 3] =
(unsigned long)prom_cif_callback;
p1275buf.prom_callback = va_arg(list, long);
break;
}
}
va_end(list);
prom_world(1);
prom_cif_interface();
prom_cif_direct(args);
prom_world(0);
attrs = fmt >> 8;
va_start(list, fmt);
for (i = 0; i < nargs; i++, attrs >>= 3) {
switch (attrs & 0x7) {
case P1275_ARG_NUMBER:
(void) va_arg(list, long);
break;
case P1275_ARG_IN_STRING:
(void) va_arg(list, char *);
break;
case P1275_ARG_IN_FUNCTION:
(void) va_arg(list, long);
break;
case P1275_ARG_IN_BUF:
(void) va_arg(list, char *);
(void) va_arg(list, long);
i++; attrs >>= 3;
break;
case P1275_ARG_OUT_BUF:
p = va_arg(list, char *);
x = va_arg(list, long);
memcpy (p, (char *)(p1275buf.prom_args[i + 3]), (int)x);
i++; attrs >>= 3;
break;
case P1275_ARG_OUT_32B:
p = va_arg(list, char *);
memcpy (p, (char *)(p1275buf.prom_args[i + 3]), 32);
break;
}
}
va_end(list);
x = p1275buf.prom_args [nargs + 3];
raw_spin_unlock(&prom_entry_lock);
raw_local_irq_restore(flags);
return x;
}
void prom_cif_init(void *cif_handler, void *cif_stack)

View File

@ -16,22 +16,39 @@
#include <asm/oplib.h>
#include <asm/ldc.h>
static int prom_node_to_node(const char *type, int node)
{
unsigned long args[5];
args[0] = (unsigned long) type;
args[1] = 1;
args[2] = 1;
args[3] = (unsigned int) node;
args[4] = (unsigned long) -1;
p1275_cmd_direct(args);
return (int) args[4];
}
/* Return the child of node 'node' or zero if no this node has no
* direct descendent.
*/
inline int __prom_getchild(int node)
{
return p1275_cmd ("child", P1275_INOUT(1, 1), node);
return prom_node_to_node("child", node);
}
inline int prom_getchild(int node)
{
int cnode;
if(node == -1) return 0;
if (node == -1)
return 0;
cnode = __prom_getchild(node);
if(cnode == -1) return 0;
return (int)cnode;
if (cnode == -1)
return 0;
return cnode;
}
EXPORT_SYMBOL(prom_getchild);
@ -39,10 +56,12 @@ inline int prom_getparent(int node)
{
int cnode;
if(node == -1) return 0;
cnode = p1275_cmd ("parent", P1275_INOUT(1, 1), node);
if(cnode == -1) return 0;
return (int)cnode;
if (node == -1)
return 0;
cnode = prom_node_to_node("parent", node);
if (cnode == -1)
return 0;
return cnode;
}
/* Return the next sibling of node 'node' or zero if no more siblings
@ -50,7 +69,7 @@ inline int prom_getparent(int node)
*/
inline int __prom_getsibling(int node)
{
return p1275_cmd(prom_peer_name, P1275_INOUT(1, 1), node);
return prom_node_to_node(prom_peer_name, node);
}
inline int prom_getsibling(int node)
@ -72,11 +91,21 @@ EXPORT_SYMBOL(prom_getsibling);
*/
inline int prom_getproplen(int node, const char *prop)
{
if((!node) || (!prop)) return -1;
return p1275_cmd ("getproplen",
P1275_ARG(1,P1275_ARG_IN_STRING)|
P1275_INOUT(2, 1),
node, prop);
unsigned long args[6];
if (!node || !prop)
return -1;
args[0] = (unsigned long) "getproplen";
args[1] = 2;
args[2] = 1;
args[3] = (unsigned int) node;
args[4] = (unsigned long) prop;
args[5] = (unsigned long) -1;
p1275_cmd_direct(args);
return (int) args[5];
}
EXPORT_SYMBOL(prom_getproplen);
@ -87,19 +116,25 @@ EXPORT_SYMBOL(prom_getproplen);
inline int prom_getproperty(int node, const char *prop,
char *buffer, int bufsize)
{
unsigned long args[8];
int plen;
plen = prom_getproplen(node, prop);
if ((plen > bufsize) || (plen == 0) || (plen == -1)) {
if ((plen > bufsize) || (plen == 0) || (plen == -1))
return -1;
} else {
/* Ok, things seem all right. */
return p1275_cmd(prom_getprop_name,
P1275_ARG(1,P1275_ARG_IN_STRING)|
P1275_ARG(2,P1275_ARG_OUT_BUF)|
P1275_INOUT(4, 1),
node, prop, buffer, P1275_SIZE(plen));
}
args[0] = (unsigned long) prom_getprop_name;
args[1] = 4;
args[2] = 1;
args[3] = (unsigned int) node;
args[4] = (unsigned long) prop;
args[5] = (unsigned long) buffer;
args[6] = bufsize;
args[7] = (unsigned long) -1;
p1275_cmd_direct(args);
return (int) args[7];
}
EXPORT_SYMBOL(prom_getproperty);
@ -110,7 +145,7 @@ inline int prom_getint(int node, const char *prop)
{
int intprop;
if(prom_getproperty(node, prop, (char *) &intprop, sizeof(int)) != -1)
if (prom_getproperty(node, prop, (char *) &intprop, sizeof(int)) != -1)
return intprop;
return -1;
@ -126,7 +161,8 @@ int prom_getintdefault(int node, const char *property, int deflt)
int retval;
retval = prom_getint(node, property);
if(retval == -1) return deflt;
if (retval == -1)
return deflt;
return retval;
}
@ -138,7 +174,8 @@ int prom_getbool(int node, const char *prop)
int retval;
retval = prom_getproplen(node, prop);
if(retval == -1) return 0;
if (retval == -1)
return 0;
return 1;
}
EXPORT_SYMBOL(prom_getbool);
@ -152,7 +189,8 @@ void prom_getstring(int node, const char *prop, char *user_buf, int ubuf_size)
int len;
len = prom_getproperty(node, prop, user_buf, ubuf_size);
if(len != -1) return;
if (len != -1)
return;
user_buf[0] = 0;
}
EXPORT_SYMBOL(prom_getstring);
@ -164,7 +202,8 @@ int prom_nodematch(int node, const char *name)
{
char namebuf[128];
prom_getproperty(node, "name", namebuf, sizeof(namebuf));
if(strcmp(namebuf, name) == 0) return 1;
if (strcmp(namebuf, name) == 0)
return 1;
return 0;
}
@ -190,16 +229,29 @@ int prom_searchsiblings(int node_start, const char *nodename)
}
EXPORT_SYMBOL(prom_searchsiblings);
static const char *prom_nextprop_name = "nextprop";
/* Return the first property type for node 'node'.
* buffer should be at least 32B in length
*/
inline char *prom_firstprop(int node, char *buffer)
{
unsigned long args[7];
*buffer = 0;
if(node == -1) return buffer;
p1275_cmd ("nextprop", P1275_ARG(2,P1275_ARG_OUT_32B)|
P1275_INOUT(3, 0),
node, (char *) 0x0, buffer);
if (node == -1)
return buffer;
args[0] = (unsigned long) prom_nextprop_name;
args[1] = 3;
args[2] = 1;
args[3] = (unsigned int) node;
args[4] = 0;
args[5] = (unsigned long) buffer;
args[6] = (unsigned long) -1;
p1275_cmd_direct(args);
return buffer;
}
EXPORT_SYMBOL(prom_firstprop);
@ -210,9 +262,10 @@ EXPORT_SYMBOL(prom_firstprop);
*/
inline char *prom_nextprop(int node, const char *oprop, char *buffer)
{
unsigned long args[7];
char buf[32];
if(node == -1) {
if (node == -1) {
*buffer = 0;
return buffer;
}
@ -220,10 +273,17 @@ inline char *prom_nextprop(int node, const char *oprop, char *buffer)
strcpy (buf, oprop);
oprop = buf;
}
p1275_cmd ("nextprop", P1275_ARG(1,P1275_ARG_IN_STRING)|
P1275_ARG(2,P1275_ARG_OUT_32B)|
P1275_INOUT(3, 0),
node, oprop, buffer);
args[0] = (unsigned long) prom_nextprop_name;
args[1] = 3;
args[2] = 1;
args[3] = (unsigned int) node;
args[4] = (unsigned long) oprop;
args[5] = (unsigned long) buffer;
args[6] = (unsigned long) -1;
p1275_cmd_direct(args);
return buffer;
}
EXPORT_SYMBOL(prom_nextprop);
@ -231,12 +291,19 @@ EXPORT_SYMBOL(prom_nextprop);
int
prom_finddevice(const char *name)
{
unsigned long args[5];
if (!name)
return 0;
return p1275_cmd(prom_finddev_name,
P1275_ARG(0,P1275_ARG_IN_STRING)|
P1275_INOUT(1, 1),
name);
args[0] = (unsigned long) "finddevice";
args[1] = 1;
args[2] = 1;
args[3] = (unsigned long) name;
args[4] = (unsigned long) -1;
p1275_cmd_direct(args);
return (int) args[4];
}
EXPORT_SYMBOL(prom_finddevice);
@ -247,7 +314,7 @@ int prom_node_has_property(int node, const char *prop)
*buf = 0;
do {
prom_nextprop(node, buf, buf);
if(!strcmp(buf, prop))
if (!strcmp(buf, prop))
return 1;
} while (*buf);
return 0;
@ -260,6 +327,8 @@ EXPORT_SYMBOL(prom_node_has_property);
int
prom_setprop(int node, const char *pname, char *value, int size)
{
unsigned long args[8];
if (size == 0)
return 0;
if ((pname == 0) || (value == 0))
@ -271,19 +340,37 @@ prom_setprop(int node, const char *pname, char *value, int size)
return 0;
}
#endif
return p1275_cmd ("setprop", P1275_ARG(1,P1275_ARG_IN_STRING)|
P1275_ARG(2,P1275_ARG_IN_BUF)|
P1275_INOUT(4, 1),
node, pname, value, P1275_SIZE(size));
args[0] = (unsigned long) "setprop";
args[1] = 4;
args[2] = 1;
args[3] = (unsigned int) node;
args[4] = (unsigned long) pname;
args[5] = (unsigned long) value;
args[6] = size;
args[7] = (unsigned long) -1;
p1275_cmd_direct(args);
return (int) args[7];
}
EXPORT_SYMBOL(prom_setprop);
inline int prom_inst2pkg(int inst)
{
unsigned long args[5];
int node;
node = p1275_cmd ("instance-to-package", P1275_INOUT(1, 1), inst);
if (node == -1) return 0;
args[0] = (unsigned long) "instance-to-package";
args[1] = 1;
args[2] = 1;
args[3] = (unsigned int) inst;
args[4] = (unsigned long) -1;
p1275_cmd_direct(args);
node = (int) args[4];
if (node == -1)
return 0;
return node;
}
@ -296,17 +383,28 @@ prom_pathtoinode(const char *path)
int node, inst;
inst = prom_devopen (path);
if (inst == 0) return 0;
node = prom_inst2pkg (inst);
prom_devclose (inst);
if (node == -1) return 0;
if (inst == 0)
return 0;
node = prom_inst2pkg(inst);
prom_devclose(inst);
if (node == -1)
return 0;
return node;
}
int prom_ihandle2path(int handle, char *buffer, int bufsize)
{
return p1275_cmd("instance-to-path",
P1275_ARG(1,P1275_ARG_OUT_BUF)|
P1275_INOUT(3, 1),
handle, buffer, P1275_SIZE(bufsize));
unsigned long args[7];
args[0] = (unsigned long) "instance-to-path";
args[1] = 3;
args[2] = 1;
args[3] = (unsigned int) handle;
args[4] = (unsigned long) buffer;
args[5] = bufsize;
args[6] = (unsigned long) -1;
p1275_cmd_direct(args);
return (int) args[6];
}

View File

@ -59,5 +59,7 @@ extern void check_tsc_sync_source(int cpu);
extern void check_tsc_sync_target(void);
extern int notsc_setup(char *);
extern void save_sched_clock_state(void);
extern void restore_sched_clock_state(void);
#endif /* _ASM_X86_TSC_H */

View File

@ -497,6 +497,8 @@ static int p4_hw_config(struct perf_event *event)
event->hw.config |= event->attr.config &
(p4_config_pack_escr(P4_ESCR_MASK_HT) |
p4_config_pack_cccr(P4_CCCR_MASK_HT | P4_CCCR_RESERVED));
event->hw.config &= ~P4_CCCR_FORCE_OVF;
}
rc = x86_setup_perfctr(event);

View File

@ -626,6 +626,44 @@ static void set_cyc2ns_scale(unsigned long cpu_khz, int cpu)
local_irq_restore(flags);
}
static unsigned long long cyc2ns_suspend;
void save_sched_clock_state(void)
{
if (!sched_clock_stable)
return;
cyc2ns_suspend = sched_clock();
}
/*
* Even on processors with invariant TSC, TSC gets reset in some the
* ACPI system sleep states. And in some systems BIOS seem to reinit TSC to
* arbitrary value (still sync'd across cpu's) during resume from such sleep
* states. To cope up with this, recompute the cyc2ns_offset for each cpu so
* that sched_clock() continues from the point where it was left off during
* suspend.
*/
void restore_sched_clock_state(void)
{
unsigned long long offset;
unsigned long flags;
int cpu;
if (!sched_clock_stable)
return;
local_irq_save(flags);
get_cpu_var(cyc2ns_offset) = 0;
offset = cyc2ns_suspend - sched_clock();
for_each_possible_cpu(cpu)
per_cpu(cyc2ns_offset, cpu) = offset;
local_irq_restore(flags);
}
#ifdef CONFIG_CPU_FREQ
/* Frequency scaling support. Adjust the TSC based timer when the cpu frequency

View File

@ -113,6 +113,7 @@ static void __save_processor_state(struct saved_context *ctxt)
void save_processor_state(void)
{
__save_processor_state(&saved_context);
save_sched_clock_state();
}
#ifdef CONFIG_X86_32
EXPORT_SYMBOL(save_processor_state);
@ -229,6 +230,7 @@ static void __restore_processor_state(struct saved_context *ctxt)
void restore_processor_state(void)
{
__restore_processor_state(&saved_context);
restore_sched_clock_state();
}
#ifdef CONFIG_X86_32
EXPORT_SYMBOL(restore_processor_state);

View File

@ -568,7 +568,7 @@ static int _request_firmware(const struct firmware **firmware_p,
out:
if (retval) {
release_firmware(firmware);
firmware_p = NULL;
*firmware_p = NULL;
}
return retval;

View File

@ -1650,7 +1650,7 @@ ip2_close( PTTY tty, struct file *pFile )
/* disable DSS reporting */
i2QueueCommands(PTYPE_INLINE, pCh, 100, 4,
CMD_DCD_NREP, CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP);
if ( !tty || (tty->termios->c_cflag & HUPCL) ) {
if (tty->termios->c_cflag & HUPCL) {
i2QueueCommands(PTYPE_INLINE, pCh, 100, 2, CMD_RTSDN, CMD_DTRDN);
pCh->dataSetOut &= ~(I2_DTR | I2_RTS);
i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25));
@ -2930,6 +2930,8 @@ ip2_ipl_ioctl (struct file *pFile, UINT cmd, ULONG arg )
if ( pCh )
{
rc = copy_to_user(argp, pCh, sizeof(i2ChanStr));
if (rc)
rc = -EFAULT;
} else {
rc = -ENODEV;
}

View File

@ -1244,6 +1244,7 @@ static int set_config(struct tty_struct *tty, struct r_port *info,
}
info->flags = ((info->flags & ~ROCKET_USR_MASK) | (new_serial.flags & ROCKET_USR_MASK));
configure_r_port(tty, info, NULL);
mutex_unlock(&info->port.mutex);
return 0;
}

View File

@ -691,8 +691,10 @@ static int open(struct tty_struct *tty, struct file *filp)
if (info->port.count == 1) {
/* 1st open on this device, init hardware */
retval = startup(info);
if (retval < 0)
if (retval < 0) {
mutex_unlock(&info->port.mutex);
goto cleanup;
}
}
mutex_unlock(&info->port.mutex);
retval = block_til_ready(tty, filp, info);

View File

@ -992,7 +992,7 @@ void intel_wait_for_vblank(struct drm_device *dev, int pipe)
/* Wait for vblank interrupt bit to set */
if (wait_for((I915_READ(pipestat_reg) &
PIPE_VBLANK_INTERRUPT_STATUS) == 0,
PIPE_VBLANK_INTERRUPT_STATUS),
50, 0))
DRM_DEBUG_KMS("vblank wait timed out\n");
}

View File

@ -160,30 +160,12 @@ static const struct attribute_group ads7871_group = {
static int __devinit ads7871_probe(struct spi_device *spi)
{
int status, ret, err = 0;
int ret, err;
uint8_t val;
struct ads7871_data *pdata;
dev_dbg(&spi->dev, "probe\n");
pdata = kzalloc(sizeof(struct ads7871_data), GFP_KERNEL);
if (!pdata) {
err = -ENOMEM;
goto exit;
}
status = sysfs_create_group(&spi->dev.kobj, &ads7871_group);
if (status < 0)
goto error_free;
pdata->hwmon_dev = hwmon_device_register(&spi->dev);
if (IS_ERR(pdata->hwmon_dev)) {
err = PTR_ERR(pdata->hwmon_dev);
goto error_remove;
}
spi_set_drvdata(spi, pdata);
/* Configure the SPI bus */
spi->mode = (SPI_MODE_0);
spi->bits_per_word = 8;
@ -201,6 +183,24 @@ static int __devinit ads7871_probe(struct spi_device *spi)
we need to make sure we really have a chip*/
if (val != ret) {
err = -ENODEV;
goto exit;
}
pdata = kzalloc(sizeof(struct ads7871_data), GFP_KERNEL);
if (!pdata) {
err = -ENOMEM;
goto exit;
}
err = sysfs_create_group(&spi->dev.kobj, &ads7871_group);
if (err < 0)
goto error_free;
spi_set_drvdata(spi, pdata);
pdata->hwmon_dev = hwmon_device_register(&spi->dev);
if (IS_ERR(pdata->hwmon_dev)) {
err = PTR_ERR(pdata->hwmon_dev);
goto error_remove;
}

View File

@ -518,7 +518,6 @@ static struct notifier_block coretemp_cpu_notifier __refdata = {
static int __init coretemp_init(void)
{
int i, err = -ENODEV;
struct pdev_entry *p, *n;
/* quick check if we run Intel */
if (cpu_data(0).x86_vendor != X86_VENDOR_INTEL)

View File

@ -143,6 +143,37 @@ static const struct pci_device_id k8temp_ids[] = {
MODULE_DEVICE_TABLE(pci, k8temp_ids);
static int __devinit is_rev_g_desktop(u8 model)
{
u32 brandidx;
if (model < 0x69)
return 0;
if (model == 0xc1 || model == 0x6c || model == 0x7c)
return 0;
/*
* Differentiate between AM2 and ASB1.
* See "Constructing the processor Name String" in "Revision
* Guide for AMD NPT Family 0Fh Processors" (33610).
*/
brandidx = cpuid_ebx(0x80000001);
brandidx = (brandidx >> 9) & 0x1f;
/* Single core */
if ((model == 0x6f || model == 0x7f) &&
(brandidx == 0x7 || brandidx == 0x9 || brandidx == 0xc))
return 0;
/* Dual core */
if (model == 0x6b &&
(brandidx == 0xb || brandidx == 0xc))
return 0;
return 1;
}
static int __devinit k8temp_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
@ -179,9 +210,7 @@ static int __devinit k8temp_probe(struct pci_dev *pdev,
"wrong - check erratum #141\n");
}
if ((model >= 0x69) &&
!(model == 0xc1 || model == 0x6c || model == 0x7c ||
model == 0x6b || model == 0x6f || model == 0x7f)) {
if (is_rev_g_desktop(model)) {
/*
* RevG desktop CPUs (i.e. no socket S1G1 or
* ASB1 parts) need additional offset,

View File

@ -45,6 +45,7 @@
#include <linux/syscalls.h>
#include <linux/suspend.h>
#include <linux/cpu.h>
#include <linux/compat.h>
#include <asm/prom.h>
#include <asm/machdep.h>
#include <asm/io.h>
@ -2349,11 +2350,52 @@ static long pmu_unlocked_ioctl(struct file *filp,
return ret;
}
#ifdef CONFIG_COMPAT
#define PMU_IOC_GET_BACKLIGHT32 _IOR('B', 1, compat_size_t)
#define PMU_IOC_SET_BACKLIGHT32 _IOW('B', 2, compat_size_t)
#define PMU_IOC_GET_MODEL32 _IOR('B', 3, compat_size_t)
#define PMU_IOC_HAS_ADB32 _IOR('B', 4, compat_size_t)
#define PMU_IOC_CAN_SLEEP32 _IOR('B', 5, compat_size_t)
#define PMU_IOC_GRAB_BACKLIGHT32 _IOR('B', 6, compat_size_t)
static long compat_pmu_ioctl (struct file *filp, u_int cmd, u_long arg)
{
switch (cmd) {
case PMU_IOC_SLEEP:
break;
case PMU_IOC_GET_BACKLIGHT32:
cmd = PMU_IOC_GET_BACKLIGHT;
break;
case PMU_IOC_SET_BACKLIGHT32:
cmd = PMU_IOC_SET_BACKLIGHT;
break;
case PMU_IOC_GET_MODEL32:
cmd = PMU_IOC_GET_MODEL;
break;
case PMU_IOC_HAS_ADB32:
cmd = PMU_IOC_HAS_ADB;
break;
case PMU_IOC_CAN_SLEEP32:
cmd = PMU_IOC_CAN_SLEEP;
break;
case PMU_IOC_GRAB_BACKLIGHT32:
cmd = PMU_IOC_GRAB_BACKLIGHT;
break;
default:
return -ENOIOCTLCMD;
}
return pmu_unlocked_ioctl(filp, cmd, (unsigned long)compat_ptr(arg));
}
#endif
static const struct file_operations pmu_device_fops = {
.read = pmu_read,
.write = pmu_write,
.poll = pmu_fpoll,
.unlocked_ioctl = pmu_unlocked_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = compat_pmu_ioctl,
#endif
.open = pmu_open,
.release = pmu_release,
};

View File

@ -1,6 +1,6 @@
config MANTIS_CORE
tristate "Mantis/Hopper PCI bridge based devices"
depends on PCI && I2C && INPUT
depends on PCI && I2C && INPUT && IR_CORE
help
Support for PCI cards based on the Mantis and Hopper PCi bridge.

View File

@ -145,7 +145,7 @@ static void free_rar_device(struct rar_device *rar)
*/
static struct rar_device *_rar_to_device(int rar, int *off)
{
if (rar >= 0 && rar <= 3) {
if (rar >= 0 && rar < MRST_NUM_RAR) {
*off = rar;
return &my_rar_device;
}

View File

@ -487,7 +487,7 @@ int intel_scu_ipc_i2c_cntrl(u32 addr, u32 *data)
mdelay(1);
*data = readl(ipcdev.i2c_base + I2C_DATA_ADDR);
} else if (cmd == IPC_I2C_WRITE) {
writel(addr, ipcdev.i2c_base + I2C_DATA_ADDR);
writel(*data, ipcdev.i2c_base + I2C_DATA_ADDR);
mdelay(1);
writel(addr, ipcdev.i2c_base + IPC_I2C_CNTRL_ADDR);
} else {

View File

@ -869,7 +869,9 @@ static int get_serial_info(struct m68k_serial * info,
tmp.close_delay = info->close_delay;
tmp.closing_wait = info->closing_wait;
tmp.custom_divisor = info->custom_divisor;
copy_to_user(retinfo,&tmp,sizeof(*retinfo));
if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
return -EFAULT;
return 0;
}
@ -882,7 +884,8 @@ static int set_serial_info(struct m68k_serial * info,
if (!new_info)
return -EFAULT;
copy_from_user(&new_serial,new_info,sizeof(new_serial));
if (copy_from_user(&new_serial, new_info, sizeof(new_serial)))
return -EFAULT;
old_info = *info;
if (!capable(CAP_SYS_ADMIN)) {
@ -943,8 +946,7 @@ static int get_lsr_info(struct m68k_serial * info, unsigned int *value)
status = 0;
#endif
local_irq_restore(flags);
put_user(status,value);
return 0;
return put_user(status, value);
}
/*
@ -999,27 +1001,18 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
send_break(info, arg ? arg*(100) : 250);
return 0;
case TIOCGSERIAL:
if (access_ok(VERIFY_WRITE, (void *) arg,
sizeof(struct serial_struct)))
return get_serial_info(info,
(struct serial_struct *) arg);
return -EFAULT;
return get_serial_info(info,
(struct serial_struct *) arg);
case TIOCSSERIAL:
return set_serial_info(info,
(struct serial_struct *) arg);
case TIOCSERGETLSR: /* Get line status register */
if (access_ok(VERIFY_WRITE, (void *) arg,
sizeof(unsigned int)))
return get_lsr_info(info, (unsigned int *) arg);
return -EFAULT;
return get_lsr_info(info, (unsigned int *) arg);
case TIOCSERGSTRUCT:
if (!access_ok(VERIFY_WRITE, (void *) arg,
sizeof(struct m68k_serial)))
if (copy_to_user((struct m68k_serial *) arg,
info, sizeof(struct m68k_serial)))
return -EFAULT;
copy_to_user((struct m68k_serial *) arg,
info, sizeof(struct m68k_serial));
return 0;
default:
return -ENOIOCTLCMD;
}

View File

@ -203,13 +203,13 @@ static int __init parse_options(struct early_serial8250_device *device,
if (mmio || mmio32)
printk(KERN_INFO
"Early serial console at MMIO%s 0x%llu (options '%s')\n",
"Early serial console at MMIO%s 0x%llx (options '%s')\n",
mmio32 ? "32" : "",
(unsigned long long)port->mapbase,
device->options);
else
printk(KERN_INFO
"Early serial console at I/O port 0x%lu (options '%s')\n",
"Early serial console at I/O port 0x%lx (options '%s')\n",
port->iobase,
device->options);

View File

@ -115,8 +115,6 @@ source "drivers/staging/vme/Kconfig"
source "drivers/staging/memrar/Kconfig"
source "drivers/staging/sep/Kconfig"
source "drivers/staging/iio/Kconfig"
source "drivers/staging/zram/Kconfig"

View File

@ -39,7 +39,6 @@ obj-$(CONFIG_FB_UDL) += udlfb/
obj-$(CONFIG_HYPERV) += hv/
obj-$(CONFIG_VME_BUS) += vme/
obj-$(CONFIG_MRST_RAR_HANDLER) += memrar/
obj-$(CONFIG_DX_SEP) += sep/
obj-$(CONFIG_IIO) += iio/
obj-$(CONFIG_ZRAM) += zram/
obj-$(CONFIG_WLAGS49_H2) += wlags49_h2/

View File

@ -267,6 +267,10 @@ static ssize_t store_log_level(struct kobject *kobj, struct attribute *attr,
if (atomic_read(&bat_priv->log_level) == log_level_tmp)
return count;
bat_info(net_dev, "Changing log level from: %i to: %li\n",
atomic_read(&bat_priv->log_level),
log_level_tmp);
atomic_set(&bat_priv->log_level, (unsigned)log_level_tmp);
return count;
}

View File

@ -129,6 +129,9 @@ static bool hardif_is_iface_up(struct batman_if *batman_if)
static void update_mac_addresses(struct batman_if *batman_if)
{
if (!batman_if || !batman_if->packet_buff)
return;
addr_to_string(batman_if->addr_str, batman_if->net_dev->dev_addr);
memcpy(((struct batman_packet *)(batman_if->packet_buff))->orig,
@ -194,8 +197,6 @@ static void hardif_activate_interface(struct net_device *net_dev,
if (batman_if->if_status != IF_INACTIVE)
return;
dev_hold(batman_if->net_dev);
update_mac_addresses(batman_if);
batman_if->if_status = IF_TO_BE_ACTIVATED;
@ -222,8 +223,6 @@ static void hardif_deactivate_interface(struct net_device *net_dev,
(batman_if->if_status != IF_TO_BE_ACTIVATED))
return;
dev_put(batman_if->net_dev);
batman_if->if_status = IF_INACTIVE;
bat_info(net_dev, "Interface deactivated: %s\n", batman_if->dev);
@ -318,11 +317,13 @@ static struct batman_if *hardif_add_interface(struct net_device *net_dev)
if (ret != 1)
goto out;
dev_hold(net_dev);
batman_if = kmalloc(sizeof(struct batman_if), GFP_ATOMIC);
if (!batman_if) {
pr_err("Can't add interface (%s): out of memory\n",
net_dev->name);
goto out;
goto release_dev;
}
batman_if->dev = kstrdup(net_dev->name, GFP_ATOMIC);
@ -336,6 +337,7 @@ static struct batman_if *hardif_add_interface(struct net_device *net_dev)
batman_if->if_num = -1;
batman_if->net_dev = net_dev;
batman_if->if_status = IF_NOT_IN_USE;
batman_if->packet_buff = NULL;
INIT_LIST_HEAD(&batman_if->list);
check_known_mac_addr(batman_if->net_dev->dev_addr);
@ -346,6 +348,8 @@ free_dev:
kfree(batman_if->dev);
free_if:
kfree(batman_if);
release_dev:
dev_put(net_dev);
out:
return NULL;
}
@ -374,6 +378,7 @@ static void hardif_remove_interface(struct batman_if *batman_if)
batman_if->if_status = IF_TO_BE_REMOVED;
list_del_rcu(&batman_if->list);
sysfs_del_hardif(&batman_if->hardif_obj);
dev_put(batman_if->net_dev);
call_rcu(&batman_if->rcu, hardif_free_interface);
}
@ -393,15 +398,13 @@ static int hard_if_event(struct notifier_block *this,
/* FIXME: each batman_if will be attached to a softif */
struct bat_priv *bat_priv = netdev_priv(soft_device);
if (!batman_if)
batman_if = hardif_add_interface(net_dev);
if (!batman_if && event == NETDEV_REGISTER)
batman_if = hardif_add_interface(net_dev);
if (!batman_if)
goto out;
switch (event) {
case NETDEV_REGISTER:
break;
case NETDEV_UP:
hardif_activate_interface(soft_device, bat_priv, batman_if);
break;
@ -442,8 +445,6 @@ int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
struct bat_priv *bat_priv = netdev_priv(soft_device);
struct batman_packet *batman_packet;
struct batman_if *batman_if;
struct net_device_stats *stats;
struct rtnl_link_stats64 temp;
int ret;
skb = skb_share_check(skb, GFP_ATOMIC);
@ -479,12 +480,6 @@ int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
if (batman_if->if_status != IF_ACTIVE)
goto err_free;
stats = (struct net_device_stats *)dev_get_stats(skb->dev, &temp);
if (stats) {
stats->rx_packets++;
stats->rx_bytes += skb->len;
}
batman_packet = (struct batman_packet *)skb->data;
if (batman_packet->version != COMPAT_VERSION) {

View File

@ -67,6 +67,7 @@ static int bat_socket_open(struct inode *inode, struct file *file)
INIT_LIST_HEAD(&socket_client->queue_list);
socket_client->queue_len = 0;
socket_client->index = i;
socket_client->bat_priv = inode->i_private;
spin_lock_init(&socket_client->lock);
init_waitqueue_head(&socket_client->queue_wait);
@ -151,9 +152,8 @@ static ssize_t bat_socket_read(struct file *file, char __user *buf,
static ssize_t bat_socket_write(struct file *file, const char __user *buff,
size_t len, loff_t *off)
{
/* FIXME: each orig_node->batman_if will be attached to a softif */
struct bat_priv *bat_priv = netdev_priv(soft_device);
struct socket_client *socket_client = file->private_data;
struct bat_priv *bat_priv = socket_client->bat_priv;
struct icmp_packet_rr icmp_packet;
struct orig_node *orig_node;
struct batman_if *batman_if;
@ -168,6 +168,9 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
return -EINVAL;
}
if (!bat_priv->primary_if)
return -EFAULT;
if (len >= sizeof(struct icmp_packet_rr))
packet_len = sizeof(struct icmp_packet_rr);
@ -223,7 +226,8 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
if (batman_if->if_status != IF_ACTIVE)
goto dst_unreach;
memcpy(icmp_packet.orig, batman_if->net_dev->dev_addr, ETH_ALEN);
memcpy(icmp_packet.orig,
bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
if (packet_len == sizeof(struct icmp_packet_rr))
memcpy(icmp_packet.rr, batman_if->net_dev->dev_addr, ETH_ALEN);
@ -271,7 +275,7 @@ int bat_socket_setup(struct bat_priv *bat_priv)
goto err;
d = debugfs_create_file(ICMP_SOCKET, S_IFREG | S_IWUSR | S_IRUSR,
bat_priv->debug_dir, NULL, &fops);
bat_priv->debug_dir, bat_priv, &fops);
if (d)
goto err;

View File

@ -250,10 +250,13 @@ int choose_orig(void *data, int32_t size)
int is_my_mac(uint8_t *addr)
{
struct batman_if *batman_if;
rcu_read_lock();
list_for_each_entry_rcu(batman_if, &if_list, list) {
if ((batman_if->net_dev) &&
(compare_orig(batman_if->net_dev->dev_addr, addr))) {
if (batman_if->if_status != IF_ACTIVE)
continue;
if (compare_orig(batman_if->net_dev->dev_addr, addr)) {
rcu_read_unlock();
return 1;
}

View File

@ -391,11 +391,12 @@ static int orig_node_add_if(struct orig_node *orig_node, int max_if_num)
int orig_hash_add_if(struct batman_if *batman_if, int max_if_num)
{
struct orig_node *orig_node;
unsigned long flags;
HASHIT(hashit);
/* resize all orig nodes because orig_node->bcast_own(_sum) depend on
* if_num */
spin_lock(&orig_hash_lock);
spin_lock_irqsave(&orig_hash_lock, flags);
while (hash_iterate(orig_hash, &hashit)) {
orig_node = hashit.bucket->data;
@ -404,11 +405,11 @@ int orig_hash_add_if(struct batman_if *batman_if, int max_if_num)
goto err;
}
spin_unlock(&orig_hash_lock);
spin_unlock_irqrestore(&orig_hash_lock, flags);
return 0;
err:
spin_unlock(&orig_hash_lock);
spin_unlock_irqrestore(&orig_hash_lock, flags);
return -ENOMEM;
}
@ -468,12 +469,13 @@ int orig_hash_del_if(struct batman_if *batman_if, int max_if_num)
{
struct batman_if *batman_if_tmp;
struct orig_node *orig_node;
unsigned long flags;
HASHIT(hashit);
int ret;
/* resize all orig nodes because orig_node->bcast_own(_sum) depend on
* if_num */
spin_lock(&orig_hash_lock);
spin_lock_irqsave(&orig_hash_lock, flags);
while (hash_iterate(orig_hash, &hashit)) {
orig_node = hashit.bucket->data;
@ -500,10 +502,10 @@ int orig_hash_del_if(struct batman_if *batman_if, int max_if_num)
rcu_read_unlock();
batman_if->if_num = -1;
spin_unlock(&orig_hash_lock);
spin_unlock_irqrestore(&orig_hash_lock, flags);
return 0;
err:
spin_unlock(&orig_hash_lock);
spin_unlock_irqrestore(&orig_hash_lock, flags);
return -ENOMEM;
}

View File

@ -783,6 +783,8 @@ int recv_bat_packet(struct sk_buff *skb,
static int recv_my_icmp_packet(struct sk_buff *skb, size_t icmp_len)
{
/* FIXME: each batman_if will be attached to a softif */
struct bat_priv *bat_priv = netdev_priv(soft_device);
struct orig_node *orig_node;
struct icmp_packet_rr *icmp_packet;
struct ethhdr *ethhdr;
@ -801,6 +803,9 @@ static int recv_my_icmp_packet(struct sk_buff *skb, size_t icmp_len)
return NET_RX_DROP;
}
if (!bat_priv->primary_if)
return NET_RX_DROP;
/* answer echo request (ping) */
/* get routing information */
spin_lock_irqsave(&orig_hash_lock, flags);
@ -830,7 +835,8 @@ static int recv_my_icmp_packet(struct sk_buff *skb, size_t icmp_len)
}
memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN);
memcpy(icmp_packet->orig,
bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
icmp_packet->msg_type = ECHO_REPLY;
icmp_packet->ttl = TTL;
@ -845,6 +851,8 @@ static int recv_my_icmp_packet(struct sk_buff *skb, size_t icmp_len)
static int recv_icmp_ttl_exceeded(struct sk_buff *skb, size_t icmp_len)
{
/* FIXME: each batman_if will be attached to a softif */
struct bat_priv *bat_priv = netdev_priv(soft_device);
struct orig_node *orig_node;
struct icmp_packet *icmp_packet;
struct ethhdr *ethhdr;
@ -865,6 +873,9 @@ static int recv_icmp_ttl_exceeded(struct sk_buff *skb, size_t icmp_len)
return NET_RX_DROP;
}
if (!bat_priv->primary_if)
return NET_RX_DROP;
/* get routing information */
spin_lock_irqsave(&orig_hash_lock, flags);
orig_node = ((struct orig_node *)
@ -892,7 +903,8 @@ static int recv_icmp_ttl_exceeded(struct sk_buff *skb, size_t icmp_len)
}
memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN);
memcpy(icmp_packet->orig,
bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
icmp_packet->msg_type = TTL_EXCEEDED;
icmp_packet->ttl = TTL;

View File

@ -126,6 +126,7 @@ struct socket_client {
unsigned char index;
spinlock_t lock;
wait_queue_head_t queue_wait;
struct bat_priv *bat_priv;
};
struct socket_packet {

View File

@ -1,10 +0,0 @@
config DX_SEP
tristate "Discretix SEP driver"
# depends on MRST
depends on RAR_REGISTER && PCI
default y
help
Discretix SEP driver
If unsure say M. The compiled module will be
called sep_driver.ko

View File

@ -1,2 +0,0 @@
obj-$(CONFIG_DX_SEP) := sep_driver.o

View File

@ -1,8 +0,0 @@
Todo's so far (from Alan Cox)
- Fix firmware loading
- Get firmware into firmware git tree
- Review and tidy each algorithm function
- Check whether it can be plugged into any of the kernel crypto API
interfaces
- Do something about the magic shared memory interface and replace it
with something saner (in Linux terms)

View File

@ -1,110 +0,0 @@
#ifndef __SEP_DEV_H__
#define __SEP_DEV_H__
/*
*
* sep_dev.h - Security Processor Device Structures
*
* Copyright(c) 2009 Intel Corporation. All rights reserved.
* Copyright(c) 2009 Discretix. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* CONTACTS:
*
* Alan Cox alan@linux.intel.com
*
*/
struct sep_device {
/* pointer to pci dev */
struct pci_dev *pdev;
unsigned long in_use;
/* address of the shared memory allocated during init for SEP driver
(coherent alloc) */
void *shared_addr;
/* the physical address of the shared area */
dma_addr_t shared_bus;
/* restricted access region (coherent alloc) */
dma_addr_t rar_bus;
void *rar_addr;
/* firmware regions: cache is at rar_addr */
unsigned long cache_size;
/* follows the cache */
dma_addr_t resident_bus;
unsigned long resident_size;
void *resident_addr;
/* start address of the access to the SEP registers from driver */
void __iomem *reg_addr;
/* transaction counter that coordinates the transactions between SEP and HOST */
unsigned long send_ct;
/* counter for the messages from sep */
unsigned long reply_ct;
/* counter for the number of bytes allocated in the pool for the current
transaction */
unsigned long data_pool_bytes_allocated;
/* array of pointers to the pages that represent input data for the synchronic
DMA action */
struct page **in_page_array;
/* array of pointers to the pages that represent out data for the synchronic
DMA action */
struct page **out_page_array;
/* number of pages in the sep_in_page_array */
unsigned long in_num_pages;
/* number of pages in the sep_out_page_array */
unsigned long out_num_pages;
/* global data for every flow */
struct sep_flow_context_t flows[SEP_DRIVER_NUM_FLOWS];
/* pointer to the workqueue that handles the flow done interrupts */
struct workqueue_struct *flow_wq;
};
static struct sep_device *sep_dev;
static inline void sep_write_reg(struct sep_device *dev, int reg, u32 value)
{
void __iomem *addr = dev->reg_addr + reg;
writel(value, addr);
}
static inline u32 sep_read_reg(struct sep_device *dev, int reg)
{
void __iomem *addr = dev->reg_addr + reg;
return readl(addr);
}
/* wait for SRAM write complete(indirect write */
static inline void sep_wait_sram_write(struct sep_device *dev)
{
u32 reg_val;
do
reg_val = sep_read_reg(dev, HW_SRAM_DATA_READY_REG_ADDR);
while (!(reg_val & 1));
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,425 +0,0 @@
/*
*
* sep_driver_api.h - Security Processor Driver api definitions
*
* Copyright(c) 2009 Intel Corporation. All rights reserved.
* Copyright(c) 2009 Discretix. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* CONTACTS:
*
* Mark Allyn mark.a.allyn@intel.com
*
* CHANGES:
*
* 2009.06.26 Initial publish
*
*/
#ifndef __SEP_DRIVER_API_H__
#define __SEP_DRIVER_API_H__
/*----------------------------------------------------------------
IOCTL command defines
-----------------------------------------------------------------*/
/* magic number 1 of the sep IOCTL command */
#define SEP_IOC_MAGIC_NUMBER 's'
/* sends interrupt to sep that message is ready */
#define SEP_IOCSENDSEPCOMMAND _IO(SEP_IOC_MAGIC_NUMBER , 0)
/* sends interrupt to sep that message is ready */
#define SEP_IOCSENDSEPRPLYCOMMAND _IO(SEP_IOC_MAGIC_NUMBER , 1)
/* allocate memory in data pool */
#define SEP_IOCALLOCDATAPOLL _IO(SEP_IOC_MAGIC_NUMBER , 2)
/* write to pre-allocated memory in data pool */
#define SEP_IOCWRITEDATAPOLL _IO(SEP_IOC_MAGIC_NUMBER , 3)
/* read from pre-allocated memory in data pool */
#define SEP_IOCREADDATAPOLL _IO(SEP_IOC_MAGIC_NUMBER , 4)
/* create sym dma lli tables */
#define SEP_IOCCREATESYMDMATABLE _IO(SEP_IOC_MAGIC_NUMBER , 5)
/* create flow dma lli tables */
#define SEP_IOCCREATEFLOWDMATABLE _IO(SEP_IOC_MAGIC_NUMBER , 6)
/* free dynamic data aalocated during table creation */
#define SEP_IOCFREEDMATABLEDATA _IO(SEP_IOC_MAGIC_NUMBER , 7)
/* get the static pool area addresses (physical and virtual) */
#define SEP_IOCGETSTATICPOOLADDR _IO(SEP_IOC_MAGIC_NUMBER , 8)
/* set flow id command */
#define SEP_IOCSETFLOWID _IO(SEP_IOC_MAGIC_NUMBER , 9)
/* add tables to the dynamic flow */
#define SEP_IOCADDFLOWTABLE _IO(SEP_IOC_MAGIC_NUMBER , 10)
/* add flow add tables message */
#define SEP_IOCADDFLOWMESSAGE _IO(SEP_IOC_MAGIC_NUMBER , 11)
/* start sep command */
#define SEP_IOCSEPSTART _IO(SEP_IOC_MAGIC_NUMBER , 12)
/* init sep command */
#define SEP_IOCSEPINIT _IO(SEP_IOC_MAGIC_NUMBER , 13)
/* end transaction command */
#define SEP_IOCENDTRANSACTION _IO(SEP_IOC_MAGIC_NUMBER , 15)
/* reallocate cache and resident */
#define SEP_IOCREALLOCCACHERES _IO(SEP_IOC_MAGIC_NUMBER , 16)
/* get the offset of the address starting from the beginnnig of the map area */
#define SEP_IOCGETMAPPEDADDROFFSET _IO(SEP_IOC_MAGIC_NUMBER , 17)
/* get time address and value */
#define SEP_IOCGETIME _IO(SEP_IOC_MAGIC_NUMBER , 19)
/*-------------------------------------------
TYPEDEFS
----------------------------------------------*/
/*
init command struct
*/
struct sep_driver_init_t {
/* start of the 1G of the host memory address that SEP can access */
unsigned long message_addr;
/* start address of resident */
unsigned long message_size_in_words;
};
/*
realloc cache resident command
*/
struct sep_driver_realloc_cache_resident_t {
/* new cache address */
u64 new_cache_addr;
/* new resident address */
u64 new_resident_addr;
/* new resident address */
u64 new_shared_area_addr;
/* new base address */
u64 new_base_addr;
};
struct sep_driver_alloc_t {
/* virtual address of allocated space */
unsigned long offset;
/* physical address of allocated space */
unsigned long phys_address;
/* number of bytes to allocate */
unsigned long num_bytes;
};
/*
*/
struct sep_driver_write_t {
/* application space address */
unsigned long app_address;
/* address of the data pool */
unsigned long datapool_address;
/* number of bytes to write */
unsigned long num_bytes;
};
/*
*/
struct sep_driver_read_t {
/* application space address */
unsigned long app_address;
/* address of the data pool */
unsigned long datapool_address;
/* number of bytes to read */
unsigned long num_bytes;
};
/*
*/
struct sep_driver_build_sync_table_t {
/* address value of the data in */
unsigned long app_in_address;
/* size of data in */
unsigned long data_in_size;
/* address of the data out */
unsigned long app_out_address;
/* the size of the block of the operation - if needed,
every table will be modulo this parameter */
unsigned long block_size;
/* the physical address of the first input DMA table */
unsigned long in_table_address;
/* number of entries in the first input DMA table */
unsigned long in_table_num_entries;
/* the physical address of the first output DMA table */
unsigned long out_table_address;
/* number of entries in the first output DMA table */
unsigned long out_table_num_entries;
/* data in the first input table */
unsigned long table_data_size;
/* distinct user/kernel layout */
bool isKernelVirtualAddress;
};
/*
*/
struct sep_driver_build_flow_table_t {
/* flow type */
unsigned long flow_type;
/* flag for input output */
unsigned long input_output_flag;
/* address value of the data in */
unsigned long virt_buff_data_addr;
/* size of data in */
unsigned long num_virtual_buffers;
/* the physical address of the first input DMA table */
unsigned long first_table_addr;
/* number of entries in the first input DMA table */
unsigned long first_table_num_entries;
/* data in the first input table */
unsigned long first_table_data_size;
/* distinct user/kernel layout */
bool isKernelVirtualAddress;
};
struct sep_driver_add_flow_table_t {
/* flow id */
unsigned long flow_id;
/* flag for input output */
unsigned long inputOutputFlag;
/* address value of the data in */
unsigned long virt_buff_data_addr;
/* size of data in */
unsigned long num_virtual_buffers;
/* address of the first table */
unsigned long first_table_addr;
/* number of entries in the first table */
unsigned long first_table_num_entries;
/* data size of the first table */
unsigned long first_table_data_size;
/* distinct user/kernel layout */
bool isKernelVirtualAddress;
};
/*
command struct for set flow id
*/
struct sep_driver_set_flow_id_t {
/* flow id to set */
unsigned long flow_id;
};
/* command struct for add tables message */
struct sep_driver_add_message_t {
/* flow id to set */
unsigned long flow_id;
/* message size in bytes */
unsigned long message_size_in_bytes;
/* address of the message */
unsigned long message_address;
};
/* command struct for static pool addresses */
struct sep_driver_static_pool_addr_t {
/* physical address of the static pool */
unsigned long physical_static_address;
/* virtual address of the static pool */
unsigned long virtual_static_address;
};
/* command struct for getiing offset of the physical address from
the start of the mapped area */
struct sep_driver_get_mapped_offset_t {
/* physical address of the static pool */
unsigned long physical_address;
/* virtual address of the static pool */
unsigned long offset;
};
/* command struct for getting time value and address */
struct sep_driver_get_time_t {
/* physical address of stored time */
unsigned long time_physical_address;
/* value of the stored time */
unsigned long time_value;
};
/*
structure that represent one entry in the DMA LLI table
*/
struct sep_lli_entry_t {
/* physical address */
unsigned long physical_address;
/* block size */
unsigned long block_size;
};
/*
structure that reperesents data needed for lli table construction
*/
struct sep_lli_prepare_table_data_t {
/* pointer to the memory where the first lli entry to be built */
struct sep_lli_entry_t *lli_entry_ptr;
/* pointer to the array of lli entries from which the table is to be built */
struct sep_lli_entry_t *lli_array_ptr;
/* number of elements in lli array */
int lli_array_size;
/* number of entries in the created table */
int num_table_entries;
/* number of array entries processed during table creation */
int num_array_entries_processed;
/* the totatl data size in the created table */
int lli_table_total_data_size;
};
/*
structure that represent tone table - it is not used in code, jkust
to show what table looks like
*/
struct sep_lli_table_t {
/* number of pages mapped in this tables. If 0 - means that the table
is not defined (used as a valid flag) */
unsigned long num_pages;
/*
pointer to array of page pointers that represent the mapping of the
virtual buffer defined by the table to the physical memory. If this
pointer is NULL, it means that the table is not defined
(used as a valid flag)
*/
struct page **table_page_array_ptr;
/* maximum flow entries in table */
struct sep_lli_entry_t lli_entries[SEP_DRIVER_MAX_FLOW_NUM_ENTRIES_IN_TABLE];
};
/*
structure for keeping the mapping of the virtual buffer into physical pages
*/
struct sep_flow_buffer_data {
/* pointer to the array of page structs pointers to the pages of the
virtual buffer */
struct page **page_array_ptr;
/* number of pages taken by the virtual buffer */
unsigned long num_pages;
/* this flag signals if this page_array is the last one among many that were
sent in one setting to SEP */
unsigned long last_page_array_flag;
};
/*
struct that keeps all the data for one flow
*/
struct sep_flow_context_t {
/*
work struct for handling the flow done interrupt in the workqueue
this structure must be in the first place, since it will be used
forcasting to the containing flow context
*/
struct work_struct flow_wq;
/* flow id */
unsigned long flow_id;
/* additional input tables exists */
unsigned long input_tables_flag;
/* additional output tables exists */
unsigned long output_tables_flag;
/* data of the first input file */
struct sep_lli_entry_t first_input_table;
/* data of the first output table */
struct sep_lli_entry_t first_output_table;
/* last input table data */
struct sep_lli_entry_t last_input_table;
/* last output table data */
struct sep_lli_entry_t last_output_table;
/* first list of table */
struct sep_lli_entry_t input_tables_in_process;
/* output table in process (in sep) */
struct sep_lli_entry_t output_tables_in_process;
/* size of messages in bytes */
unsigned long message_size_in_bytes;
/* message */
unsigned char message[SEP_MAX_ADD_MESSAGE_LENGTH_IN_BYTES];
};
#endif

View File

@ -1,225 +0,0 @@
/*
*
* sep_driver_config.h - Security Processor Driver configuration
*
* Copyright(c) 2009 Intel Corporation. All rights reserved.
* Copyright(c) 2009 Discretix. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* CONTACTS:
*
* Mark Allyn mark.a.allyn@intel.com
*
* CHANGES:
*
* 2009.06.26 Initial publish
*
*/
#ifndef __SEP_DRIVER_CONFIG_H__
#define __SEP_DRIVER_CONFIG_H__
/*--------------------------------------
DRIVER CONFIGURATION FLAGS
-------------------------------------*/
/* if flag is on , then the driver is running in polling and
not interrupt mode */
#define SEP_DRIVER_POLLING_MODE 1
/* flag which defines if the shared area address should be
reconfiged (send to SEP anew) during init of the driver */
#define SEP_DRIVER_RECONFIG_MESSAGE_AREA 0
/* the mode for running on the ARM1172 Evaluation platform (flag is 1) */
#define SEP_DRIVER_ARM_DEBUG_MODE 0
/*-------------------------------------------
INTERNAL DATA CONFIGURATION
-------------------------------------------*/
/* flag for the input array */
#define SEP_DRIVER_IN_FLAG 0
/* flag for output array */
#define SEP_DRIVER_OUT_FLAG 1
/* maximum number of entries in one LLI tables */
#define SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP 8
/*--------------------------------------------------------
SHARED AREA memory total size is 36K
it is divided is following:
SHARED_MESSAGE_AREA 8K }
}
STATIC_POOL_AREA 4K } MAPPED AREA ( 24 K)
}
DATA_POOL_AREA 12K }
SYNCHRONIC_DMA_TABLES_AREA 5K
FLOW_DMA_TABLES_AREA 4K
SYSTEM_MEMORY_AREA 3k
SYSTEM_MEMORY total size is 3k
it is divided as following:
TIME_MEMORY_AREA 8B
-----------------------------------------------------------*/
/*
the maximum length of the message - the rest of the message shared
area will be dedicated to the dma lli tables
*/
#define SEP_DRIVER_MAX_MESSAGE_SIZE_IN_BYTES (8 * 1024)
/* the size of the message shared area in pages */
#define SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES (8 * 1024)
/* the size of the data pool static area in pages */
#define SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES (4 * 1024)
/* the size of the data pool shared area size in pages */
#define SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES (12 * 1024)
/* the size of the message shared area in pages */
#define SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_SIZE_IN_BYTES (1024 * 5)
/* the size of the data pool shared area size in pages */
#define SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES (1024 * 4)
/* system data (time, caller id etc') pool */
#define SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES 100
/* area size that is mapped - we map the MESSAGE AREA, STATIC POOL and
DATA POOL areas. area must be module 4k */
#define SEP_DRIVER_MMMAP_AREA_SIZE (1024 * 24)
/*-----------------------------------------------
offsets of the areas starting from the shared area start address
*/
/* message area offset */
#define SEP_DRIVER_MESSAGE_AREA_OFFSET_IN_BYTES 0
/* static pool area offset */
#define SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES \
(SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES)
/* data pool area offset */
#define SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES \
(SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES + \
SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES)
/* synhronic dma tables area offset */
#define SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES \
(SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES + \
SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES)
/* sep driver flow dma tables area offset */
#define SEP_DRIVER_FLOW_DMA_TABLES_AREA_OFFSET_IN_BYTES \
(SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES + \
SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_SIZE_IN_BYTES)
/* system memory offset in bytes */
#define SEP_DRIVER_SYSTEM_DATA_MEMORY_OFFSET_IN_BYTES \
(SEP_DRIVER_FLOW_DMA_TABLES_AREA_OFFSET_IN_BYTES + \
SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES)
/* offset of the time area */
#define SEP_DRIVER_SYSTEM_TIME_MEMORY_OFFSET_IN_BYTES \
(SEP_DRIVER_SYSTEM_DATA_MEMORY_OFFSET_IN_BYTES)
/* start physical address of the SEP registers memory in HOST */
#define SEP_IO_MEM_REGION_START_ADDRESS 0x80000000
/* size of the SEP registers memory region in HOST (for now 100 registers) */
#define SEP_IO_MEM_REGION_SIZE (2 * 0x100000)
/* define the number of IRQ for SEP interrupts */
#define SEP_DIRVER_IRQ_NUM 1
/* maximum number of add buffers */
#define SEP_MAX_NUM_ADD_BUFFERS 100
/* number of flows */
#define SEP_DRIVER_NUM_FLOWS 4
/* maximum number of entries in flow table */
#define SEP_DRIVER_MAX_FLOW_NUM_ENTRIES_IN_TABLE 25
/* offset of the num entries in the block length entry of the LLI */
#define SEP_NUM_ENTRIES_OFFSET_IN_BITS 24
/* offset of the interrupt flag in the block length entry of the LLI */
#define SEP_INT_FLAG_OFFSET_IN_BITS 31
/* mask for extracting data size from LLI */
#define SEP_TABLE_DATA_SIZE_MASK 0xFFFFFF
/* mask for entries after being shifted left */
#define SEP_NUM_ENTRIES_MASK 0x7F
/* default flow id */
#define SEP_FREE_FLOW_ID 0xFFFFFFFF
/* temp flow id used during cretiong of new flow until receiving
real flow id from sep */
#define SEP_TEMP_FLOW_ID (SEP_DRIVER_NUM_FLOWS + 1)
/* maximum add buffers message length in bytes */
#define SEP_MAX_ADD_MESSAGE_LENGTH_IN_BYTES (7 * 4)
/* maximum number of concurrent virtual buffers */
#define SEP_MAX_VIRT_BUFFERS_CONCURRENT 100
/* the token that defines the start of time address */
#define SEP_TIME_VAL_TOKEN 0x12345678
/* DEBUG LEVEL MASKS */
#define SEP_DEBUG_LEVEL_BASIC 0x1
#define SEP_DEBUG_LEVEL_EXTENDED 0x4
/* Debug helpers */
#define dbg(fmt, args...) \
do {\
if (debug & SEP_DEBUG_LEVEL_BASIC) \
printk(KERN_DEBUG fmt, ##args); \
} while(0);
#define edbg(fmt, args...) \
do { \
if (debug & SEP_DEBUG_LEVEL_EXTENDED) \
printk(KERN_DEBUG fmt, ##args); \
} while(0);
#endif

View File

@ -1,232 +0,0 @@
/*
*
* sep_driver_hw_defs.h - Security Processor Driver hardware definitions
*
* Copyright(c) 2009 Intel Corporation. All rights reserved.
* Copyright(c) 2009 Discretix. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* CONTACTS:
*
* Mark Allyn mark.a.allyn@intel.com
*
* CHANGES:
*
* 2009.06.26 Initial publish
*
*/
#ifndef SEP_DRIVER_HW_DEFS__H
#define SEP_DRIVER_HW_DEFS__H
/*--------------------------------------------------------------------------*/
/* Abstract: HW Registers Defines. */
/* */
/* Note: This file was automatically created !!! */
/* DO NOT EDIT THIS FILE !!! */
/*--------------------------------------------------------------------------*/
/* cf registers */
#define HW_R0B_ADDR_0_REG_ADDR 0x0000UL
#define HW_R0B_ADDR_1_REG_ADDR 0x0004UL
#define HW_R0B_ADDR_2_REG_ADDR 0x0008UL
#define HW_R0B_ADDR_3_REG_ADDR 0x000cUL
#define HW_R0B_ADDR_4_REG_ADDR 0x0010UL
#define HW_R0B_ADDR_5_REG_ADDR 0x0014UL
#define HW_R0B_ADDR_6_REG_ADDR 0x0018UL
#define HW_R0B_ADDR_7_REG_ADDR 0x001cUL
#define HW_R0B_ADDR_8_REG_ADDR 0x0020UL
#define HW_R2B_ADDR_0_REG_ADDR 0x0080UL
#define HW_R2B_ADDR_1_REG_ADDR 0x0084UL
#define HW_R2B_ADDR_2_REG_ADDR 0x0088UL
#define HW_R2B_ADDR_3_REG_ADDR 0x008cUL
#define HW_R2B_ADDR_4_REG_ADDR 0x0090UL
#define HW_R2B_ADDR_5_REG_ADDR 0x0094UL
#define HW_R2B_ADDR_6_REG_ADDR 0x0098UL
#define HW_R2B_ADDR_7_REG_ADDR 0x009cUL
#define HW_R2B_ADDR_8_REG_ADDR 0x00a0UL
#define HW_R3B_REG_ADDR 0x00C0UL
#define HW_R4B_REG_ADDR 0x0100UL
#define HW_CSA_ADDR_0_REG_ADDR 0x0140UL
#define HW_CSA_ADDR_1_REG_ADDR 0x0144UL
#define HW_CSA_ADDR_2_REG_ADDR 0x0148UL
#define HW_CSA_ADDR_3_REG_ADDR 0x014cUL
#define HW_CSA_ADDR_4_REG_ADDR 0x0150UL
#define HW_CSA_ADDR_5_REG_ADDR 0x0154UL
#define HW_CSA_ADDR_6_REG_ADDR 0x0158UL
#define HW_CSA_ADDR_7_REG_ADDR 0x015cUL
#define HW_CSA_ADDR_8_REG_ADDR 0x0160UL
#define HW_CSA_REG_ADDR 0x0140UL
#define HW_SINB_REG_ADDR 0x0180UL
#define HW_SOUTB_REG_ADDR 0x0184UL
#define HW_PKI_CONTROL_REG_ADDR 0x01C0UL
#define HW_PKI_STATUS_REG_ADDR 0x01C4UL
#define HW_PKI_BUSY_REG_ADDR 0x01C8UL
#define HW_PKI_A_1025_REG_ADDR 0x01CCUL
#define HW_PKI_SDMA_CTL_REG_ADDR 0x01D0UL
#define HW_PKI_SDMA_OFFSET_REG_ADDR 0x01D4UL
#define HW_PKI_SDMA_POINTERS_REG_ADDR 0x01D8UL
#define HW_PKI_SDMA_DLENG_REG_ADDR 0x01DCUL
#define HW_PKI_SDMA_EXP_POINTERS_REG_ADDR 0x01E0UL
#define HW_PKI_SDMA_RES_POINTERS_REG_ADDR 0x01E4UL
#define HW_PKI_CLR_REG_ADDR 0x01E8UL
#define HW_PKI_SDMA_BUSY_REG_ADDR 0x01E8UL
#define HW_PKI_SDMA_FIRST_EXP_N_REG_ADDR 0x01ECUL
#define HW_PKI_SDMA_MUL_BY1_REG_ADDR 0x01F0UL
#define HW_PKI_SDMA_RMUL_SEL_REG_ADDR 0x01F4UL
#define HW_DES_KEY_0_REG_ADDR 0x0208UL
#define HW_DES_KEY_1_REG_ADDR 0x020CUL
#define HW_DES_KEY_2_REG_ADDR 0x0210UL
#define HW_DES_KEY_3_REG_ADDR 0x0214UL
#define HW_DES_KEY_4_REG_ADDR 0x0218UL
#define HW_DES_KEY_5_REG_ADDR 0x021CUL
#define HW_DES_CONTROL_0_REG_ADDR 0x0220UL
#define HW_DES_CONTROL_1_REG_ADDR 0x0224UL
#define HW_DES_IV_0_REG_ADDR 0x0228UL
#define HW_DES_IV_1_REG_ADDR 0x022CUL
#define HW_AES_KEY_0_ADDR_0_REG_ADDR 0x0400UL
#define HW_AES_KEY_0_ADDR_1_REG_ADDR 0x0404UL
#define HW_AES_KEY_0_ADDR_2_REG_ADDR 0x0408UL
#define HW_AES_KEY_0_ADDR_3_REG_ADDR 0x040cUL
#define HW_AES_KEY_0_ADDR_4_REG_ADDR 0x0410UL
#define HW_AES_KEY_0_ADDR_5_REG_ADDR 0x0414UL
#define HW_AES_KEY_0_ADDR_6_REG_ADDR 0x0418UL
#define HW_AES_KEY_0_ADDR_7_REG_ADDR 0x041cUL
#define HW_AES_KEY_0_REG_ADDR 0x0400UL
#define HW_AES_IV_0_ADDR_0_REG_ADDR 0x0440UL
#define HW_AES_IV_0_ADDR_1_REG_ADDR 0x0444UL
#define HW_AES_IV_0_ADDR_2_REG_ADDR 0x0448UL
#define HW_AES_IV_0_ADDR_3_REG_ADDR 0x044cUL
#define HW_AES_IV_0_REG_ADDR 0x0440UL
#define HW_AES_CTR1_ADDR_0_REG_ADDR 0x0460UL
#define HW_AES_CTR1_ADDR_1_REG_ADDR 0x0464UL
#define HW_AES_CTR1_ADDR_2_REG_ADDR 0x0468UL
#define HW_AES_CTR1_ADDR_3_REG_ADDR 0x046cUL
#define HW_AES_CTR1_REG_ADDR 0x0460UL
#define HW_AES_SK_REG_ADDR 0x0478UL
#define HW_AES_MAC_OK_REG_ADDR 0x0480UL
#define HW_AES_PREV_IV_0_ADDR_0_REG_ADDR 0x0490UL
#define HW_AES_PREV_IV_0_ADDR_1_REG_ADDR 0x0494UL
#define HW_AES_PREV_IV_0_ADDR_2_REG_ADDR 0x0498UL
#define HW_AES_PREV_IV_0_ADDR_3_REG_ADDR 0x049cUL
#define HW_AES_PREV_IV_0_REG_ADDR 0x0490UL
#define HW_AES_CONTROL_REG_ADDR 0x04C0UL
#define HW_HASH_H0_REG_ADDR 0x0640UL
#define HW_HASH_H1_REG_ADDR 0x0644UL
#define HW_HASH_H2_REG_ADDR 0x0648UL
#define HW_HASH_H3_REG_ADDR 0x064CUL
#define HW_HASH_H4_REG_ADDR 0x0650UL
#define HW_HASH_H5_REG_ADDR 0x0654UL
#define HW_HASH_H6_REG_ADDR 0x0658UL
#define HW_HASH_H7_REG_ADDR 0x065CUL
#define HW_HASH_H8_REG_ADDR 0x0660UL
#define HW_HASH_H9_REG_ADDR 0x0664UL
#define HW_HASH_H10_REG_ADDR 0x0668UL
#define HW_HASH_H11_REG_ADDR 0x066CUL
#define HW_HASH_H12_REG_ADDR 0x0670UL
#define HW_HASH_H13_REG_ADDR 0x0674UL
#define HW_HASH_H14_REG_ADDR 0x0678UL
#define HW_HASH_H15_REG_ADDR 0x067CUL
#define HW_HASH_CONTROL_REG_ADDR 0x07C0UL
#define HW_HASH_PAD_EN_REG_ADDR 0x07C4UL
#define HW_HASH_PAD_CFG_REG_ADDR 0x07C8UL
#define HW_HASH_CUR_LEN_0_REG_ADDR 0x07CCUL
#define HW_HASH_CUR_LEN_1_REG_ADDR 0x07D0UL
#define HW_HASH_CUR_LEN_2_REG_ADDR 0x07D4UL
#define HW_HASH_CUR_LEN_3_REG_ADDR 0x07D8UL
#define HW_HASH_PARAM_REG_ADDR 0x07DCUL
#define HW_HASH_INT_BUSY_REG_ADDR 0x07E0UL
#define HW_HASH_SW_RESET_REG_ADDR 0x07E4UL
#define HW_HASH_ENDIANESS_REG_ADDR 0x07E8UL
#define HW_HASH_DATA_REG_ADDR 0x07ECUL
#define HW_DRNG_CONTROL_REG_ADDR 0x0800UL
#define HW_DRNG_VALID_REG_ADDR 0x0804UL
#define HW_DRNG_DATA_REG_ADDR 0x0808UL
#define HW_RND_SRC_EN_REG_ADDR 0x080CUL
#define HW_AES_CLK_ENABLE_REG_ADDR 0x0810UL
#define HW_DES_CLK_ENABLE_REG_ADDR 0x0814UL
#define HW_HASH_CLK_ENABLE_REG_ADDR 0x0818UL
#define HW_PKI_CLK_ENABLE_REG_ADDR 0x081CUL
#define HW_CLK_STATUS_REG_ADDR 0x0824UL
#define HW_CLK_ENABLE_REG_ADDR 0x0828UL
#define HW_DRNG_SAMPLE_REG_ADDR 0x0850UL
#define HW_RND_SRC_CTL_REG_ADDR 0x0858UL
#define HW_CRYPTO_CTL_REG_ADDR 0x0900UL
#define HW_CRYPTO_STATUS_REG_ADDR 0x090CUL
#define HW_CRYPTO_BUSY_REG_ADDR 0x0910UL
#define HW_AES_BUSY_REG_ADDR 0x0914UL
#define HW_DES_BUSY_REG_ADDR 0x0918UL
#define HW_HASH_BUSY_REG_ADDR 0x091CUL
#define HW_CONTENT_REG_ADDR 0x0924UL
#define HW_VERSION_REG_ADDR 0x0928UL
#define HW_CONTEXT_ID_REG_ADDR 0x0930UL
#define HW_DIN_BUFFER_REG_ADDR 0x0C00UL
#define HW_DIN_MEM_DMA_BUSY_REG_ADDR 0x0c20UL
#define HW_SRC_LLI_MEM_ADDR_REG_ADDR 0x0c24UL
#define HW_SRC_LLI_WORD0_REG_ADDR 0x0C28UL
#define HW_SRC_LLI_WORD1_REG_ADDR 0x0C2CUL
#define HW_SRAM_SRC_ADDR_REG_ADDR 0x0c30UL
#define HW_DIN_SRAM_BYTES_LEN_REG_ADDR 0x0c34UL
#define HW_DIN_SRAM_DMA_BUSY_REG_ADDR 0x0C38UL
#define HW_WRITE_ALIGN_REG_ADDR 0x0C3CUL
#define HW_OLD_DATA_REG_ADDR 0x0C48UL
#define HW_WRITE_ALIGN_LAST_REG_ADDR 0x0C4CUL
#define HW_DOUT_BUFFER_REG_ADDR 0x0C00UL
#define HW_DST_LLI_WORD0_REG_ADDR 0x0D28UL
#define HW_DST_LLI_WORD1_REG_ADDR 0x0D2CUL
#define HW_DST_LLI_MEM_ADDR_REG_ADDR 0x0D24UL
#define HW_DOUT_MEM_DMA_BUSY_REG_ADDR 0x0D20UL
#define HW_SRAM_DEST_ADDR_REG_ADDR 0x0D30UL
#define HW_DOUT_SRAM_BYTES_LEN_REG_ADDR 0x0D34UL
#define HW_DOUT_SRAM_DMA_BUSY_REG_ADDR 0x0D38UL
#define HW_READ_ALIGN_REG_ADDR 0x0D3CUL
#define HW_READ_LAST_DATA_REG_ADDR 0x0D44UL
#define HW_RC4_THRU_CPU_REG_ADDR 0x0D4CUL
#define HW_AHB_SINGLE_REG_ADDR 0x0E00UL
#define HW_SRAM_DATA_REG_ADDR 0x0F00UL
#define HW_SRAM_ADDR_REG_ADDR 0x0F04UL
#define HW_SRAM_DATA_READY_REG_ADDR 0x0F08UL
#define HW_HOST_IRR_REG_ADDR 0x0A00UL
#define HW_HOST_IMR_REG_ADDR 0x0A04UL
#define HW_HOST_ICR_REG_ADDR 0x0A08UL
#define HW_HOST_SEP_SRAM_THRESHOLD_REG_ADDR 0x0A10UL
#define HW_HOST_SEP_BUSY_REG_ADDR 0x0A14UL
#define HW_HOST_SEP_LCS_REG_ADDR 0x0A18UL
#define HW_HOST_CC_SW_RST_REG_ADDR 0x0A40UL
#define HW_HOST_SEP_SW_RST_REG_ADDR 0x0A44UL
#define HW_HOST_FLOW_DMA_SW_INT0_REG_ADDR 0x0A80UL
#define HW_HOST_FLOW_DMA_SW_INT1_REG_ADDR 0x0A84UL
#define HW_HOST_FLOW_DMA_SW_INT2_REG_ADDR 0x0A88UL
#define HW_HOST_FLOW_DMA_SW_INT3_REG_ADDR 0x0A8cUL
#define HW_HOST_FLOW_DMA_SW_INT4_REG_ADDR 0x0A90UL
#define HW_HOST_FLOW_DMA_SW_INT5_REG_ADDR 0x0A94UL
#define HW_HOST_FLOW_DMA_SW_INT6_REG_ADDR 0x0A98UL
#define HW_HOST_FLOW_DMA_SW_INT7_REG_ADDR 0x0A9cUL
#define HW_HOST_SEP_HOST_GPR0_REG_ADDR 0x0B00UL
#define HW_HOST_SEP_HOST_GPR1_REG_ADDR 0x0B04UL
#define HW_HOST_SEP_HOST_GPR2_REG_ADDR 0x0B08UL
#define HW_HOST_SEP_HOST_GPR3_REG_ADDR 0x0B0CUL
#define HW_HOST_HOST_SEP_GPR0_REG_ADDR 0x0B80UL
#define HW_HOST_HOST_SEP_GPR1_REG_ADDR 0x0B84UL
#define HW_HOST_HOST_SEP_GPR2_REG_ADDR 0x0B88UL
#define HW_HOST_HOST_SEP_GPR3_REG_ADDR 0x0B8CUL
#define HW_HOST_HOST_ENDIAN_REG_ADDR 0x0B90UL
#define HW_HOST_HOST_COMM_CLK_EN_REG_ADDR 0x0B94UL
#define HW_CLR_SRAM_BUSY_REG_REG_ADDR 0x0F0CUL
#define HW_CC_SRAM_BASE_ADDRESS 0x5800UL
#endif /* ifndef HW_DEFS */

View File

@ -27,6 +27,7 @@
#include <linux/kthread.h>
#include <linux/log2.h>
#include <linux/init.h>
#include <linux/smp_lock.h>
/**** Helper functions used for Div, Remainder operation on u64 ****/
@ -113,7 +114,6 @@ u64 GLOB_u64_Remainder(u64 addr, u32 divisor_type)
#define GLOB_SBD_NAME "nd"
#define GLOB_SBD_IRQ_NUM (29)
#define GLOB_VERSION "driver version 20091110"
#define GLOB_SBD_IOCTL_GC (0x7701)
#define GLOB_SBD_IOCTL_WL (0x7702)
@ -272,13 +272,6 @@ static int get_res_blk_num_os(void)
return res_blks;
}
static void SBD_prepare_flush(struct request_queue *q, struct request *rq)
{
rq->cmd_type = REQ_TYPE_LINUX_BLOCK;
/* rq->timeout = 5 * HZ; */
rq->cmd[0] = REQ_LB_OP_FLUSH;
}
/* Transfer a full request. */
static int do_transfer(struct spectra_nand_dev *tr, struct request *req)
{
@ -296,8 +289,7 @@ static int do_transfer(struct spectra_nand_dev *tr, struct request *req)
IdentifyDeviceData.PagesPerBlock *
res_blks_os;
if (req->cmd_type == REQ_TYPE_LINUX_BLOCK &&
req->cmd[0] == REQ_LB_OP_FLUSH) {
if (req->cmd_type & REQ_FLUSH) {
if (force_flush_cache()) /* Fail to flush cache */
return -EIO;
else
@ -597,11 +589,23 @@ int GLOB_SBD_ioctl(struct block_device *bdev, fmode_t mode,
return -ENOTTY;
}
int GLOB_SBD_unlocked_ioctl(struct block_device *bdev, fmode_t mode,
unsigned int cmd, unsigned long arg)
{
int ret;
lock_kernel();
ret = GLOB_SBD_ioctl(bdev, mode, cmd, arg);
unlock_kernel();
return ret;
}
static struct block_device_operations GLOB_SBD_ops = {
.owner = THIS_MODULE,
.open = GLOB_SBD_open,
.release = GLOB_SBD_release,
.locked_ioctl = GLOB_SBD_ioctl,
.ioctl = GLOB_SBD_unlocked_ioctl,
.getgeo = GLOB_SBD_getgeo,
};
@ -650,8 +654,7 @@ static int SBD_setup_device(struct spectra_nand_dev *dev, int which)
/* Here we force report 512 byte hardware sector size to Kernel */
blk_queue_logical_block_size(dev->queue, 512);
blk_queue_ordered(dev->queue, QUEUE_ORDERED_DRAIN_FLUSH,
SBD_prepare_flush);
blk_queue_ordered(dev->queue, QUEUE_ORDERED_DRAIN_FLUSH);
dev->thread = kthread_run(spectra_trans_thread, dev, "nand_thd");
if (IS_ERR(dev->thread)) {

View File

@ -61,7 +61,6 @@ static void FTL_Cache_Read_Page(u8 *pData, u64 dwPageAddr,
static void FTL_Cache_Write_Page(u8 *pData, u64 dwPageAddr,
u8 cache_blk, u16 flag);
static int FTL_Cache_Write(void);
static int FTL_Cache_Write_Back(u8 *pData, u64 blk_addr);
static void FTL_Calculate_LRU(void);
static u32 FTL_Get_Block_Index(u32 wBlockNum);
@ -86,8 +85,6 @@ static u32 FTL_Replace_MWBlock(void);
static int FTL_Replace_Block(u64 blk_addr);
static int FTL_Adjust_Relative_Erase_Count(u32 Index_of_MAX);
static int FTL_Flash_Error_Handle(u8 *pData, u64 old_page_addr, u64 blk_addr);
struct device_info_tag DeviceInfo;
struct flash_cache_tag Cache;
static struct spectra_l2_cache_info cache_l2;
@ -775,7 +772,7 @@ static void dump_cache_l2_table(void)
{
struct list_head *p;
struct spectra_l2_cache_list *pnd;
int n, i;
int n;
n = 0;
list_for_each(p, &cache_l2.table.list) {
@ -1537,79 +1534,6 @@ static int FTL_Cache_Write_All(u8 *pData, u64 blk_addr)
return wResult;
}
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
* Function: FTL_Cache_Update_Block
* Inputs: pointer to buffer,page address,block address
* Outputs: PASS=0 / FAIL=1
* Description: It updates the cache
*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
static int FTL_Cache_Update_Block(u8 *pData,
u64 old_page_addr, u64 blk_addr)
{
int i, j;
u8 *buf = pData;
int wResult = PASS;
int wFoundInCache;
u64 page_addr;
u64 addr;
u64 old_blk_addr;
u16 page_offset;
nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
__FILE__, __LINE__, __func__);
old_blk_addr = (u64)(old_page_addr >>
DeviceInfo.nBitsInBlockDataSize) * DeviceInfo.wBlockDataSize;
page_offset = (u16)(GLOB_u64_Remainder(old_page_addr, 2) >>
DeviceInfo.nBitsInPageDataSize);
for (i = 0; i < DeviceInfo.wPagesPerBlock; i += Cache.pages_per_item) {
page_addr = old_blk_addr + i * DeviceInfo.wPageDataSize;
if (i != page_offset) {
wFoundInCache = FAIL;
for (j = 0; j < CACHE_ITEM_NUM; j++) {
addr = Cache.array[j].address;
addr = FTL_Get_Physical_Block_Addr(addr) +
GLOB_u64_Remainder(addr, 2);
if ((addr >= page_addr) && addr <
(page_addr + Cache.cache_item_size)) {
wFoundInCache = PASS;
buf = Cache.array[j].buf;
Cache.array[j].changed = SET;
#if CMD_DMA
#if RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE
int_cache[ftl_cmd_cnt].item = j;
int_cache[ftl_cmd_cnt].cache.address =
Cache.array[j].address;
int_cache[ftl_cmd_cnt].cache.changed =
Cache.array[j].changed;
#endif
#endif
break;
}
}
if (FAIL == wFoundInCache) {
if (ERR == FTL_Cache_Read_All(g_pTempBuf,
page_addr)) {
wResult = FAIL;
break;
}
buf = g_pTempBuf;
}
} else {
buf = pData;
}
if (FAIL == FTL_Cache_Write_All(buf,
blk_addr + (page_addr - old_blk_addr))) {
wResult = FAIL;
break;
}
}
return wResult;
}
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
* Function: FTL_Copy_Block
* Inputs: source block address
@ -1698,7 +1622,7 @@ static int get_l2_cache_blks(void)
static int erase_l2_cache_blocks(void)
{
int i, ret = PASS;
u32 pblk, lblk;
u32 pblk, lblk = BAD_BLOCK;
u64 addr;
u32 *pbt = (u32 *)g_pBlockTable;
@ -2004,87 +1928,6 @@ static int search_l2_cache(u8 *buf, u64 logical_addr)
return ret;
}
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
* Function: FTL_Cache_Write_Back
* Inputs: pointer to data cached in sys memory
* address of free block in flash
* Outputs: PASS=0 / FAIL=1
* Description: writes all the pages of Cache Block to flash
*
*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
static int FTL_Cache_Write_Back(u8 *pData, u64 blk_addr)
{
int i, j, iErase;
u64 old_page_addr, addr, phy_addr;
u32 *pbt = (u32 *)g_pBlockTable;
u32 lba;
nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
__FILE__, __LINE__, __func__);
old_page_addr = FTL_Get_Physical_Block_Addr(blk_addr) +
GLOB_u64_Remainder(blk_addr, 2);
iErase = (FAIL == FTL_Replace_Block(blk_addr)) ? PASS : FAIL;
pbt[BLK_FROM_ADDR(blk_addr)] &= (~SPARE_BLOCK);
#if CMD_DMA
p_BTableChangesDelta = (struct BTableChangesDelta *)g_pBTDelta_Free;
g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
p_BTableChangesDelta->ftl_cmd_cnt = ftl_cmd_cnt;
p_BTableChangesDelta->BT_Index = (u32)(blk_addr >>
DeviceInfo.nBitsInBlockDataSize);
p_BTableChangesDelta->BT_Entry_Value =
pbt[(u32)(blk_addr >> DeviceInfo.nBitsInBlockDataSize)];
p_BTableChangesDelta->ValidFields = 0x0C;
#endif
if (IN_PROGRESS_BLOCK_TABLE != g_cBlockTableStatus) {
g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
FTL_Write_IN_Progress_Block_Table_Page();
}
for (i = 0; i < RETRY_TIMES; i++) {
if (PASS == iErase) {
phy_addr = FTL_Get_Physical_Block_Addr(blk_addr);
if (FAIL == GLOB_FTL_Block_Erase(phy_addr)) {
lba = BLK_FROM_ADDR(blk_addr);
MARK_BLOCK_AS_BAD(pbt[lba]);
i = RETRY_TIMES;
break;
}
}
for (j = 0; j < CACHE_ITEM_NUM; j++) {
addr = Cache.array[j].address;
if ((addr <= blk_addr) &&
((addr + Cache.cache_item_size) > blk_addr))
cache_block_to_write = j;
}
phy_addr = FTL_Get_Physical_Block_Addr(blk_addr);
if (PASS == FTL_Cache_Update_Block(pData,
old_page_addr, phy_addr)) {
cache_block_to_write = UNHIT_CACHE_ITEM;
break;
} else {
iErase = PASS;
}
}
if (i >= RETRY_TIMES) {
if (ERR == FTL_Flash_Error_Handle(pData,
old_page_addr, blk_addr))
return ERR;
else
return FAIL;
}
return PASS;
}
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
* Function: FTL_Cache_Write_Page
* Inputs: Pointer to buffer, page address, cache block number
@ -2370,159 +2213,6 @@ static int FTL_Write_Block_Table(int wForce)
return 1;
}
/******************************************************************
* Function: GLOB_FTL_Flash_Format
* Inputs: none
* Outputs: PASS
* Description: The block table stores bad block info, including MDF+
* blocks gone bad over the ages. Therefore, if we have a
* block table in place, then use it to scan for bad blocks
* If not, then scan for MDF.
* Now, a block table will only be found if spectra was already
* being used. For a fresh flash, we'll go thru scanning for
* MDF. If spectra was being used, then there is a chance that
* the MDF has been corrupted. Spectra avoids writing to the
* first 2 bytes of the spare area to all pages in a block. This
* covers all known flash devices. However, since flash
* manufacturers have no standard of where the MDF is stored,
* this cannot guarantee that the MDF is protected for future
* devices too. The initial scanning for the block table assures
* this. It is ok even if the block table is outdated, as all
* we're looking for are bad block markers.
* Use this when mounting a file system or starting a
* new flash.
*
*********************************************************************/
static int FTL_Format_Flash(u8 valid_block_table)
{
u32 i, j;
u32 *pbt = (u32 *)g_pBlockTable;
u32 tempNode;
int ret;
#if CMD_DMA
u32 *pbtStartingCopy = (u32 *)g_pBTStartingCopy;
if (ftl_cmd_cnt)
return FAIL;
#endif
if (FAIL == FTL_Check_Block_Table(FAIL))
valid_block_table = 0;
if (valid_block_table) {
u8 switched = 1;
u32 block, k;
k = DeviceInfo.wSpectraStartBlock;
while (switched && (k < DeviceInfo.wSpectraEndBlock)) {
switched = 0;
k++;
for (j = DeviceInfo.wSpectraStartBlock, i = 0;
j <= DeviceInfo.wSpectraEndBlock;
j++, i++) {
block = (pbt[i] & ~BAD_BLOCK) -
DeviceInfo.wSpectraStartBlock;
if (block != i) {
switched = 1;
tempNode = pbt[i];
pbt[i] = pbt[block];
pbt[block] = tempNode;
}
}
}
if ((k == DeviceInfo.wSpectraEndBlock) && switched)
valid_block_table = 0;
}
if (!valid_block_table) {
memset(g_pBlockTable, 0,
DeviceInfo.wDataBlockNum * sizeof(u32));
memset(g_pWearCounter, 0,
DeviceInfo.wDataBlockNum * sizeof(u8));
if (DeviceInfo.MLCDevice)
memset(g_pReadCounter, 0,
DeviceInfo.wDataBlockNum * sizeof(u16));
#if CMD_DMA
memset(g_pBTStartingCopy, 0,
DeviceInfo.wDataBlockNum * sizeof(u32));
memset(g_pWearCounterCopy, 0,
DeviceInfo.wDataBlockNum * sizeof(u8));
if (DeviceInfo.MLCDevice)
memset(g_pReadCounterCopy, 0,
DeviceInfo.wDataBlockNum * sizeof(u16));
#endif
for (j = DeviceInfo.wSpectraStartBlock, i = 0;
j <= DeviceInfo.wSpectraEndBlock;
j++, i++) {
if (GLOB_LLD_Get_Bad_Block((u32)j))
pbt[i] = (u32)(BAD_BLOCK | j);
}
}
nand_dbg_print(NAND_DBG_WARN, "Erasing all blocks in the NAND\n");
for (j = DeviceInfo.wSpectraStartBlock, i = 0;
j <= DeviceInfo.wSpectraEndBlock;
j++, i++) {
if ((pbt[i] & BAD_BLOCK) != BAD_BLOCK) {
ret = GLOB_LLD_Erase_Block(j);
if (FAIL == ret) {
pbt[i] = (u32)(j);
MARK_BLOCK_AS_BAD(pbt[i]);
nand_dbg_print(NAND_DBG_WARN,
"NAND Program fail in %s, Line %d, "
"Function: %s, new Bad Block %d generated!\n",
__FILE__, __LINE__, __func__, (int)j);
} else {
pbt[i] = (u32)(SPARE_BLOCK | j);
}
}
#if CMD_DMA
pbtStartingCopy[i] = pbt[i];
#endif
}
g_wBlockTableOffset = 0;
for (i = 0; (i <= (DeviceInfo.wSpectraEndBlock -
DeviceInfo.wSpectraStartBlock))
&& ((pbt[i] & BAD_BLOCK) == BAD_BLOCK); i++)
;
if (i > (DeviceInfo.wSpectraEndBlock - DeviceInfo.wSpectraStartBlock)) {
printk(KERN_ERR "All blocks bad!\n");
return FAIL;
} else {
g_wBlockTableIndex = pbt[i] & ~BAD_BLOCK;
if (i != BLOCK_TABLE_INDEX) {
tempNode = pbt[i];
pbt[i] = pbt[BLOCK_TABLE_INDEX];
pbt[BLOCK_TABLE_INDEX] = tempNode;
}
}
pbt[BLOCK_TABLE_INDEX] &= (~SPARE_BLOCK);
#if CMD_DMA
pbtStartingCopy[BLOCK_TABLE_INDEX] &= (~SPARE_BLOCK);
#endif
g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
memset(g_pBTBlocks, 0xFF,
(1 + LAST_BT_ID - FIRST_BT_ID) * sizeof(u32));
g_pBTBlocks[FIRST_BT_ID-FIRST_BT_ID] = g_wBlockTableIndex;
FTL_Write_Block_Table(FAIL);
for (i = 0; i < CACHE_ITEM_NUM; i++) {
Cache.array[i].address = NAND_CACHE_INIT_ADDR;
Cache.array[i].use_cnt = 0;
Cache.array[i].changed = CLEAR;
}
#if (RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE && CMD_DMA)
memcpy((void *)&cache_start_copy, (void *)&Cache,
sizeof(struct flash_cache_tag));
#endif
return PASS;
}
static int force_format_nand(void)
{
u32 i;
@ -3031,112 +2721,6 @@ static int FTL_Read_Block_Table(void)
return wResult;
}
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
* Function: FTL_Flash_Error_Handle
* Inputs: Pointer to data
* Page address
* Block address
* Outputs: PASS=0 / FAIL=1
* Description: It handles any error occured during Spectra operation
*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
static int FTL_Flash_Error_Handle(u8 *pData, u64 old_page_addr,
u64 blk_addr)
{
u32 i;
int j;
u32 tmp_node, blk_node = BLK_FROM_ADDR(blk_addr);
u64 phy_addr;
int wErase = FAIL;
int wResult = FAIL;
u32 *pbt = (u32 *)g_pBlockTable;
nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
__FILE__, __LINE__, __func__);
if (ERR == GLOB_FTL_Garbage_Collection())
return ERR;
do {
for (i = DeviceInfo.wSpectraEndBlock -
DeviceInfo.wSpectraStartBlock;
i > 0; i--) {
if (IS_SPARE_BLOCK(i)) {
tmp_node = (u32)(BAD_BLOCK |
pbt[blk_node]);
pbt[blk_node] = (u32)(pbt[i] &
(~SPARE_BLOCK));
pbt[i] = tmp_node;
#if CMD_DMA
p_BTableChangesDelta =
(struct BTableChangesDelta *)
g_pBTDelta_Free;
g_pBTDelta_Free +=
sizeof(struct BTableChangesDelta);
p_BTableChangesDelta->ftl_cmd_cnt =
ftl_cmd_cnt;
p_BTableChangesDelta->BT_Index =
blk_node;
p_BTableChangesDelta->BT_Entry_Value =
pbt[blk_node];
p_BTableChangesDelta->ValidFields = 0x0C;
p_BTableChangesDelta =
(struct BTableChangesDelta *)
g_pBTDelta_Free;
g_pBTDelta_Free +=
sizeof(struct BTableChangesDelta);
p_BTableChangesDelta->ftl_cmd_cnt =
ftl_cmd_cnt;
p_BTableChangesDelta->BT_Index = i;
p_BTableChangesDelta->BT_Entry_Value = pbt[i];
p_BTableChangesDelta->ValidFields = 0x0C;
#endif
wResult = PASS;
break;
}
}
if (FAIL == wResult) {
if (FAIL == GLOB_FTL_Garbage_Collection())
break;
else
continue;
}
if (IN_PROGRESS_BLOCK_TABLE != g_cBlockTableStatus) {
g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
FTL_Write_IN_Progress_Block_Table_Page();
}
phy_addr = FTL_Get_Physical_Block_Addr(blk_addr);
for (j = 0; j < RETRY_TIMES; j++) {
if (PASS == wErase) {
if (FAIL == GLOB_FTL_Block_Erase(phy_addr)) {
MARK_BLOCK_AS_BAD(pbt[blk_node]);
break;
}
}
if (PASS == FTL_Cache_Update_Block(pData,
old_page_addr,
phy_addr)) {
wResult = PASS;
break;
} else {
wResult = FAIL;
wErase = PASS;
}
}
} while (FAIL == wResult);
FTL_Write_Block_Table(FAIL);
return wResult;
}
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
* Function: FTL_Get_Page_Num
* Inputs: Size in bytes

View File

@ -723,12 +723,12 @@ int usb_string_ids_tab(struct usb_composite_dev *cdev, struct usb_string *str)
/**
* usb_string_ids_n() - allocate unused string IDs in batch
* @cdev: the device whose string descriptor IDs are being allocated
* @c: the device whose string descriptor IDs are being allocated
* @n: number of string IDs to allocate
* Context: single threaded during gadget setup
*
* Returns the first requested ID. This ID and next @n-1 IDs are now
* valid IDs. At least providind that @n is non zore because if it
* valid IDs. At least provided that @n is non-zero because if it
* is, returns last requested ID which is now very useful information.
*
* @usb_string_ids_n() is called from bind() callbacks to allocate

View File

@ -1609,6 +1609,7 @@ static int __init m66592_probe(struct platform_device *pdev)
/* initialize ucd */
m66592 = kzalloc(sizeof(struct m66592), GFP_KERNEL);
if (m66592 == NULL) {
ret = -ENOMEM;
pr_err("kzalloc error\n");
goto clean_up;
}

View File

@ -1557,6 +1557,7 @@ static int __init r8a66597_probe(struct platform_device *pdev)
/* initialize ucd */
r8a66597 = kzalloc(sizeof(struct r8a66597), GFP_KERNEL);
if (r8a66597 == NULL) {
ret = -ENOMEM;
printk(KERN_ERR "kzalloc error\n");
goto clean_up;
}

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