Commit 2e4e0292 authored by Richard Henderson's avatar Richard Henderson

Merge kanga.twiddle.net:/home/rth/linux/linus-2.5

into kanga.twiddle.net:/home/rth/linux/alt
parents c62d4408 9e12ea16
Tools that manage md devices can be found at Tools that manage md devices can be found at
http://www.<country>.kernel.org/pub/linux/daemons/raid/.... http://www.<country>.kernel.org/pub/linux/utils/raid/....
You can boot (if you selected boot support in the configuration) with your md You can boot with your md device with the following kernel command
device with the following kernel command lines: lines:
for old raid arrays without persistent superblocks: for old raid arrays without persistent superblocks:
md=<md device no.>,<raid level>,<chunk size factor>,<fault level>,dev0,dev1,...,devn md=<md device no.>,<raid level>,<chunk size factor>,<fault level>,dev0,dev1,...,devn
...@@ -34,3 +34,63 @@ A possible loadlin line (Harald Hoyer <HarryH@Royal.Net>) looks like this: ...@@ -34,3 +34,63 @@ A possible loadlin line (Harald Hoyer <HarryH@Royal.Net>) looks like this:
e:\loadlin\loadlin e:\zimage root=/dev/md0 md=0,0,4,0,/dev/hdb2,/dev/hdc3 ro e:\loadlin\loadlin e:\zimage root=/dev/md0 md=0,0,4,0,/dev/hdb2,/dev/hdc3 ro
-------------------------------
The md driver can support a variety of different superblock formats.
(It doesn't yet, but it can)
The kernel does *NOT* autodetect which format superblock is being
used. It must be told.
Superblock format '0' is treated differently to others for legacy
reasons.
General Rules - apply for all superblock formats
------------------------------------------------
An array is 'created' by writing appropriate superblocks to all
devices.
It is 'assembled' by associating each of these devices with an
particular md virtual device. Once it is completely assembled, it can
be accessed.
An array should be created by a user-space tool. This will write
superblocks to all devices. It will usually mark the array as
'unclean', or with some devices missing so that the kernel md driver
can create approrpriate redundancy (copying in raid1, parity
calculation in raid4/5).
When an array is assembled, it is first initialised with the
SET_ARRAY_INFO ioctl. This contains, in particular, a major and minor
version number. The major version number selects which superblock
format is to be used. The minor number might be used to tune handling
of the format, such as suggesting where on each device to look for the
superblock.
Then each device is added using the ADD_NEW_DISK ioctl. This
provides, in particular, a major and minor number identifying the
device to add.
The array is started with the RUN_ARRAY ioctl.
Once started, new devices can be added. They should have an
appropriate superblock written to them, and then passed be in with
ADD_NEW_DISK.
Devices that have failed or are not yet active can be detached from an
array using HOT_REMOVE_DISK.
Specific Rules that apply to format-0 super block arrays, and
arrays with no superblock (non-presistant).
-------------------------------------------------------------
An array can be 'created' by describing the array (level, chunksize
etc) in a SET_ARRAY_INFO ioctl. This must has major_version==0 and
raid_disks != 0.
Then uninitialised devices can be added with ADD_NEW_DISK. The
structure passed to ADD_NEW_DISK must specify the state of the device
and it's role in the array.
One started with RUN_ARRAY, uninitialised spares can be added with
HOT_ADD_DISK.
...@@ -248,6 +248,37 @@ static void __init winchip2_protect_mcr(void) ...@@ -248,6 +248,37 @@ static void __init winchip2_protect_mcr(void)
} }
#endif #endif
static void __init init_c3(struct cpuinfo_x86 *c)
{
u32 lo, hi;
/* Test for Centaur Extended Feature Flags presence */
if (cpuid_eax(0xC0000000) >= 0xC0000001) {
/* store Centaur Extended Feature Flags as
* word 5 of the CPU capability bit array
*/
c->x86_capability[5] = cpuid_edx(0xC0000001);
}
switch (c->x86_model) {
case 6 ... 8: /* Cyrix III family */
rdmsr (MSR_VIA_FCR, lo, hi);
lo |= (1<<1 | 1<<7); /* Report CX8 & enable PGE */
wrmsr (MSR_VIA_FCR, lo, hi);
set_bit(X86_FEATURE_CX8, c->x86_capability);
set_bit(X86_FEATURE_3DNOW, c->x86_capability);
/* fall through */
case 9: /* Nehemiah */
default:
get_model_name(c);
display_cacheinfo(c);
break;
}
}
static void __init init_centaur(struct cpuinfo_x86 *c) static void __init init_centaur(struct cpuinfo_x86 *c)
{ {
enum { enum {
...@@ -386,21 +417,7 @@ static void __init init_centaur(struct cpuinfo_x86 *c) ...@@ -386,21 +417,7 @@ static void __init init_centaur(struct cpuinfo_x86 *c)
break; break;
case 6: case 6:
switch (c->x86_model) { init_c3(c);
case 6 ... 8: /* Cyrix III family */
rdmsr (MSR_VIA_FCR, lo, hi);
lo |= (1<<1 | 1<<7); /* Report CX8 & enable PGE */
wrmsr (MSR_VIA_FCR, lo, hi);
set_bit(X86_FEATURE_CX8, c->x86_capability);
set_bit(X86_FEATURE_3DNOW, c->x86_capability);
case 9: /* Nehemiah */
default:
get_model_name(c);
display_cacheinfo(c);
break;
}
break; break;
} }
} }
......
...@@ -211,9 +211,10 @@ void __init generic_identify(struct cpuinfo_x86 * c) ...@@ -211,9 +211,10 @@ void __init generic_identify(struct cpuinfo_x86 * c)
/* Intel-defined flags: level 0x00000001 */ /* Intel-defined flags: level 0x00000001 */
if ( c->cpuid_level >= 0x00000001 ) { if ( c->cpuid_level >= 0x00000001 ) {
u32 capability; u32 capability, excap;
cpuid(0x00000001, &tfms, &junk, &junk, &capability); cpuid(0x00000001, &tfms, &junk, &excap, &capability);
c->x86_capability[0] = capability; c->x86_capability[0] = capability;
c->x86_capability[4] = excap;
c->x86 = (tfms >> 8) & 15; c->x86 = (tfms >> 8) & 15;
c->x86_model = (tfms >> 4) & 15; c->x86_model = (tfms >> 4) & 15;
c->x86_mask = tfms & 15; c->x86_mask = tfms & 15;
......
...@@ -37,7 +37,20 @@ static int show_cpuinfo(struct seq_file *m, void *v) ...@@ -37,7 +37,20 @@ static int show_cpuinfo(struct seq_file *m, void *v)
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* Other (Linux-defined) */ /* Other (Linux-defined) */
"cxmmx", "k6_mtrr", "cyrix_arr", "centaur_mcr", NULL, NULL, NULL, NULL, "cxmmx", "k6_mtrr", "cyrix_arr", "centaur_mcr",
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* Intel-defined (#2) */
"pni", NULL, NULL, "monitor", "ds_cpl", NULL, NULL, NULL,
"tm2", NULL, "cnxt_id", NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* VIA/Cyrix/Centaur-defined */
NULL, NULL, "xstore", NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/module.h>
#include <linux/apm_bios.h> #include <linux/apm_bios.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -893,3 +894,5 @@ void __init dmi_scan_machine(void) ...@@ -893,3 +894,5 @@ void __init dmi_scan_machine(void)
if(err == 0) if(err == 0)
dmi_check_blacklist(); dmi_check_blacklist();
} }
EXPORT_SYMBOL(is_unsafe_smbus);
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
* trini@mvista.com * trini@mvista.com
* Derived from arch/ppc/boot/prep/head.S (Cort Dougan, many others). * Derived from arch/ppc/boot/prep/head.S (Cort Dougan, many others).
* *
* 2001 (c) MontaVista, Software, Inc. This file is licensed under * 2001-2003 (c) MontaVista, Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program * the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express * is licensed "as is" without any warranty of any kind, whether express
* or implied. * or implied.
...@@ -98,7 +98,7 @@ _setup_L2CR: ...@@ -98,7 +98,7 @@ _setup_L2CR:
isync isync
mfspr r8,L2CR mfspr r8,L2CR
rlwinm r8,r8,0,1,31 rlwinm r8,r8,0,1,31
oris r8,r8,0x0020 oris r8,r8,L2CR_L2I@h
sync sync
isync isync
mtspr L2CR,r8 mtspr L2CR,r8
...@@ -106,11 +106,25 @@ _setup_L2CR: ...@@ -106,11 +106,25 @@ _setup_L2CR:
isync isync
/* Wait for the invalidation to complete */ /* Wait for the invalidation to complete */
1: mfspr r8,L2CR mfspr r8,PVR
rlwinm. r9,r8,0,31,31 srwi r8,r8,16
cmpli cr0,r8,0x8000 /* 7450 */
cmpli cr1,r8,0x8001 /* 7455 */
cmpli cr2,r8,0x8002 /* 7457 */
cror 4*cr0+eq,4*cr0+eq,4*cr1+eq /* Now test if any are true. */
cror 4*cr0+eq,4*cr0+eq,4*cr2+eq
bne 2f
1: mfspr r8,L2CR /* On 745x, poll L2I bit (bit 10) */
rlwinm. r9,r8,0,10,10
bne 1b bne 1b
b 3f
2: mfspr r8,L2CR /* On 75x & 74[01]0, poll L2IP bit (bit 31) */
rlwinm. r9,r8,0,31,31
bne 2b
rlwinm r8,r8,0,11,9 /* Turn off L2I bit */ 3: rlwinm r8,r8,0,11,9 /* Turn off L2I bit */
sync sync
isync isync
mtspr L2CR,r8 mtspr L2CR,r8
...@@ -118,6 +132,33 @@ _setup_L2CR: ...@@ -118,6 +132,33 @@ _setup_L2CR:
isync isync
blr blr
.globl _setup_L3CR
_setup_L3CR:
/* Invalidate/disable L3 cache */
sync
isync
mfspr r8,L3CR
rlwinm r8,r8,0,1,31
ori r8,r8,L3CR_L3I@l
sync
isync
mtspr L3CR,r8
sync
isync
/* Wait for the invalidation to complete */
1: mfspr r8,L3CR
rlwinm. r9,r8,0,21,21
bne 1b
rlwinm r8,r8,0,22,20 /* Turn off L3I bit */
sync
isync
mtspr L3CR,r8
sync
isync
blr
/* /*
* Delay for a number of microseconds * Delay for a number of microseconds
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* trini@mvista.com * trini@mvista.com
* Derived from arch/ppc/boot/prep/head.S (Cort Dougan, many others). * Derived from arch/ppc/boot/prep/head.S (Cort Dougan, many others).
* *
* 2001 (c) MontaVista, Software, Inc. This file is licensed under * 2001-2003 (c) MontaVista, Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program * the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express * is licensed "as is" without any warranty of any kind, whether express
* or implied. * or implied.
...@@ -74,6 +74,17 @@ start_: ...@@ -74,6 +74,17 @@ start_:
#if defined(CONFIG_FORCE) || defined(CONFIG_K2) \ #if defined(CONFIG_FORCE) || defined(CONFIG_K2) \
|| defined(CONFIG_EV64260) || defined(CONFIG_PAL4) || defined(CONFIG_EV64260) || defined(CONFIG_PAL4)
bl _setup_L2CR bl _setup_L2CR
/* If 745x, turn off L3CR as well */
mfspr r8,PVR
srwi r8,r8,16
cmpli cr0,r8,0x8000 /* 7450 */
cmpli cr1,r8,0x8001 /* 7455 */
cmpli cr2,r8,0x8002 /* 7457 */
cror 4*cr0+eq,4*cr0+eq,4*cr1+eq /* Now test if any are true. */
cror 4*cr0+eq,4*cr0+eq,4*cr2+eq
beql _setup_L3CR
#endif #endif
#endif #endif
......
...@@ -684,7 +684,7 @@ static void register_irq_proc (unsigned int irq) ...@@ -684,7 +684,7 @@ static void register_irq_proc (unsigned int irq)
struct proc_dir_entry *entry; struct proc_dir_entry *entry;
char name [MAX_NAMELEN]; char name [MAX_NAMELEN];
if (!root_irq_dir || (irq_desc[irq].handler == NULL)) if (!root_irq_dir || (irq_desc[irq].handler == NULL) || irq_dir[irq])
return; return;
memset(name, 0, MAX_NAMELEN); memset(name, 0, MAX_NAMELEN);
......
...@@ -420,18 +420,6 @@ static void kgdb_flush_cache_all(void) ...@@ -420,18 +420,6 @@ static void kgdb_flush_cache_all(void)
flush_instruction_cache(); flush_instruction_cache();
} }
static inline int get_msr(void)
{
int msr;
asm volatile("mfmsr %0" : "=r" (msr):);
return msr;
}
static inline void set_msr(int msr)
{
asm volatile("mtmsr %0" : : "r" (msr));
}
/* Set up exception handlers for tracing and breakpoints /* Set up exception handlers for tracing and breakpoints
* [could be called kgdb_init()] * [could be called kgdb_init()]
*/ */
...@@ -598,8 +586,8 @@ handle_exception (struct pt_regs *regs) ...@@ -598,8 +586,8 @@ handle_exception (struct pt_regs *regs)
kgdb_interruptible(0); kgdb_interruptible(0);
lock_kernel(); lock_kernel();
msr = get_msr(); msr = mfmsr();
set_msr(msr & ~MSR_EE); /* disable interrupts */ mtmsr(msr & ~MSR_EE); /* disable interrupts */
if (regs->nip == (unsigned long)breakinst) { if (regs->nip == (unsigned long)breakinst) {
/* Skip over breakpoint trap insn */ /* Skip over breakpoint trap insn */
...@@ -626,7 +614,7 @@ handle_exception (struct pt_regs *regs) ...@@ -626,7 +614,7 @@ handle_exception (struct pt_regs *regs)
*ptr++ = hexchars[SP_REGNUM >> 4]; *ptr++ = hexchars[SP_REGNUM >> 4];
*ptr++ = hexchars[SP_REGNUM & 0xf]; *ptr++ = hexchars[SP_REGNUM & 0xf];
*ptr++ = ':'; *ptr++ = ':';
ptr = mem2hex(((char *)&regs) + SP_REGNUM*4, ptr, 4); ptr = mem2hex(((char *)regs) + SP_REGNUM*4, ptr, 4);
*ptr++ = ';'; *ptr++ = ';';
#endif #endif
...@@ -786,7 +774,7 @@ handle_exception (struct pt_regs *regs) ...@@ -786,7 +774,7 @@ handle_exception (struct pt_regs *regs)
strcpy(remcomOutBuffer, "OK"); strcpy(remcomOutBuffer, "OK");
putpacket(remcomOutBuffer); putpacket(remcomOutBuffer);
#endif #endif
set_msr(msr); mtmsr(msr);
kgdb_interruptible(1); kgdb_interruptible(1);
unlock_kernel(); unlock_kernel();
...@@ -802,10 +790,9 @@ handle_exception (struct pt_regs *regs) ...@@ -802,10 +790,9 @@ handle_exception (struct pt_regs *regs)
#if defined(CONFIG_40x) #if defined(CONFIG_40x)
regs->msr |= MSR_DE; regs->msr |= MSR_DE;
regs->dbcr0 |= (DBCR0_IDM | DBCR0_IC); regs->dbcr0 |= (DBCR0_IDM | DBCR0_IC);
set_msr(msr); mtmsr(msr);
#else #else
regs->msr |= MSR_SE; regs->msr |= MSR_SE;
set_msr(msr | MSR_SE);
#endif #endif
unlock_kernel(); unlock_kernel();
kgdb_active = 0; kgdb_active = 0;
......
...@@ -320,6 +320,24 @@ release_thread(struct task_struct *t) ...@@ -320,6 +320,24 @@ release_thread(struct task_struct *t)
{ {
} }
/*
* This gets called before we allocate a new thread and copy
* the current task into it.
*/
void prepare_to_copy(struct task_struct *tsk)
{
struct pt_regs *regs = tsk->thread.regs;
if (regs == NULL)
return;
if (regs->msr & MSR_FP)
giveup_fpu(current);
#ifdef CONFIG_ALTIVEC
if (regs->msr & MSR_VEC)
giveup_altivec(current);
#endif /* CONFIG_ALTIVEC */
}
/* /*
* Copy a thread.. * Copy a thread..
*/ */
...@@ -348,6 +366,8 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp, ...@@ -348,6 +366,8 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
} else { } else {
childregs->gpr[1] = usp; childregs->gpr[1] = usp;
p->thread.regs = childregs; p->thread.regs = childregs;
if (clone_flags & CLONE_SETTLS)
childregs->gpr[2] = childregs->gpr[6];
} }
childregs->gpr[3] = 0; /* Result from fork() */ childregs->gpr[3] = 0; /* Result from fork() */
sp -= STACK_FRAME_OVERHEAD; sp -= STACK_FRAME_OVERHEAD;
...@@ -367,29 +387,6 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp, ...@@ -367,29 +387,6 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
p->thread.ksp = sp; p->thread.ksp = sp;
kregs->nip = (unsigned long)ret_from_fork; kregs->nip = (unsigned long)ret_from_fork;
/*
* copy fpu info - assume lazy fpu switch now always
* -- Cort
*/
if (regs->msr & MSR_FP) {
giveup_fpu(current);
childregs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1);
}
memcpy(&p->thread.fpr, &current->thread.fpr, sizeof(p->thread.fpr));
p->thread.fpscr = current->thread.fpscr;
#ifdef CONFIG_ALTIVEC
/*
* copy altiVec info - assume lazy altiVec switch
* - kumar
*/
if (regs->msr & MSR_VEC)
giveup_altivec(current);
memcpy(&p->thread.vr, &current->thread.vr, sizeof(p->thread.vr));
p->thread.vscr = current->thread.vscr;
childregs->msr &= ~MSR_VEC;
#endif /* CONFIG_ALTIVEC */
p->thread.last_syscall = -1; p->thread.last_syscall = -1;
return 0; return 0;
...@@ -444,15 +441,17 @@ int get_fpexc_mode(struct task_struct *tsk, unsigned long adr) ...@@ -444,15 +441,17 @@ int get_fpexc_mode(struct task_struct *tsk, unsigned long adr)
return put_user(val, (unsigned int *) adr); return put_user(val, (unsigned int *) adr);
} }
int sys_clone(int p1, int p2, int p3, int p4, int p5, int p6, int sys_clone(unsigned long clone_flags, unsigned long usp, int *parent_tidp,
void *child_threadptr, int *child_tidp, int p6,
struct pt_regs *regs) struct pt_regs *regs)
{ {
struct task_struct *p; struct task_struct *p;
CHECK_FULL_REGS(regs); CHECK_FULL_REGS(regs);
if (p2 == 0) if (usp == 0)
p2 = regs->gpr[1]; /* stack pointer for child */ usp = regs->gpr[1]; /* stack pointer for child */
p = do_fork(p1 & ~CLONE_IDLETASK, p2, regs, 0, (int *)p3, (int *)p4); p = do_fork(clone_flags & ~CLONE_IDLETASK, usp, regs, 0,
parent_tidp, child_tidp);
return IS_ERR(p) ? PTR_ERR(p) : p->pid; return IS_ERR(p) ? PTR_ERR(p) : p->pid;
} }
......
...@@ -56,6 +56,41 @@ void bad_page_fault(struct pt_regs *, unsigned long, int sig); ...@@ -56,6 +56,41 @@ void bad_page_fault(struct pt_regs *, unsigned long, int sig);
void do_page_fault(struct pt_regs *, unsigned long, unsigned long); void do_page_fault(struct pt_regs *, unsigned long, unsigned long);
extern int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep); extern int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep);
/*
* Check whether the instruction at regs->nip is a store using
* an update addressing form which will update r1.
*/
static int store_updates_sp(struct pt_regs *regs)
{
unsigned int inst;
if (get_user(inst, (unsigned int *)regs->nip))
return 0;
/* check for 1 in the rA field */
if (((inst >> 16) & 0x1f) != 1)
return 0;
/* check major opcode */
switch (inst >> 26) {
case 37: /* stwu */
case 39: /* stbu */
case 45: /* sthu */
case 53: /* stfsu */
case 55: /* stfdu */
return 1;
case 31:
/* check minor opcode */
switch ((inst >> 1) & 0x3ff) {
case 183: /* stwux */
case 247: /* stbux */
case 439: /* sthux */
case 695: /* stfsux */
case 759: /* stfdux */
return 1;
}
}
return 0;
}
/* /*
* For 600- and 800-family processors, the error_code parameter is DSISR * For 600- and 800-family processors, the error_code parameter is DSISR
* for a data fault, SRR1 for an instruction fault. For 400-family processors * for a data fault, SRR1 for an instruction fault. For 400-family processors
...@@ -112,6 +147,40 @@ void do_page_fault(struct pt_regs *regs, unsigned long address, ...@@ -112,6 +147,40 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
goto good_area; goto good_area;
if (!(vma->vm_flags & VM_GROWSDOWN)) if (!(vma->vm_flags & VM_GROWSDOWN))
goto bad_area; goto bad_area;
if (!is_write)
goto bad_area;
/*
* N.B. The rs6000/xcoff ABI allows programs to access up to
* a few hundred bytes below the stack pointer.
* The kernel signal delivery code writes up to about 1.5kB
* below the stack pointer (r1) before decrementing it.
* The exec code can write slightly over 640kB to the stack
* before setting the user r1. Thus we allow the stack to
* expand to 1MB without further checks.
*/
if (address + 0x100000 < vma->vm_end) {
/* get user regs even if this fault is in kernel mode */
struct pt_regs *uregs = current->thread.regs;
if (uregs == NULL)
goto bad_area;
/*
* A user-mode access to an address a long way below
* the stack pointer is only valid if the instruction
* is one which would update the stack pointer to the
* address accessed if the instruction completed,
* i.e. either stwu rs,n(r1) or stwux rs,r1,rb
* (or the byte, halfword, float or double forms).
*
* If we don't check this then any write to the area
* between the last mapped region and the stack will
* expand the stack rather than segfaulting.
*/
if (address + 2048 < uregs->gpr[1]
&& (!user_mode(regs) || !store_updates_sp(regs)))
goto bad_area;
}
if (expand_stack(vma, address)) if (expand_stack(vma, address))
goto bad_area; goto bad_area;
......
...@@ -338,6 +338,7 @@ void __init do_init_bootmem(void) ...@@ -338,6 +338,7 @@ void __init do_init_bootmem(void)
min_low_pfn = start >> PAGE_SHIFT; min_low_pfn = start >> PAGE_SHIFT;
max_low_pfn = (PPC_MEMSTART + total_lowmem) >> PAGE_SHIFT; max_low_pfn = (PPC_MEMSTART + total_lowmem) >> PAGE_SHIFT;
max_pfn = (PPC_MEMSTART + total_memory) >> PAGE_SHIFT;
boot_mapsize = init_bootmem_node(&contig_page_data, min_low_pfn, boot_mapsize = init_bootmem_node(&contig_page_data, min_low_pfn,
PPC_MEMSTART >> PAGE_SHIFT, PPC_MEMSTART >> PAGE_SHIFT,
max_low_pfn); max_low_pfn);
......
...@@ -324,7 +324,7 @@ lopec_setup_arch(void) ...@@ -324,7 +324,7 @@ lopec_setup_arch(void)
ROOT_DEV = Root_SDA1; ROOT_DEV = Root_SDA1;
#endif #endif
#ifdef CONFIG_DUMMY_CONSOLE #ifdef CONFIG_VT
conswitchp = &dummy_con; conswitchp = &dummy_con;
#endif #endif
#ifdef CONFIG_PPCBUG_NVRAM #ifdef CONFIG_PPCBUG_NVRAM
...@@ -378,7 +378,7 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, ...@@ -378,7 +378,7 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_md.nvram_read_val = todc_direct_read_val; ppc_md.nvram_read_val = todc_direct_read_val;
ppc_md.nvram_write_val = todc_direct_write_val; ppc_md.nvram_write_val = todc_direct_write_val;
#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_ID_MODULE) #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
ppc_ide_md.default_irq = lopec_ide_default_irq; ppc_ide_md.default_irq = lopec_ide_default_irq;
ppc_ide_md.default_io_base = lopec_ide_default_io_base; ppc_ide_md.default_io_base = lopec_ide_default_io_base;
ppc_ide_md.ide_init_hwif = lopec_ide_init_hwif_ports; ppc_ide_md.ide_init_hwif = lopec_ide_init_hwif_ports;
......
...@@ -580,14 +580,19 @@ void openpic_request_IPIs(void) ...@@ -580,14 +580,19 @@ void openpic_request_IPIs(void)
if (OpenPIC == NULL) if (OpenPIC == NULL)
return; return;
/* IPIs are marked SA_INTERRUPT as they must run with irqs disabled */
request_irq(OPENPIC_VEC_IPI+open_pic_irq_offset, request_irq(OPENPIC_VEC_IPI+open_pic_irq_offset,
openpic_ipi_action, 0, "IPI0 (call function)", 0); openpic_ipi_action, SA_INTERRUPT,
"IPI0 (call function)", 0);
request_irq(OPENPIC_VEC_IPI+open_pic_irq_offset+1, request_irq(OPENPIC_VEC_IPI+open_pic_irq_offset+1,
openpic_ipi_action, 0, "IPI1 (reschedule)", 0); openpic_ipi_action, SA_INTERRUPT,
"IPI1 (reschedule)", 0);
request_irq(OPENPIC_VEC_IPI+open_pic_irq_offset+2, request_irq(OPENPIC_VEC_IPI+open_pic_irq_offset+2,
openpic_ipi_action, 0, "IPI2 (invalidate tlb)", 0); openpic_ipi_action, SA_INTERRUPT,
"IPI2 (invalidate tlb)", 0);
request_irq(OPENPIC_VEC_IPI+open_pic_irq_offset+3, request_irq(OPENPIC_VEC_IPI+open_pic_irq_offset+3,
openpic_ipi_action, 0, "IPI3 (xmon break)", 0); openpic_ipi_action, SA_INTERRUPT,
"IPI3 (xmon break)", 0);
for ( i = 0; i < OPENPIC_NUM_IPI ; i++ ) for ( i = 0; i < OPENPIC_NUM_IPI ; i++ )
openpic_enable_ipi(OPENPIC_VEC_IPI+open_pic_irq_offset+i); openpic_enable_ipi(OPENPIC_VEC_IPI+open_pic_irq_offset+i);
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
static struct device legacy_bus = { struct device legacy_bus = {
.name = "legacy bus", .name = "legacy bus",
.bus_id = "legacy", .bus_id = "legacy",
}; };
...@@ -75,5 +75,7 @@ int __init platform_bus_init(void) ...@@ -75,5 +75,7 @@ int __init platform_bus_init(void)
return bus_register(&platform_bus_type); return bus_register(&platform_bus_type);
} }
EXPORT_SYMBOL(legacy_bus);
EXPORT_SYMBOL(platform_bus_type);
EXPORT_SYMBOL(platform_device_register); EXPORT_SYMBOL(platform_device_register);
EXPORT_SYMBOL(platform_device_unregister); EXPORT_SYMBOL(platform_device_unregister);
...@@ -709,39 +709,20 @@ config NWFLASH ...@@ -709,39 +709,20 @@ config NWFLASH
If you're not sure, say N. If you're not sure, say N.
config INTEL_RNG config HW_RANDOM
tristate "Intel i8x0 Random Number Generator support" tristate "Intel/AMD/VIA HW Random Number Generator support"
depends on (X86 || IA64) && PCI depends on (X86 || IA64) && PCI
---help--- ---help---
This driver provides kernel-side support for the Random Number This driver provides kernel-side support for the Random Number
Generator hardware found on Intel i8xx-based motherboards. Generator hardware found on Intel i8xx-based motherboards,
AMD 76x-based motherboards, and Via Nehemiah CPUs.
Both a character driver, used to read() entropy data, and a timer Provides a character driver, used to read() entropy data.
function which automatically adds entropy directly into the
kernel pool, are exported by this driver.
To compile this driver as a module ( = code which can be inserted in To compile this driver as a module ( = code which can be inserted in
and removed from the running kernel whenever you want), say M here and removed from the running kernel whenever you want), say M here
and read <file:Documentation/modules.txt>. The module will be called and read <file:Documentation/modules.txt>. The module will be called
i810_rng. hw_random.
If unsure, say N.
config AMD_RNG
tristate "AMD 768 Random Number Generator support"
depends on X86 && PCI
---help---
This driver provides kernel-side support for the Random Number
Generator hardware found on AMD 76x based motherboards.
Both a character driver, used to read() entropy data, and a timer
function which automatically adds entropy directly into the
kernel pool, are exported by this driver.
To compile this driver as a module ( = code which can be inserted in
and removed from the running kernel whenever you want), say M here
and read <file:Documentation/modules.txt>. The module will be called
amd768_rng.
If unsure, say N. If unsure, say N.
......
...@@ -59,8 +59,7 @@ endif ...@@ -59,8 +59,7 @@ endif
obj-$(CONFIG_TOSHIBA) += toshiba.o obj-$(CONFIG_TOSHIBA) += toshiba.o
obj-$(CONFIG_I8K) += i8k.o obj-$(CONFIG_I8K) += i8k.o
obj-$(CONFIG_DS1620) += ds1620.o obj-$(CONFIG_DS1620) += ds1620.o
obj-$(CONFIG_INTEL_RNG) += i810_rng.o obj-$(CONFIG_HW_RANDOM) += hw_random.o
obj-$(CONFIG_AMD_RNG) += amd768_rng.o
obj-$(CONFIG_QIC02_TAPE) += tpqic02.o obj-$(CONFIG_QIC02_TAPE) += tpqic02.o
obj-$(CONFIG_FTAPE) += ftape/ obj-$(CONFIG_FTAPE) += ftape/
obj-$(CONFIG_H8) += h8.o obj-$(CONFIG_H8) += h8.o
......
/*
Hardware driver for the AMD 768 Random Number Generator (RNG)
(c) Copyright 2001 Red Hat Inc <alan@redhat.com>
derived from
Hardware driver for Intel i810 Random Number Generator (RNG)
Copyright 2000,2001 Jeff Garzik <jgarzik@pobox.com>
Copyright 2000,2001 Philipp Rumpf <prumpf@mandrakesoft.com>
Please read Documentation/i810_rng.txt for details on use.
----------------------------------------------------------
This software may be used and distributed according to the terms
of the GNU General Public License, incorporated herein by reference.
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/random.h>
#include <linux/miscdevice.h>
#include <linux/smp_lock.h>
#include <linux/mm.h>
#include <linux/delay.h>
#include <asm/io.h>
#include <asm/uaccess.h>
/*
* core module and version information
*/
#define RNG_VERSION "0.1.0"
#define RNG_MODULE_NAME "amd768_rng"
#define RNG_DRIVER_NAME RNG_MODULE_NAME " hardware driver " RNG_VERSION
#define PFX RNG_MODULE_NAME ": "
/*
* debugging macros
*/
#undef RNG_DEBUG /* define to enable copious debugging info */
#ifdef RNG_DEBUG
/* note: prints function name for you */
#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
#else
#define DPRINTK(fmt, args...)
#endif
#undef RNG_NDEBUG /* define to disable lightweight runtime checks */
#ifdef RNG_NDEBUG
#define assert(expr)
#else
#define assert(expr) \
if(!(expr)) { \
printk( "Assertion failed! %s,%s,%s,line=%d\n", \
#expr,__FILE__,__FUNCTION__,__LINE__); \
}
#endif
#define RNG_MISCDEV_MINOR 183 /* official */
/*
* various RNG status variables. they are globals
* as we only support a single RNG device
*/
static u32 pmbase; /* PMxx I/O base */
static struct semaphore rng_open_sem; /* Semaphore for serializing rng_open/release */
/*
* inlined helper functions for accessing RNG registers
*/
static inline int rng_data_present (void)
{
return inl(pmbase+0xF4) & 1;
}
static inline int rng_data_read (void)
{
return inl(pmbase+0xF0);
}
static int rng_dev_open (struct inode *inode, struct file *filp)
{
if ((filp->f_mode & FMODE_READ) == 0)
return -EINVAL;
if (filp->f_mode & FMODE_WRITE)
return -EINVAL;
/* wait for device to become free */
if (filp->f_flags & O_NONBLOCK) {
if (down_trylock (&rng_open_sem))
return -EAGAIN;
} else {
if (down_interruptible (&rng_open_sem))
return -ERESTARTSYS;
}
return 0;
}
static int rng_dev_release (struct inode *inode, struct file *filp)
{
up(&rng_open_sem);
return 0;
}
static ssize_t rng_dev_read (struct file *filp, char *buf, size_t size,
loff_t * offp)
{
static spinlock_t rng_lock = SPIN_LOCK_UNLOCKED;
int have_data;
u32 data = 0;
ssize_t ret = 0;
while (size) {
spin_lock(&rng_lock);
have_data = 0;
if (rng_data_present()) {
data = rng_data_read();
have_data = 4;
}
spin_unlock (&rng_lock);
while (have_data > 0) {
if (put_user((u8)data, buf++)) {
ret = ret ? : -EFAULT;
break;
}
size--;
ret++;
have_data--;
data>>=8;
}
if (filp->f_flags & O_NONBLOCK)
return ret ? : -EAGAIN;
if(need_resched())
{
current->state = TASK_INTERRUPTIBLE;
schedule_timeout(1);
}
else
udelay(200); /* FIXME: We could poll for 250uS ?? */
if (signal_pending (current))
return ret ? : -ERESTARTSYS;
}
return ret;
}
static struct file_operations rng_chrdev_ops = {
.owner = THIS_MODULE,
.open = rng_dev_open,
.release = rng_dev_release,
.read = rng_dev_read,
};
static struct miscdevice rng_miscdev = {
RNG_MISCDEV_MINOR,
RNG_MODULE_NAME,
&rng_chrdev_ops,
};
/*
* rng_init_one - look for and attempt to init a single RNG
*/
static int __init rng_init_one (struct pci_dev *dev)
{
int rc;
u8 rnen;
DPRINTK ("ENTER\n");
rc = misc_register (&rng_miscdev);
if (rc) {
printk (KERN_ERR PFX "cannot register misc device\n");
DPRINTK ("EXIT, returning %d\n", rc);
goto err_out;
}
pci_read_config_dword(dev, 0x58, &pmbase);
pmbase&=0x0000FF00;
if(pmbase == 0)
{
printk (KERN_ERR PFX "power management base not set\n");
DPRINTK ("EXIT, returning %d\n", rc);
goto err_out_free_miscdev;
}
pci_read_config_byte(dev, 0x40, &rnen);
rnen|=(1<<7); /* RNG on */
pci_write_config_byte(dev, 0x40, rnen);
pci_read_config_byte(dev, 0x41, &rnen);
rnen|=(1<<7); /* PMIO enable */
pci_write_config_byte(dev, 0x41, rnen);
printk(KERN_INFO PFX "AMD768 system management I/O registers at 0x%X.\n", pmbase);
DPRINTK ("EXIT, returning 0\n");
return 0;
err_out_free_miscdev:
misc_deregister (&rng_miscdev);
err_out:
return rc;
}
/*
* Data for PCI driver interface
*
* This data only exists for exporting the supported
* PCI ids via MODULE_DEVICE_TABLE. We do not actually
* register a pci_driver, because someone else might one day
* want to register another driver on the same PCI id.
*/
static struct pci_device_id rng_pci_tbl[] __initdata = {
{ 0x1022, 0x7443, PCI_ANY_ID, PCI_ANY_ID, },
{ 0, },
};
MODULE_DEVICE_TABLE (pci, rng_pci_tbl);
MODULE_AUTHOR("Alan Cox, Jeff Garzik, Philipp Rumpf, Matt Sottek");
MODULE_DESCRIPTION("AMD 768 Random Number Generator (RNG) driver");
MODULE_LICENSE("GPL");
/*
* rng_init - initialize RNG module
*/
static int __init rng_init (void)
{
int rc;
struct pci_dev *pdev;
DPRINTK ("ENTER\n");
init_MUTEX (&rng_open_sem);
pci_for_each_dev(pdev) {
if (pci_match_device (rng_pci_tbl, pdev) != NULL)
goto match;
}
DPRINTK ("EXIT, returning -ENODEV\n");
return -ENODEV;
match:
rc = rng_init_one (pdev);
if (rc)
return rc;
printk (KERN_INFO RNG_DRIVER_NAME " loaded\n");
DPRINTK ("EXIT, returning 0\n");
return 0;
}
/*
* rng_init - shutdown RNG module
*/
static void __exit rng_cleanup (void)
{
DPRINTK ("ENTER\n");
misc_deregister (&rng_miscdev);
DPRINTK ("EXIT\n");
}
module_init (rng_init);
module_exit (rng_cleanup);
...@@ -5,6 +5,20 @@ ...@@ -5,6 +5,20 @@
menu "I2C Hardware Sensors Mainboard support" menu "I2C Hardware Sensors Mainboard support"
config I2C_ALI15X3
tristate " ALI 15x3"
depends on I2C && I2C_PROC && PCI && EXPERIMENTAL
help
If you say yes to this option, support will be included for the
Acer Labs Inc. (ALI) M1514 and M1543 motherboard I2C interfaces.
This can also be built as a module. If so, the module will be
called i2c-ali15x3.
You will also need the latest user-space utilties: you can find them
in the lm_sensors package, which you can download at
http://www.lm-sensors.nu
config I2C_AMD756 config I2C_AMD756
tristate " AMD 756/766" tristate " AMD 756/766"
depends on I2C && I2C_PROC depends on I2C && I2C_PROC
...@@ -39,5 +53,51 @@ config I2C_AMD8111 ...@@ -39,5 +53,51 @@ config I2C_AMD8111
in the lm_sensors package, which you can download at in the lm_sensors package, which you can download at
http://www.lm-sensors.nu http://www.lm-sensors.nu
config I2C_I801
tristate " Intel 801"
depends on I2C && I2C_PROC && PCI && EXPERIMENTAL
help
If you say yes to this option, support will be included for the Intel
801 family of mainboard I2C interfaces. Specifically, the following
versions of the chipset is supported:
82801AA
82801AB
82801BA
82801CA/CAM
82801DB
This can also be built as a module which can be inserted and removed
while the kernel is running. If you want to compile it as a module,
say M here and read <file:Documentation/modules.txt>.
The module will be called i2c-i801.
You will also need the latest user-space utilties: you can find them
in the lm_sensors package, which you can download at
http://www.lm-sensors.nu
config I2C_PIIX4
tristate " Intel PIIX4"
depends on I2C && I2C_PROC && PCI && EXPERIMENTAL
help
If you say yes to this option, support will be included for the Intel
PIIX4 family of mainboard I2C interfaces. Specifically, the following
versions of the chipset is supported:
Intel PIIX4
Intel 440MX
Serverworks OSB4
Serverworks CSB5
SMSC Victory66
This can also be built as a module which can be inserted and removed
while the kernel is running. If you want to compile it as a module,
say M here and read <file:Documentation/modules.txt>.
The module will be called i2c-piix4.
You will also need the latest user-space utilties: you can find them
in the lm_sensors package, which you can download at
http://www.lm-sensors.nu
endmenu endmenu
...@@ -2,5 +2,8 @@ ...@@ -2,5 +2,8 @@
# Makefile for the kernel hardware sensors bus drivers. # Makefile for the kernel hardware sensors bus drivers.
# #
obj-$(CONFIG_I2C_ALI15X3) += i2c-ali15x3.o
obj-$(CONFIG_I2C_AMD756) += i2c-amd756.o obj-$(CONFIG_I2C_AMD756) += i2c-amd756.o
obj-$(CONFIG_I2C_AMD8111) += i2c-amd8111.o obj-$(CONFIG_I2C_AMD8111) += i2c-amd8111.o
obj-$(CONFIG_I2C_I801) += i2c-i801.o
obj-$(CONFIG_I2C_PIIX4) += i2c-piix4.o
This diff is collapsed.
...@@ -375,6 +375,9 @@ static int __devinit amd756_probe(struct pci_dev *pdev, ...@@ -375,6 +375,9 @@ static int __devinit amd756_probe(struct pci_dev *pdev,
printk(KERN_DEBUG DRV_NAME ": AMD756_smba = 0x%X\n", amd756_ioport); printk(KERN_DEBUG DRV_NAME ": AMD756_smba = 0x%X\n", amd756_ioport);
#endif #endif
/* set up the driverfs linkage to our parent device */
amd756_adapter.dev.parent = &pdev->dev;
sprintf(amd756_adapter.name, sprintf(amd756_adapter.name,
"SMBus AMD75x adapter at %04x", amd756_ioport); "SMBus AMD75x adapter at %04x", amd756_ioport);
......
...@@ -363,6 +363,9 @@ static int __devinit amd8111_probe(struct pci_dev *dev, const struct pci_device_ ...@@ -363,6 +363,9 @@ static int __devinit amd8111_probe(struct pci_dev *dev, const struct pci_device_
smbus->adapter.algo = &smbus_algorithm; smbus->adapter.algo = &smbus_algorithm;
smbus->adapter.algo_data = smbus; smbus->adapter.algo_data = smbus;
/* set up the driverfs linkage to our parent device */
smbus->adapter.dev.parent = &dev->dev;
error = i2c_add_adapter(&smbus->adapter); error = i2c_add_adapter(&smbus->adapter);
if (error) if (error)
goto out_release_region; goto out_release_region;
...@@ -389,7 +392,7 @@ static void __devexit amd8111_remove(struct pci_dev *dev) ...@@ -389,7 +392,7 @@ static void __devexit amd8111_remove(struct pci_dev *dev)
} }
static struct pci_driver amd8111_driver = { static struct pci_driver amd8111_driver = {
.name = "amd8111 smbus 2.0", .name = "amd8111 smbus",
.id_table = amd8111_ids, .id_table = amd8111_ids,
.probe = amd8111_probe, .probe = amd8111_probe,
.remove = __devexit_p(amd8111_remove), .remove = __devexit_p(amd8111_remove),
......
This diff is collapsed.
This diff is collapsed.
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/seq_file.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -87,6 +88,16 @@ int i2c_add_adapter(struct i2c_adapter *adap) ...@@ -87,6 +88,16 @@ int i2c_add_adapter(struct i2c_adapter *adap)
init_MUTEX(&adap->bus); init_MUTEX(&adap->bus);
init_MUTEX(&adap->list); init_MUTEX(&adap->list);
/* Add the adapter to the driver core.
* If the parent pointer is not set up,
* we add this adapter to the legacy bus.
*/
if (adap->dev.parent == NULL)
adap->dev.parent = &legacy_bus;
sprintf(adap->dev.bus_id, "i2c-%d", i);
strcpy(adap->dev.name, "i2c controller");
device_register(&adap->dev);
/* inform drivers of new adapters */ /* inform drivers of new adapters */
for (j=0;j<I2C_DRIVER_MAX;j++) for (j=0;j<I2C_DRIVER_MAX;j++)
if (drivers[j]!=NULL && if (drivers[j]!=NULL &&
...@@ -154,6 +165,9 @@ int i2c_del_adapter(struct i2c_adapter *adap) ...@@ -154,6 +165,9 @@ int i2c_del_adapter(struct i2c_adapter *adap)
i2cproc_remove(i); i2cproc_remove(i);
/* clean up the sysfs representation */
device_unregister(&adap->dev);
adapters[i] = NULL; adapters[i] = NULL;
DEB(printk(KERN_DEBUG "i2c-core.o: adapter unregistered: %s\n",adap->name)); DEB(printk(KERN_DEBUG "i2c-core.o: adapter unregistered: %s\n",adap->name));
...@@ -313,42 +327,45 @@ int i2c_check_addr(struct i2c_adapter *adapter, int addr) ...@@ -313,42 +327,45 @@ int i2c_check_addr(struct i2c_adapter *adapter, int addr)
int i2c_attach_client(struct i2c_client *client) int i2c_attach_client(struct i2c_client *client)
{ {
struct i2c_adapter *adapter = client->adapter; struct i2c_adapter *adapter = client->adapter;
int res = -EBUSY, i; int i;
down(&adapter->list); down(&adapter->list);
if (__i2c_check_addr(client->adapter,client->addr)) if (__i2c_check_addr(client->adapter, client->addr))
goto out_unlock_list; goto out_unlock_list;
for (i = 0; i < I2C_CLIENT_MAX; i++) for (i = 0; i < I2C_CLIENT_MAX; i++) {
if (NULL == adapter->clients[i]) if (!adapter->clients[i])
break; goto free_slot;
if (I2C_CLIENT_MAX == i) { }
printk(KERN_WARNING printk(KERN_WARNING
" i2c-core.o: attach_client(%s) - enlarge I2C_CLIENT_MAX.\n", " i2c-core.o: attach_client(%s) - enlarge I2C_CLIENT_MAX.\n",
client->name); client->name);
res = -ENOMEM;
goto out_unlock_list;
}
out_unlock_list:
up(&adapter->list);
return -EBUSY;
free_slot:
adapter->clients[i] = client; adapter->clients[i] = client;
up(&adapter->list); up(&adapter->list);
if (adapter->client_register) if (adapter->client_register) {
if (adapter->client_register(client)) if (adapter->client_register(client)) {
printk(KERN_DEBUG "i2c-core.o: warning: client_register seems " printk(KERN_DEBUG
"i2c-core.o: warning: client_register seems "
"to have failed for client %02x at adapter %s\n", "to have failed for client %02x at adapter %s\n",
client->addr,adapter->name); client->addr, adapter->name);
DEB(printk(KERN_DEBUG "i2c-core.o: client [%s] registered to adapter [%s](pos. %d).\n", }
client->name, adapter->name,i)); }
if(client->flags & I2C_CLIENT_ALLOW_USE) DEB(printk(KERN_DEBUG
client->usage_count = 0; "i2c-core.o: client [%s] registered to adapter [%s] "
"(pos. %d).\n", client->name, adapter->name, i));
if (client->flags & I2C_CLIENT_ALLOW_USE)
client->usage_count = 0;
return 0; return 0;
out_unlock_list:
up(&adapter->list);
return res;
} }
...@@ -363,28 +380,30 @@ int i2c_detach_client(struct i2c_client *client) ...@@ -363,28 +380,30 @@ int i2c_detach_client(struct i2c_client *client)
if (adapter->client_unregister) { if (adapter->client_unregister) {
res = adapter->client_unregister(client); res = adapter->client_unregister(client);
if (res) { if (res) {
printk(KERN_ERR "i2c-core.o: client_unregister [%s] failed, " printk(KERN_ERR
"client not detached",client->name); "i2c-core.o: client_unregister [%s] failed, "
return res; "client not detached", client->name);
goto out;
} }
} }
down(&adapter->list); down(&adapter->list);
for (i = 0; i < I2C_CLIENT_MAX; i++) { for (i = 0; i < I2C_CLIENT_MAX; i++) {
if (client == adapter->clients[i]) if (client == adapter->clients[i]) {
break; adapter->clients[i] = NULL;
goto out_unlock;
}
} }
if (I2C_CLIENT_MAX == i) { printk(KERN_WARNING
printk(KERN_WARNING " i2c-core.o: unregister_client " " i2c-core.o: unregister_client [%s] not found\n",
"[%s] not found\n",
client->name); client->name);
return -ENODEV; res = -ENODEV;
} else
adapter->clients[i] = NULL;
up(&adapter->list);
return 0; out_unlock:
up(&adapter->list);
out:
return res;
} }
static int i2c_inc_use_client(struct i2c_client *client) static int i2c_inc_use_client(struct i2c_client *client)
...@@ -443,45 +462,7 @@ int i2c_release_client(struct i2c_client *client) ...@@ -443,45 +462,7 @@ int i2c_release_client(struct i2c_client *client)
return 0; return 0;
} }
/* ----------------------------------------------------
* The /proc functions
* ----------------------------------------------------
*/
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
/* This function generates the output for /proc/bus/i2c */
static int read_bus_i2c(char *buf, char **start, off_t offset,
int len, int *eof, void *private)
{
int i;
int nr = 0;
/* Note that it is safe to write a `little' beyond len. Yes, really. */
/* Fuck you. Will convert this to seq_file later. --hch */
down(&core_lists);
for (i = 0; (i < I2C_ADAP_MAX) && (nr < len); i++) {
if (adapters[i]) {
nr += sprintf(buf+nr, "i2c-%d\t", i);
if (adapters[i]->algo->smbus_xfer) {
if (adapters[i]->algo->master_xfer)
nr += sprintf(buf+nr,"smbus/i2c");
else
nr += sprintf(buf+nr,"smbus ");
} else if (adapters[i]->algo->master_xfer)
nr += sprintf(buf+nr,"i2c ");
else
nr += sprintf(buf+nr,"dummy ");
nr += sprintf(buf+nr,"\t%-32s\t%-32s\n",
adapters[i]->name,
adapters[i]->algo->name);
}
}
up(&core_lists);
return nr;
}
/* This function generates the output for /proc/bus/i2c-? */ /* This function generates the output for /proc/bus/i2c-? */
static ssize_t i2cproc_bus_read(struct file *file, char *buf, static ssize_t i2cproc_bus_read(struct file *file, char *buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
...@@ -551,6 +532,50 @@ static struct file_operations i2cproc_operations = { ...@@ -551,6 +532,50 @@ static struct file_operations i2cproc_operations = {
.read = i2cproc_bus_read, .read = i2cproc_bus_read,
}; };
/* This function generates the output for /proc/bus/i2c */
static int bus_i2c_show(struct seq_file *s, void *p)
{
int i;
down(&core_lists);
for (i = 0; i < I2C_ADAP_MAX; i++) {
struct i2c_adapter *adapter = adapters[i];
if (!adapter)
continue;
seq_printf(s, "i2c-%d\t", i);
if (adapter->algo->smbus_xfer) {
if (adapter->algo->master_xfer)
seq_printf(s, "smbus/i2c");
else
seq_printf(s, "smbus ");
} else if (adapter->algo->master_xfer)
seq_printf(s ,"i2c ");
else
seq_printf(s, "dummy ");
seq_printf(s, "\t%-32s\t%-32s\n",
adapter->name, adapter->algo->name);
}
up(&core_lists);
return 0;
}
static int bus_i2c_open(struct inode *inode, struct file *file)
{
return single_open(file, bus_i2c_show, NULL);
}
static struct file_operations bus_i2c_fops = {
.open = bus_i2c_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int i2cproc_register(struct i2c_adapter *adap, int bus) static int i2cproc_register(struct i2c_adapter *adap, int bus)
{ {
struct proc_dir_entry *proc_entry; struct proc_dir_entry *proc_entry;
...@@ -563,7 +588,7 @@ static int i2cproc_register(struct i2c_adapter *adap, int bus) ...@@ -563,7 +588,7 @@ static int i2cproc_register(struct i2c_adapter *adap, int bus)
goto fail; goto fail;
proc_entry->proc_fops = &i2cproc_operations; proc_entry->proc_fops = &i2cproc_operations;
proc_entry->owner = THIS_MODULE; proc_entry->owner = adap->owner;
adap->inode = proc_entry->low_ino; adap->inode = proc_entry->low_ino;
return 0; return 0;
fail: fail:
...@@ -583,25 +608,53 @@ static int __init i2cproc_init(void) ...@@ -583,25 +608,53 @@ static int __init i2cproc_init(void)
{ {
struct proc_dir_entry *proc_bus_i2c; struct proc_dir_entry *proc_bus_i2c;
proc_bus_i2c = create_proc_entry("i2c",0,proc_bus); proc_bus_i2c = create_proc_entry("i2c", 0, proc_bus);
if (!proc_bus_i2c) { if (!proc_bus_i2c)
printk(KERN_ERR "i2c-core.o: Could not create /proc/bus/i2c"); goto fail;
return -ENOENT; proc_bus_i2c->proc_fops = &bus_i2c_fops;
}
proc_bus_i2c->read_proc = &read_bus_i2c;
proc_bus_i2c->owner = THIS_MODULE; proc_bus_i2c->owner = THIS_MODULE;
return 0; return 0;
fail:
printk(KERN_ERR "i2c-core.o: Could not create /proc/bus/i2c");
return -ENOENT;
} }
static void __exit i2cproc_cleanup(void) static void __exit i2cproc_cleanup(void)
{ {
remove_proc_entry("i2c",proc_bus); remove_proc_entry("i2c",proc_bus);
} }
#else
static int __init i2cproc_init(void) { return 0; }
static void __exit i2cproc_cleanup(void) { }
#endif /* CONFIG_PROC_FS */
/* match always succeeds, as we want the probe() to tell if we really accept this match */
static int i2c_device_match(struct device *dev, struct device_driver *drv)
{
return 1;
}
struct bus_type i2c_bus_type = {
.name = "i2c",
.match = i2c_device_match,
};
static int __init i2c_init(void)
{
bus_register(&i2c_bus_type);
return i2cproc_init();
}
static void __exit i2c_exit(void)
{
i2cproc_cleanup();
bus_unregister(&i2c_bus_type);
}
module_init(i2cproc_init); module_init(i2c_init);
module_exit(i2cproc_cleanup); module_exit(i2c_exit);
#endif /* def CONFIG_PROC_FS */
/* ---------------------------------------------------- /* ----------------------------------------------------
* the functional interface to the i2c busses. * the functional interface to the i2c busses.
......
...@@ -35,8 +35,6 @@ ...@@ -35,8 +35,6 @@
#include <linux/i2c-proc.h> #include <linux/i2c-proc.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
static int i2c_create_name(char **name, const char *prefix,
struct i2c_adapter *adapter, int addr);
static int i2c_parse_reals(int *nrels, void *buffer, int bufsize, static int i2c_parse_reals(int *nrels, void *buffer, int bufsize,
long *results, int magnitude); long *results, int magnitude);
static int i2c_write_reals(int nrels, void *buffer, size_t *bufsize, static int i2c_write_reals(int nrels, void *buffer, size_t *bufsize,
...@@ -54,15 +52,6 @@ static struct ctl_table_header *i2c_entries[SENSORS_ENTRY_MAX]; ...@@ -54,15 +52,6 @@ static struct ctl_table_header *i2c_entries[SENSORS_ENTRY_MAX];
static struct i2c_client *i2c_clients[SENSORS_ENTRY_MAX]; static struct i2c_client *i2c_clients[SENSORS_ENTRY_MAX];
static ctl_table sysctl_table[] = {
{CTL_DEV, "dev", NULL, 0, 0555},
{0},
{DEV_SENSORS, "sensors", NULL, 0, 0555},
{0},
{0, NULL, NULL, 0, 0555},
{0}
};
static ctl_table i2c_proc_dev_sensors[] = { static ctl_table i2c_proc_dev_sensors[] = {
{SENSORS_CHIPS, "chips", NULL, 0, 0644, NULL, &i2c_proc_chips, {SENSORS_CHIPS, "chips", NULL, 0, 0644, NULL, &i2c_proc_chips,
&i2c_sysctl_chips}, &i2c_sysctl_chips},
...@@ -87,36 +76,40 @@ static struct ctl_table_header *i2c_proc_header; ...@@ -87,36 +76,40 @@ static struct ctl_table_header *i2c_proc_header;
(for a LM78 chip on the ISA bus at port 0x310), or lm75-i2c-3-4e (for (for a LM78 chip on the ISA bus at port 0x310), or lm75-i2c-3-4e (for
a LM75 chip on the third i2c bus at address 0x4e). a LM75 chip on the third i2c bus at address 0x4e).
name is allocated first. */ name is allocated first. */
static int i2c_create_name(char **name, const char *prefix, static char *generate_name(struct i2c_client *client, const char *prefix)
struct i2c_adapter *adapter, int addr)
{ {
char name_buffer[50]; struct i2c_adapter *adapter = client->adapter;
int id, i, end; int addr = client->addr;
if (i2c_is_isa_adapter(adapter)) char name_buffer[50], *name;
if (i2c_is_isa_adapter(adapter)) {
sprintf(name_buffer, "%s-isa-%04x", prefix, addr); sprintf(name_buffer, "%s-isa-%04x", prefix, addr);
else if (!adapter->algo->smbus_xfer && !adapter->algo->master_xfer) { } else if (adapter->algo->smbus_xfer || adapter->algo->master_xfer) {
/* dummy adapter, generate prefix */ int id = i2c_adapter_id(adapter);
if (id < 0)
return ERR_PTR(-ENOENT);
sprintf(name_buffer, "%s-i2c-%d-%02x", prefix, id, addr);
} else { /* dummy adapter, generate prefix */
int end, i;
sprintf(name_buffer, "%s-", prefix); sprintf(name_buffer, "%s-", prefix);
end = strlen(name_buffer); end = strlen(name_buffer);
for(i = 0; i < 32; i++) {
if(adapter->algo->name[i] == ' ') for (i = 0; i < 32; i++) {
if (adapter->algo->name[i] == ' ')
break; break;
name_buffer[end++] = tolower(adapter->algo->name[i]); name_buffer[end++] = tolower(adapter->algo->name[i]);
} }
name_buffer[end] = 0; name_buffer[end] = 0;
sprintf(name_buffer + end, "-%04x", addr); sprintf(name_buffer + end, "-%04x", addr);
} else {
if ((id = i2c_adapter_id(adapter)) < 0)
return -ENOENT;
sprintf(name_buffer, "%s-i2c-%d-%02x", prefix, id, addr);
} }
*name = kmalloc(strlen(name_buffer) + 1, GFP_KERNEL);
if (!*name) { name = kmalloc(strlen(name_buffer) + 1, GFP_KERNEL);
printk (KERN_WARNING "i2c_create_name: not enough memory\n"); if (unlikely(!name))
return -ENOMEM; return ERR_PTR(-ENOMEM);
} strcpy(name, name_buffer);
strcpy(*name, name_buffer); return name;
return 0;
} }
/* This rather complex function must be called when you want to add an entry /* This rather complex function must be called when you want to add an entry
...@@ -127,93 +120,80 @@ static int i2c_create_name(char **name, const char *prefix, ...@@ -127,93 +120,80 @@ static int i2c_create_name(char **name, const char *prefix,
If any driver wants subdirectories within the newly created directory, If any driver wants subdirectories within the newly created directory,
this function must be updated! */ this function must be updated! */
int i2c_register_entry(struct i2c_client *client, const char *prefix, int i2c_register_entry(struct i2c_client *client, const char *prefix,
ctl_table * ctl_template) struct ctl_table *leaf)
{ {
int i, res, len, id; struct { struct ctl_table root[2], dev[2], sensors[2]; } *tbl;
ctl_table *new_table, *client_tbl, *tbl; struct ctl_table_header *hdr;
char *name; struct ctl_table *tmp;
struct ctl_table_header *new_header; const char *name;
int id;
if ((res = i2c_create_name(&name, prefix, client->adapter, name = generate_name(client, prefix);
client->addr))) return res; if (IS_ERR(name))
return PTR_ERR(name);
for (id = 0; id < SENSORS_ENTRY_MAX; id++) for (id = 0; id < SENSORS_ENTRY_MAX; id++) {
if (!i2c_entries[id]) { if (!i2c_entries[id])
break; goto free_slot;
}
if (id == SENSORS_ENTRY_MAX) {
kfree(name);
return -ENOMEM;
} }
id += 256; goto out_free_name;
len = 0; free_slot:
while (ctl_template[len].procname) tbl = kmalloc(sizeof(*tbl), GFP_KERNEL);
len++; if (unlikely(!tbl))
if (!(new_table = kmalloc(sizeof(sysctl_table) + sizeof(ctl_table) * (len + 1), goto out_free_name;
GFP_KERNEL))) { memset(tbl, 0, sizeof(*tbl));
kfree(name);
return -ENOMEM;
}
memcpy(new_table, sysctl_table, sizeof(sysctl_table)); for (tmp = leaf; tmp->ctl_name; tmp++)
tbl = new_table; /* sys/ */ tmp->extra2 = client;
tbl = tbl->child = tbl + 2; /* dev/ */
tbl = tbl->child = tbl + 2; /* sensors/ */
client_tbl = tbl->child = tbl + 2; /* XX-chip-YY-ZZ/ */
client_tbl->procname = name; tbl->sensors->ctl_name = id+256;
client_tbl->ctl_name = id; tbl->sensors->procname = name;
client_tbl->child = client_tbl + 2; tbl->sensors->mode = 0555;
tbl->sensors->child = leaf;
/* Next the client sysctls. --km */ tbl->dev->ctl_name = DEV_SENSORS;
tbl = client_tbl->child; tbl->dev->procname = "sensors";
memcpy(tbl, ctl_template, sizeof(ctl_table) * (len+1)); tbl->dev->mode = 0555;
for (i = 0; i < len; i++) tbl->dev->child = tbl->sensors;
tbl[i].extra2 = client;
if (!(new_header = register_sysctl_table(new_table, 0))) { tbl->root->ctl_name = CTL_DEV;
printk(KERN_ERR "i2c-proc.o: error: sysctl interface not supported by kernel!\n"); tbl->root->procname = "dev";
kfree(new_table); tbl->root->mode = 0555;
kfree(name); tbl->root->child = tbl->dev;
return -EPERM;
}
i2c_entries[id - 256] = new_header; hdr = register_sysctl_table(tbl->root, 0);
if (unlikely(!hdr))
goto out_free_tbl;
i2c_clients[id - 256] = client; i2c_entries[id] = hdr;
i2c_clients[id] = client;
#ifdef DEBUG return (id + 256); /* XXX(hch) why?? */
if (!new_header || !new_header->ctl_table ||
!new_header->ctl_table->child || out_free_tbl:
!new_header->ctl_table->child->child || kfree(tbl);
!new_header->ctl_table->child->child->de ) { out_free_name:
printk kfree(name);
(KERN_ERR "i2c-proc.o: NULL pointer when trying to install fill_inode fix!\n"); return -ENOMEM;
return id;
}
#endif /* DEBUG */
client_tbl->de->owner = client->driver->owner;
return id;
} }
void i2c_deregister_entry(int id) void i2c_deregister_entry(int id)
{ {
ctl_table *table;
char *temp;
id -= 256; id -= 256;
if (i2c_entries[id]) { if (i2c_entries[id]) {
table = i2c_entries[id]->ctl_table; struct ctl_table_header *hdr = i2c_entries[id];
unregister_sysctl_table(i2c_entries[id]); struct ctl_table *tbl = hdr->ctl_table;
/* 2-step kfree needed to keep gcc happy about const points */
(const char *) temp = table[4].procname; unregister_sysctl_table(hdr);
kfree(temp); kfree(tbl->child->child->procname);
kfree(table); kfree(tbl); /* actually the whole anonymous struct */
}
i2c_entries[id] = NULL; i2c_entries[id] = NULL;
i2c_clients[id] = NULL; i2c_clients[id] = NULL;
}
} }
static int i2c_proc_chips(ctl_table * ctl, int write, struct file *filp, static int i2c_proc_chips(ctl_table * ctl, int write, struct file *filp,
......
...@@ -203,36 +203,34 @@ static int linear_make_request (request_queue_t *q, struct bio *bio) ...@@ -203,36 +203,34 @@ static int linear_make_request (request_queue_t *q, struct bio *bio)
return 0; return 0;
} }
bio->bi_bdev = tmp_dev->rdev->bdev; bio->bi_bdev = tmp_dev->rdev->bdev;
bio->bi_sector = bio->bi_sector - (tmp_dev->offset << 1); bio->bi_sector = bio->bi_sector - (tmp_dev->offset << 1) + tmp_dev->rdev->data_offset;
return 1; return 1;
} }
static int linear_status (char *page, mddev_t *mddev) static void linear_status (struct seq_file *seq, mddev_t *mddev)
{ {
int sz = 0;
#undef MD_DEBUG #undef MD_DEBUG
#ifdef MD_DEBUG #ifdef MD_DEBUG
int j; int j;
linear_conf_t *conf = mddev_to_conf(mddev); linear_conf_t *conf = mddev_to_conf(mddev);
sz += sprintf(page+sz, " "); seq_printf(seq, " ");
for (j = 0; j < conf->nr_zones; j++) for (j = 0; j < conf->nr_zones; j++)
{ {
sz += sprintf(page+sz, "[%s", seq_printf(seq, "[%s",
bdev_partition_name(conf->hash_table[j].dev0->rdev->bdev)); bdev_partition_name(conf->hash_table[j].dev0->rdev->bdev));
if (conf->hash_table[j].dev1) if (conf->hash_table[j].dev1)
sz += sprintf(page+sz, "/%s] ", seq_printf(seq, "/%s] ",
bdev_partition_name(conf->hash_table[j].dev1->rdev->bdev)); bdev_partition_name(conf->hash_table[j].dev1->rdev->bdev));
else else
sz += sprintf(page+sz, "] "); seq_printf(seq, "] ");
} }
sz += sprintf(page+sz, "\n"); seq_printf(seq, "\n");
#endif #endif
sz += sprintf(page+sz, " %dk rounding", mddev->chunk_size/1024); seq_printf(seq, " %dk rounding", mddev->chunk_size/1024);
return sz;
} }
......
This diff is collapsed.
...@@ -86,7 +86,6 @@ static void multipath_reschedule_retry (struct multipath_bh *mp_bh) ...@@ -86,7 +86,6 @@ static void multipath_reschedule_retry (struct multipath_bh *mp_bh)
{ {
unsigned long flags; unsigned long flags;
mddev_t *mddev = mp_bh->mddev; mddev_t *mddev = mp_bh->mddev;
multipath_conf_t *conf = mddev_to_conf(mddev);
spin_lock_irqsave(&retry_list_lock, flags); spin_lock_irqsave(&retry_list_lock, flags);
if (multipath_retry_list == NULL) if (multipath_retry_list == NULL)
...@@ -95,7 +94,7 @@ static void multipath_reschedule_retry (struct multipath_bh *mp_bh) ...@@ -95,7 +94,7 @@ static void multipath_reschedule_retry (struct multipath_bh *mp_bh)
multipath_retry_tail = &mp_bh->next_mp; multipath_retry_tail = &mp_bh->next_mp;
mp_bh->next_mp = NULL; mp_bh->next_mp = NULL;
spin_unlock_irqrestore(&retry_list_lock, flags); spin_unlock_irqrestore(&retry_list_lock, flags);
md_wakeup_thread(conf->thread); md_wakeup_thread(mddev->thread);
} }
...@@ -185,19 +184,18 @@ static int multipath_make_request (request_queue_t *q, struct bio * bio) ...@@ -185,19 +184,18 @@ static int multipath_make_request (request_queue_t *q, struct bio * bio)
return 0; return 0;
} }
static int multipath_status (char *page, mddev_t *mddev) static void multipath_status (struct seq_file *seq, mddev_t *mddev)
{ {
multipath_conf_t *conf = mddev_to_conf(mddev); multipath_conf_t *conf = mddev_to_conf(mddev);
int sz = 0, i; int i;
sz += sprintf (page+sz, " [%d/%d] [", conf->raid_disks, seq_printf (seq, " [%d/%d] [", conf->raid_disks,
conf->working_disks); conf->working_disks);
for (i = 0; i < conf->raid_disks; i++) for (i = 0; i < conf->raid_disks; i++)
sz += sprintf (page+sz, "%s", seq_printf (seq, "%s",
conf->multipaths[i].rdev && conf->multipaths[i].rdev &&
conf->multipaths[i].rdev->in_sync ? "U" : "_"); conf->multipaths[i].rdev->in_sync ? "U" : "_");
sz += sprintf (page+sz, "]"); seq_printf (seq, "]");
return sz;
} }
#define LAST_DISK KERN_ALERT \ #define LAST_DISK KERN_ALERT \
...@@ -334,14 +332,14 @@ static int multipath_remove_disk(mddev_t *mddev, int number) ...@@ -334,14 +332,14 @@ static int multipath_remove_disk(mddev_t *mddev, int number)
* 3. Performs writes following reads for array syncronising. * 3. Performs writes following reads for array syncronising.
*/ */
static void multipathd (void *data) static void multipathd (mddev_t *mddev)
{ {
struct multipath_bh *mp_bh; struct multipath_bh *mp_bh;
struct bio *bio; struct bio *bio;
unsigned long flags; unsigned long flags;
mddev_t *mddev;
mdk_rdev_t *rdev; mdk_rdev_t *rdev;
md_check_recovery(mddev);
for (;;) { for (;;) {
spin_lock_irqsave(&retry_list_lock, flags); spin_lock_irqsave(&retry_list_lock, flags);
mp_bh = multipath_retry_list; mp_bh = multipath_retry_list;
...@@ -471,10 +469,10 @@ static int multipath_run (mddev_t *mddev) ...@@ -471,10 +469,10 @@ static int multipath_run (mddev_t *mddev)
} }
{ {
const char * name = "multipathd"; const char * name = "md%d_multipath";
conf->thread = md_register_thread(multipathd, conf, name); mddev->thread = md_register_thread(multipathd, mddev, name);
if (!conf->thread) { if (!mddev->thread) {
printk(THREAD_ERROR, mdidx(mddev)); printk(THREAD_ERROR, mdidx(mddev));
goto out_free_conf; goto out_free_conf;
} }
...@@ -513,7 +511,7 @@ static int multipath_stop (mddev_t *mddev) ...@@ -513,7 +511,7 @@ static int multipath_stop (mddev_t *mddev)
{ {
multipath_conf_t *conf = mddev_to_conf(mddev); multipath_conf_t *conf = mddev_to_conf(mddev);
md_unregister_thread(conf->thread); md_unregister_thread(mddev->thread);
mempool_destroy(conf->pool); mempool_destroy(conf->pool);
kfree(conf); kfree(conf);
mddev->private = NULL; mddev->private = NULL;
......
...@@ -349,7 +349,7 @@ static int raid0_make_request (request_queue_t *q, struct bio *bio) ...@@ -349,7 +349,7 @@ static int raid0_make_request (request_queue_t *q, struct bio *bio)
* is the only IO operation happening on this bh. * is the only IO operation happening on this bh.
*/ */
bio->bi_bdev = tmp_dev->bdev; bio->bi_bdev = tmp_dev->bdev;
bio->bi_sector = rsect; bio->bi_sector = rsect + tmp_dev->data_offset;
/* /*
* Let the main block layer submit the IO and resolve recursion: * Let the main block layer submit the IO and resolve recursion:
...@@ -372,41 +372,40 @@ static int raid0_make_request (request_queue_t *q, struct bio *bio) ...@@ -372,41 +372,40 @@ static int raid0_make_request (request_queue_t *q, struct bio *bio)
return 0; return 0;
} }
static int raid0_status (char *page, mddev_t *mddev) static void raid0_status (struct seq_file *seq, mddev_t *mddev)
{ {
int sz = 0;
#undef MD_DEBUG #undef MD_DEBUG
#ifdef MD_DEBUG #ifdef MD_DEBUG
int j, k; int j, k;
raid0_conf_t *conf = mddev_to_conf(mddev); raid0_conf_t *conf = mddev_to_conf(mddev);
sz += sprintf(page + sz, " "); seq_printf(seq, " ");
for (j = 0; j < conf->nr_zones; j++) { for (j = 0; j < conf->nr_zones; j++) {
sz += sprintf(page + sz, "[z%d", seq_printf(seq, "[z%d",
conf->hash_table[j].zone0 - conf->strip_zone); conf->hash_table[j].zone0 - conf->strip_zone);
if (conf->hash_table[j].zone1) if (conf->hash_table[j].zone1)
sz += sprintf(page+sz, "/z%d] ", seq_printf(seq, "/z%d] ",
conf->hash_table[j].zone1 - conf->strip_zone); conf->hash_table[j].zone1 - conf->strip_zone);
else else
sz += sprintf(page+sz, "] "); seq_printf(seq, "] ");
} }
sz += sprintf(page + sz, "\n"); seq_printf(seq, "\n");
for (j = 0; j < conf->nr_strip_zones; j++) { for (j = 0; j < conf->nr_strip_zones; j++) {
sz += sprintf(page + sz, " z%d=[", j); seq_printf(seq, " z%d=[", j);
for (k = 0; k < conf->strip_zone[j].nb_dev; k++) for (k = 0; k < conf->strip_zone[j].nb_dev; k++)
sz += sprintf (page+sz, "%s/", bdev_partition_name( seq_printf (seq, "%s/", bdev_partition_name(
conf->strip_zone[j].dev[k]->bdev)); conf->strip_zone[j].dev[k]->bdev));
sz--;
sz += sprintf (page+sz, "] zo=%d do=%d s=%d\n", seq_printf (seq, "] zo=%d do=%d s=%d\n",
conf->strip_zone[j].zone_offset, conf->strip_zone[j].zone_offset,
conf->strip_zone[j].dev_offset, conf->strip_zone[j].dev_offset,
conf->strip_zone[j].size); conf->strip_zone[j].size);
} }
#endif #endif
sz += sprintf(page + sz, " %dk chunks", mddev->chunk_size/1024); seq_printf(seq, " %dk chunks", mddev->chunk_size/1024);
return sz; return;
} }
static mdk_personality_t raid0_personality= static mdk_personality_t raid0_personality=
......
...@@ -225,13 +225,12 @@ static void reschedule_retry(r1bio_t *r1_bio) ...@@ -225,13 +225,12 @@ static void reschedule_retry(r1bio_t *r1_bio)
{ {
unsigned long flags; unsigned long flags;
mddev_t *mddev = r1_bio->mddev; mddev_t *mddev = r1_bio->mddev;
conf_t *conf = mddev_to_conf(mddev);
spin_lock_irqsave(&retry_list_lock, flags); spin_lock_irqsave(&retry_list_lock, flags);
list_add(&r1_bio->retry_list, &retry_list_head); list_add(&r1_bio->retry_list, &retry_list_head);
spin_unlock_irqrestore(&retry_list_lock, flags); spin_unlock_irqrestore(&retry_list_lock, flags);
md_wakeup_thread(conf->thread); md_wakeup_thread(mddev->thread);
} }
/* /*
...@@ -320,7 +319,7 @@ static int end_request(struct bio *bio, unsigned int bytes_done, int error) ...@@ -320,7 +319,7 @@ static int end_request(struct bio *bio, unsigned int bytes_done, int error)
* already. * already.
*/ */
if (atomic_dec_and_test(&r1_bio->remaining)) { if (atomic_dec_and_test(&r1_bio->remaining)) {
md_write_end(r1_bio->mddev,conf->thread); md_write_end(r1_bio->mddev);
raid_end_bio_io(r1_bio, uptodate); raid_end_bio_io(r1_bio, uptodate);
} }
} }
...@@ -494,7 +493,7 @@ static int make_request(request_queue_t *q, struct bio * bio) ...@@ -494,7 +493,7 @@ static int make_request(request_queue_t *q, struct bio * bio)
BUG(); BUG();
r1_bio->read_bio = read_bio; r1_bio->read_bio = read_bio;
read_bio->bi_sector = r1_bio->sector; read_bio->bi_sector = r1_bio->sector + mirror->rdev->data_offset;
read_bio->bi_bdev = mirror->rdev->bdev; read_bio->bi_bdev = mirror->rdev->bdev;
read_bio->bi_end_io = end_request; read_bio->bi_end_io = end_request;
read_bio->bi_rw = r1_bio->cmd; read_bio->bi_rw = r1_bio->cmd;
...@@ -529,7 +528,7 @@ static int make_request(request_queue_t *q, struct bio * bio) ...@@ -529,7 +528,7 @@ static int make_request(request_queue_t *q, struct bio * bio)
mbio = bio_clone(bio, GFP_NOIO); mbio = bio_clone(bio, GFP_NOIO);
r1_bio->write_bios[i] = mbio; r1_bio->write_bios[i] = mbio;
mbio->bi_sector = r1_bio->sector; mbio->bi_sector = r1_bio->sector + conf->mirrors[i].rdev->data_offset;
mbio->bi_bdev = conf->mirrors[i].rdev->bdev; mbio->bi_bdev = conf->mirrors[i].rdev->bdev;
mbio->bi_end_io = end_request; mbio->bi_end_io = end_request;
mbio->bi_rw = r1_bio->cmd; mbio->bi_rw = r1_bio->cmd;
...@@ -542,7 +541,7 @@ static int make_request(request_queue_t *q, struct bio * bio) ...@@ -542,7 +541,7 @@ static int make_request(request_queue_t *q, struct bio * bio)
* If all mirrors are non-operational * If all mirrors are non-operational
* then return an IO error: * then return an IO error:
*/ */
md_write_end(mddev,conf->thread); md_write_end(mddev);
raid_end_bio_io(r1_bio, 0); raid_end_bio_io(r1_bio, 0);
return 0; return 0;
} }
...@@ -571,19 +570,18 @@ static int make_request(request_queue_t *q, struct bio * bio) ...@@ -571,19 +570,18 @@ static int make_request(request_queue_t *q, struct bio * bio)
return 0; return 0;
} }
static int status(char *page, mddev_t *mddev) static void status(struct seq_file *seq, mddev_t *mddev)
{ {
conf_t *conf = mddev_to_conf(mddev); conf_t *conf = mddev_to_conf(mddev);
int sz = 0, i; int i;
sz += sprintf(page+sz, " [%d/%d] [", conf->raid_disks, seq_printf(seq, " [%d/%d] [", conf->raid_disks,
conf->working_disks); conf->working_disks);
for (i = 0; i < conf->raid_disks; i++) for (i = 0; i < conf->raid_disks; i++)
sz += sprintf(page+sz, "%s", seq_printf(seq, "%s",
conf->mirrors[i].rdev && conf->mirrors[i].rdev &&
conf->mirrors[i].rdev->in_sync ? "U" : "_"); conf->mirrors[i].rdev->in_sync ? "U" : "_");
sz += sprintf (page+sz, "]"); seq_printf(seq, "]");
return sz;
} }
#define LAST_DISK KERN_ALERT \ #define LAST_DISK KERN_ALERT \
...@@ -624,10 +622,9 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev) ...@@ -624,10 +622,9 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
mddev->degraded++; mddev->degraded++;
conf->working_disks--; conf->working_disks--;
/* /*
* if recovery was running, stop it now. * if recovery is running, make sure it aborts.
*/ */
if (mddev->recovery_running) set_bit(MD_RECOVERY_ERR, &mddev->recovery);
mddev->recovery_running = -EIO;
} }
rdev->in_sync = 0; rdev->in_sync = 0;
rdev->faulty = 1; rdev->faulty = 1;
...@@ -859,7 +856,7 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio) ...@@ -859,7 +856,7 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio)
mbio = bio_clone(bio, GFP_NOIO); mbio = bio_clone(bio, GFP_NOIO);
r1_bio->write_bios[i] = mbio; r1_bio->write_bios[i] = mbio;
mbio->bi_bdev = conf->mirrors[i].rdev->bdev; mbio->bi_bdev = conf->mirrors[i].rdev->bdev;
mbio->bi_sector = r1_bio->sector; mbio->bi_sector = r1_bio->sector | conf->mirrors[i].rdev->data_offset;
mbio->bi_end_io = end_sync_write; mbio->bi_end_io = end_sync_write;
mbio->bi_rw = WRITE; mbio->bi_rw = WRITE;
mbio->bi_private = r1_bio; mbio->bi_private = r1_bio;
...@@ -900,17 +897,17 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio) ...@@ -900,17 +897,17 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio)
* 3. Performs writes following reads for array syncronising. * 3. Performs writes following reads for array syncronising.
*/ */
static void raid1d(void *data) static void raid1d(mddev_t *mddev)
{ {
struct list_head *head = &retry_list_head; struct list_head *head = &retry_list_head;
r1bio_t *r1_bio; r1bio_t *r1_bio;
struct bio *bio; struct bio *bio;
unsigned long flags; unsigned long flags;
mddev_t *mddev; conf_t *conf = mddev_to_conf(mddev);
conf_t *conf = data;
mdk_rdev_t *rdev; mdk_rdev_t *rdev;
md_handle_safemode(conf->mddev); md_check_recovery(mddev);
md_handle_safemode(mddev);
for (;;) { for (;;) {
spin_lock_irqsave(&retry_list_lock, flags); spin_lock_irqsave(&retry_list_lock, flags);
...@@ -937,7 +934,7 @@ static void raid1d(void *data) ...@@ -937,7 +934,7 @@ static void raid1d(void *data)
printk(REDIRECT_SECTOR, printk(REDIRECT_SECTOR,
bdev_partition_name(rdev->bdev), (unsigned long long)r1_bio->sector); bdev_partition_name(rdev->bdev), (unsigned long long)r1_bio->sector);
bio->bi_bdev = rdev->bdev; bio->bi_bdev = rdev->bdev;
bio->bi_sector = r1_bio->sector; bio->bi_sector = r1_bio->sector + rdev->data_offset;
bio->bi_rw = r1_bio->cmd; bio->bi_rw = r1_bio->cmd;
generic_make_request(bio); generic_make_request(bio);
...@@ -1048,7 +1045,7 @@ static int sync_request(mddev_t *mddev, sector_t sector_nr, int go_faster) ...@@ -1048,7 +1045,7 @@ static int sync_request(mddev_t *mddev, sector_t sector_nr, int go_faster)
read_bio = bio_clone(r1_bio->master_bio, GFP_NOIO); read_bio = bio_clone(r1_bio->master_bio, GFP_NOIO);
read_bio->bi_sector = sector_nr; read_bio->bi_sector = sector_nr + mirror->rdev->data_offset;
read_bio->bi_bdev = mirror->rdev->bdev; read_bio->bi_bdev = mirror->rdev->bdev;
read_bio->bi_end_io = end_sync_read; read_bio->bi_end_io = end_sync_read;
read_bio->bi_rw = READ; read_bio->bi_rw = READ;
...@@ -1190,10 +1187,8 @@ static int run(mddev_t *mddev) ...@@ -1190,10 +1187,8 @@ static int run(mddev_t *mddev)
{ {
snprintf(conf->thread_name,MD_THREAD_NAME_MAX,"raid1d_md%d",mdidx(mddev)); mddev->thread = md_register_thread(raid1d, mddev, "md%d_raid1");
if (!mddev->thread) {
conf->thread = md_register_thread(raid1d, conf, conf->thread_name);
if (!conf->thread) {
printk(THREAD_ERROR, mdidx(mddev)); printk(THREAD_ERROR, mdidx(mddev));
goto out_free_conf; goto out_free_conf;
} }
...@@ -1219,7 +1214,8 @@ static int stop(mddev_t *mddev) ...@@ -1219,7 +1214,8 @@ static int stop(mddev_t *mddev)
{ {
conf_t *conf = mddev_to_conf(mddev); conf_t *conf = mddev_to_conf(mddev);
md_unregister_thread(conf->thread); md_unregister_thread(mddev->thread);
mddev->thread = NULL;
if (conf->r1bio_pool) if (conf->r1bio_pool)
mempool_destroy(conf->r1bio_pool); mempool_destroy(conf->r1bio_pool);
kfree(conf); kfree(conf);
......
...@@ -71,12 +71,12 @@ static inline void __release_stripe(raid5_conf_t *conf, struct stripe_head *sh) ...@@ -71,12 +71,12 @@ static inline void __release_stripe(raid5_conf_t *conf, struct stripe_head *sh)
list_add_tail(&sh->lru, &conf->delayed_list); list_add_tail(&sh->lru, &conf->delayed_list);
else else
list_add_tail(&sh->lru, &conf->handle_list); list_add_tail(&sh->lru, &conf->handle_list);
md_wakeup_thread(conf->thread); md_wakeup_thread(conf->mddev->thread);
} else { } else {
if (test_and_clear_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) { if (test_and_clear_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) {
atomic_dec(&conf->preread_active_stripes); atomic_dec(&conf->preread_active_stripes);
if (atomic_read(&conf->preread_active_stripes) < IO_THRESHOLD) if (atomic_read(&conf->preread_active_stripes) < IO_THRESHOLD)
md_wakeup_thread(conf->thread); md_wakeup_thread(conf->mddev->thread);
} }
list_add_tail(&sh->lru, &conf->inactive_list); list_add_tail(&sh->lru, &conf->inactive_list);
atomic_dec(&conf->active_stripes); atomic_dec(&conf->active_stripes);
...@@ -463,10 +463,9 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev) ...@@ -463,10 +463,9 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
conf->failed_disks++; conf->failed_disks++;
rdev->in_sync = 0; rdev->in_sync = 0;
/* /*
* if recovery was running, stop it now. * if recovery was running, make sure it aborts.
*/ */
if (mddev->recovery_running) set_bit(MD_RECOVERY_ERR, &mddev->recovery);
mddev->recovery_running = -EIO;
} }
rdev->faulty = 1; rdev->faulty = 1;
printk (KERN_ALERT printk (KERN_ALERT
...@@ -913,7 +912,7 @@ static void handle_stripe(struct stripe_head *sh) ...@@ -913,7 +912,7 @@ static void handle_stripe(struct stripe_head *sh)
struct bio *nextbi = bi->bi_next; struct bio *nextbi = bi->bi_next;
clear_bit(BIO_UPTODATE, &bi->bi_flags); clear_bit(BIO_UPTODATE, &bi->bi_flags);
if (--bi->bi_phys_segments == 0) { if (--bi->bi_phys_segments == 0) {
md_write_end(conf->mddev, conf->thread); md_write_end(conf->mddev);
bi->bi_next = return_bi; bi->bi_next = return_bi;
return_bi = bi; return_bi = bi;
} }
...@@ -970,7 +969,7 @@ static void handle_stripe(struct stripe_head *sh) ...@@ -970,7 +969,7 @@ static void handle_stripe(struct stripe_head *sh)
while (wbi && wbi->bi_sector < dev->sector + STRIPE_SECTORS) { while (wbi && wbi->bi_sector < dev->sector + STRIPE_SECTORS) {
wbi2 = wbi->bi_next; wbi2 = wbi->bi_next;
if (--wbi->bi_phys_segments == 0) { if (--wbi->bi_phys_segments == 0) {
md_write_end(conf->mddev, conf->thread); md_write_end(conf->mddev);
wbi->bi_next = return_bi; wbi->bi_next = return_bi;
return_bi = wbi; return_bi = wbi;
} }
...@@ -1113,7 +1112,7 @@ static void handle_stripe(struct stripe_head *sh) ...@@ -1113,7 +1112,7 @@ static void handle_stripe(struct stripe_head *sh)
if (test_and_clear_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) { if (test_and_clear_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) {
atomic_dec(&conf->preread_active_stripes); atomic_dec(&conf->preread_active_stripes);
if (atomic_read(&conf->preread_active_stripes) < IO_THRESHOLD) if (atomic_read(&conf->preread_active_stripes) < IO_THRESHOLD)
md_wakeup_thread(conf->thread); md_wakeup_thread(conf->mddev->thread);
} }
} }
} }
...@@ -1207,7 +1206,7 @@ static void handle_stripe(struct stripe_head *sh) ...@@ -1207,7 +1206,7 @@ static void handle_stripe(struct stripe_head *sh)
bi->bi_bdev = rdev->bdev; bi->bi_bdev = rdev->bdev;
PRINTK("for %llu schedule op %ld on disc %d\n", (unsigned long long)sh->sector, bi->bi_rw, i); PRINTK("for %llu schedule op %ld on disc %d\n", (unsigned long long)sh->sector, bi->bi_rw, i);
atomic_inc(&sh->count); atomic_inc(&sh->count);
bi->bi_sector = sh->sector; bi->bi_sector = sh->sector + rdev->data_offset;
bi->bi_flags = 1 << BIO_UPTODATE; bi->bi_flags = 1 << BIO_UPTODATE;
bi->bi_vcnt = 1; bi->bi_vcnt = 1;
bi->bi_idx = 0; bi->bi_idx = 0;
...@@ -1251,7 +1250,7 @@ static void raid5_unplug_device(void *data) ...@@ -1251,7 +1250,7 @@ static void raid5_unplug_device(void *data)
if (blk_remove_plug(q)) if (blk_remove_plug(q))
raid5_activate_delayed(conf); raid5_activate_delayed(conf);
md_wakeup_thread(conf->thread); md_wakeup_thread(mddev->thread);
spin_unlock_irqrestore(&conf->device_lock, flags); spin_unlock_irqrestore(&conf->device_lock, flags);
} }
...@@ -1304,7 +1303,7 @@ static int make_request (request_queue_t *q, struct bio * bi) ...@@ -1304,7 +1303,7 @@ static int make_request (request_queue_t *q, struct bio * bi)
int bytes = bi->bi_size; int bytes = bi->bi_size;
if ( bio_data_dir(bi) == WRITE ) if ( bio_data_dir(bi) == WRITE )
md_write_end(mddev,conf->thread); md_write_end(mddev);
bi->bi_size = 0; bi->bi_size = 0;
bi->bi_end_io(bi, bytes, 0); bi->bi_end_io(bi, bytes, 0);
} }
...@@ -1356,16 +1355,17 @@ static int sync_request (mddev_t *mddev, sector_t sector_nr, int go_faster) ...@@ -1356,16 +1355,17 @@ static int sync_request (mddev_t *mddev, sector_t sector_nr, int go_faster)
* During the scan, completed stripes are saved for us by the interrupt * During the scan, completed stripes are saved for us by the interrupt
* handler, so that they will not have to wait for our next wakeup. * handler, so that they will not have to wait for our next wakeup.
*/ */
static void raid5d (void *data) static void raid5d (mddev_t *mddev)
{ {
struct stripe_head *sh; struct stripe_head *sh;
raid5_conf_t *conf = data; raid5_conf_t *conf = mddev_to_conf(mddev);
mddev_t *mddev = conf->mddev;
int handled; int handled;
PRINTK("+++ raid5d active\n"); PRINTK("+++ raid5d active\n");
md_check_recovery(mddev);
md_handle_safemode(mddev); md_handle_safemode(mddev);
handled = 0; handled = 0;
spin_lock_irq(&conf->device_lock); spin_lock_irq(&conf->device_lock);
while (1) { while (1) {
...@@ -1486,10 +1486,8 @@ static int run (mddev_t *mddev) ...@@ -1486,10 +1486,8 @@ static int run (mddev_t *mddev)
} }
{ {
snprintf(conf->thread_name,MD_THREAD_NAME_MAX,"raid5d_md%d",mdidx(mddev)); mddev->thread = md_register_thread(raid5d, mddev, "md%d_raid5");
if (!mddev->thread) {
conf->thread = md_register_thread(raid5d, conf, conf->thread_name);
if (!conf->thread) {
printk(KERN_ERR "raid5: couldn't allocate thread for md%d\n", mdidx(mddev)); printk(KERN_ERR "raid5: couldn't allocate thread for md%d\n", mdidx(mddev));
goto abort; goto abort;
} }
...@@ -1500,7 +1498,7 @@ static int run (mddev_t *mddev) ...@@ -1500,7 +1498,7 @@ static int run (mddev_t *mddev)
if (grow_stripes(conf, conf->max_nr_stripes)) { if (grow_stripes(conf, conf->max_nr_stripes)) {
printk(KERN_ERR "raid5: couldn't allocate %dkB for buffers\n", memory); printk(KERN_ERR "raid5: couldn't allocate %dkB for buffers\n", memory);
shrink_stripes(conf); shrink_stripes(conf);
md_unregister_thread(conf->thread); md_unregister_thread(mddev->thread);
goto abort; goto abort;
} else } else
printk(KERN_INFO "raid5: allocated %dkB for md%d\n", memory, mdidx(mddev)); printk(KERN_INFO "raid5: allocated %dkB for md%d\n", memory, mdidx(mddev));
...@@ -1536,7 +1534,8 @@ static int stop (mddev_t *mddev) ...@@ -1536,7 +1534,8 @@ static int stop (mddev_t *mddev)
{ {
raid5_conf_t *conf = (raid5_conf_t *) mddev->private; raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
md_unregister_thread(conf->thread); md_unregister_thread(mddev->thread);
mddev->thread = NULL;
shrink_stripes(conf); shrink_stripes(conf);
free_pages((unsigned long) conf->stripe_hashtbl, HASH_PAGES_ORDER); free_pages((unsigned long) conf->stripe_hashtbl, HASH_PAGES_ORDER);
kfree(conf); kfree(conf);
...@@ -1574,29 +1573,26 @@ static void printall (raid5_conf_t *conf) ...@@ -1574,29 +1573,26 @@ static void printall (raid5_conf_t *conf)
} }
} }
spin_unlock_irq(&conf->device_lock); spin_unlock_irq(&conf->device_lock);
PRINTK("--- raid5d inactive\n");
} }
#endif #endif
static int status (char *page, mddev_t *mddev) static void status (struct seq_file *seq, mddev_t *mddev)
{ {
raid5_conf_t *conf = (raid5_conf_t *) mddev->private; raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
int sz = 0, i; int i;
sz += sprintf (page+sz, " level %d, %dk chunk, algorithm %d", mddev->level, mddev->chunk_size >> 10, mddev->layout); seq_printf (seq, " level %d, %dk chunk, algorithm %d", mddev->level, mddev->chunk_size >> 10, mddev->layout);
sz += sprintf (page+sz, " [%d/%d] [", conf->raid_disks, conf->working_disks); seq_printf (seq, " [%d/%d] [", conf->raid_disks, conf->working_disks);
for (i = 0; i < conf->raid_disks; i++) for (i = 0; i < conf->raid_disks; i++)
sz += sprintf (page+sz, "%s", seq_printf (seq, "%s",
conf->disks[i].rdev && conf->disks[i].rdev &&
conf->disks[i].rdev->in_sync ? "U" : "_"); conf->disks[i].rdev->in_sync ? "U" : "_");
sz += sprintf (page+sz, "]"); seq_printf (seq, "]");
#if RAID5_DEBUG #if RAID5_DEBUG
#define D(x) \ #define D(x) \
sz += sprintf (page+sz, "<"#x":%d>", atomic_read(&conf->x)) seq_printf (seq, "<"#x":%d>", atomic_read(&conf->x))
printall(conf); printall(conf);
#endif #endif
return sz;
} }
static void print_raid5_conf (raid5_conf_t *conf) static void print_raid5_conf (raid5_conf_t *conf)
......
...@@ -36,7 +36,6 @@ ...@@ -36,7 +36,6 @@
#include <asm/io.h> #include <asm/io.h>
#include "bttvp.h" #include "bttvp.h"
#include "tuner.h"
#include "bt832.h" #include "bt832.h"
/* fwd decl */ /* fwd decl */
......
...@@ -37,7 +37,6 @@ ...@@ -37,7 +37,6 @@
#include <asm/io.h> #include <asm/io.h>
#include "bttvp.h" #include "bttvp.h"
#include "tuner.h"
int bttv_num; /* number of Bt848s in use */ int bttv_num; /* number of Bt848s in use */
struct bttv bttvs[BTTV_MAX]; struct bttv bttvs[BTTV_MAX];
......
...@@ -34,7 +34,6 @@ ...@@ -34,7 +34,6 @@
#include <asm/io.h> #include <asm/io.h>
#include "bttvp.h" #include "bttvp.h"
#include "tuner.h"
static struct i2c_algo_bit_data bttv_i2c_algo_template; static struct i2c_algo_bit_data bttv_i2c_algo_template;
static struct i2c_adapter bttv_i2c_adap_template; static struct i2c_adapter bttv_i2c_adap_template;
......
...@@ -34,10 +34,12 @@ ...@@ -34,10 +34,12 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <asm/scatterlist.h> #include <asm/scatterlist.h>
#include <media/video-buf.h>
#include <media/audiochip.h>
#include <media/tuner.h>
#include "bt848.h" #include "bt848.h"
#include "bttv.h" #include "bttv.h"
#include "video-buf.h"
#include "audiochip.h"
#ifdef __KERNEL__ #ifdef __KERNEL__
......
...@@ -56,7 +56,7 @@ ...@@ -56,7 +56,7 @@
#define __KERNEL_SYSCALLS__ #define __KERNEL_SYSCALLS__
#include <linux/unistd.h> #include <linux/unistd.h>
#include "audiochip.h" #include <media/audiochip.h>
#include "msp3400.h" #include "msp3400.h"
/* Addresses to scan */ /* Addresses to scan */
...@@ -1495,8 +1495,8 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) ...@@ -1495,8 +1495,8 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
VIDEO_AUDIO_MUTABLE; VIDEO_AUDIO_MUTABLE;
if (msp->muted) if (msp->muted)
va->flags |= VIDEO_AUDIO_MUTE; va->flags |= VIDEO_AUDIO_MUTE;
va->volume=MAX(msp->left,msp->right); va->volume=max(msp->left,msp->right);
va->balance=(32768*MIN(msp->left,msp->right))/ va->balance=(32768*min(msp->left,msp->right))/
(va->volume ? va->volume : 1); (va->volume ? va->volume : 1);
va->balance=(msp->left<msp->right)? va->balance=(msp->left<msp->right)?
(65535-va->balance) : va->balance; (65535-va->balance) : va->balance;
...@@ -1517,9 +1517,9 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) ...@@ -1517,9 +1517,9 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
dprintk(KERN_DEBUG "msp34xx: VIDIOCSAUDIO\n"); dprintk(KERN_DEBUG "msp34xx: VIDIOCSAUDIO\n");
msp->muted = (va->flags & VIDEO_AUDIO_MUTE); msp->muted = (va->flags & VIDEO_AUDIO_MUTE);
msp->left = (MIN(65536 - va->balance,32768) * msp->left = (min(65536 - va->balance,32768) *
va->volume) / 32768; va->volume) / 32768;
msp->right = (MIN(va->balance,32768) * msp->right = (min(va->balance,(__u16)32768) *
va->volume) / 32768; va->volume) / 32768;
msp->bass = va->bass; msp->bass = va->bass;
msp->treble = va->treble; msp->treble = va->treble;
......
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
#include "saa7134-reg.h" #include "saa7134-reg.h"
#include "saa7134.h" #include "saa7134.h"
#include "tuner.h"
/* commly used strings */ /* commly used strings */
static char name_mute[] = "mute"; static char name_mute[] = "mute";
......
...@@ -30,7 +30,6 @@ ...@@ -30,7 +30,6 @@
#include "saa7134-reg.h" #include "saa7134-reg.h"
#include "saa7134.h" #include "saa7134.h"
#include "tuner.h"
MODULE_DESCRIPTION("v4l2 driver module for saa7130/34 based TV cards"); MODULE_DESCRIPTION("v4l2 driver module for saa7130/34 based TV cards");
MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
......
...@@ -30,8 +30,6 @@ ...@@ -30,8 +30,6 @@
#include "saa7134-reg.h" #include "saa7134-reg.h"
#include "saa7134.h" #include "saa7134.h"
#include "tuner.h"
#include "id.h"
/* ----------------------------------------------------------- */ /* ----------------------------------------------------------- */
......
...@@ -29,8 +29,6 @@ ...@@ -29,8 +29,6 @@
#include "saa7134-reg.h" #include "saa7134-reg.h"
#include "saa7134.h" #include "saa7134.h"
#include "tuner.h"
#include "audiochip.h"
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
......
...@@ -22,7 +22,11 @@ ...@@ -22,7 +22,11 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/videodev.h> #include <linux/videodev.h>
#include <linux/kdev_t.h> #include <linux/kdev_t.h>
#include "video-buf.h"
#include <media/video-buf.h>
#include <media/tuner.h>
#include <media/audiochip.h>
#include <media/id.h>
#define SAA7134_VERSION_CODE KERNEL_VERSION(0,2,2) #define SAA7134_VERSION_CODE KERNEL_VERSION(0,2,2)
......
...@@ -49,8 +49,8 @@ ...@@ -49,8 +49,8 @@
#include <linux/i2c-algo-bit.h> #include <linux/i2c-algo-bit.h>
#include "bttv.h" #include "bttv.h"
#include "audiochip.h" #include <media/audiochip.h>
#include "id.h" #include <media/id.h>
#ifndef VIDEO_AUDIO_BALANCE #ifndef VIDEO_AUDIO_BALANCE
# define VIDEO_AUDIO_BALANCE 32 # define VIDEO_AUDIO_BALANCE 32
......
...@@ -31,8 +31,8 @@ ...@@ -31,8 +31,8 @@
#include <linux/init.h> #include <linux/init.h>
#include "bttv.h" #include "bttv.h"
#include "audiochip.h" #include <media/audiochip.h>
#include "id.h" #include <media/id.h>
MODULE_PARM(debug,"i"); MODULE_PARM(debug,"i");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -316,17 +316,15 @@ static int tda9875_command(struct i2c_client *client, ...@@ -316,17 +316,15 @@ static int tda9875_command(struct i2c_client *client,
/* min is -84 max is 24 */ /* min is -84 max is 24 */
left = (t->lvol+84)*606; left = (t->lvol+84)*606;
right = (t->rvol+84)*606; right = (t->rvol+84)*606;
va->volume=MAX(left,right); va->volume=max(left,right);
va->balance=(32768*MIN(left,right))/ va->balance=(32768*min(left,right))/
(va->volume ? va->volume : 1); (va->volume ? va->volume : 1);
va->balance=(left<right)? va->balance=(left<right)?
(65535-va->balance) : va->balance; (65535-va->balance) : va->balance;
va->bass = (t->bass+12)*2427; /* min -12 max +15 */ va->bass = (t->bass+12)*2427; /* min -12 max +15 */
va->treble = (t->treble+12)*2730;/* min -12 max +12 */ va->treble = (t->treble+12)*2730;/* min -12 max +12 */
va->mode |= VIDEO_SOUND_MONO; va->mode |= VIDEO_SOUND_MONO;
break; /* VIDIOCGAUDIO case */ break; /* VIDIOCGAUDIO case */
} }
...@@ -336,9 +334,9 @@ static int tda9875_command(struct i2c_client *client, ...@@ -336,9 +334,9 @@ static int tda9875_command(struct i2c_client *client,
int left,right; int left,right;
dprintk("VIDEOCSAUDIO...\n"); dprintk("VIDEOCSAUDIO...\n");
left = (MIN(65536 - va->balance,32768) * left = (min(65536 - va->balance,32768) *
va->volume) / 32768; va->volume) / 32768;
right = (MIN(va->balance,32768) * right = (min(va->balance,(__u16)32768) *
va->volume) / 32768; va->volume) / 32768;
t->lvol = ((left/606)-84) & 0xff; t->lvol = ((left/606)-84) & 0xff;
if (t->lvol > 24) if (t->lvol > 24)
......
...@@ -7,8 +7,8 @@ ...@@ -7,8 +7,8 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/slab.h> #include <linux/slab.h>
#include "id.h" #include <media/audiochip.h>
#include "audiochip.h" #include <media/id.h>
/* Chips: /* Chips:
TDA9885 (PAL, NTSC) TDA9885 (PAL, NTSC)
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/videodev.h> #include <linux/videodev.h>
#include "tuner.h" #include <media/tuner.h>
static int debug; /* insmod parameter */ static int debug; /* insmod parameter */
static int this_adap; static int this_adap;
......
...@@ -12,8 +12,8 @@ ...@@ -12,8 +12,8 @@
#include <linux/videodev.h> #include <linux/videodev.h>
#include <linux/init.h> #include <linux/init.h>
#include "tuner.h" #include <media/tuner.h>
#include "audiochip.h" #include <media/audiochip.h>
/* Addresses to scan */ /* Addresses to scan */
static unsigned short normal_i2c[] = {I2C_CLIENT_END}; static unsigned short normal_i2c[] = {I2C_CLIENT_END};
......
...@@ -29,9 +29,10 @@ ...@@ -29,9 +29,10 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include "audiochip.h" #include <media/audiochip.h>
#include <media/id.h>
#include "tvaudio.h" #include "tvaudio.h"
#include "id.h"
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
...@@ -1477,8 +1478,8 @@ static int chip_command(struct i2c_client *client, ...@@ -1477,8 +1478,8 @@ static int chip_command(struct i2c_client *client,
if (desc->flags & CHIP_HAS_VOLUME) { if (desc->flags & CHIP_HAS_VOLUME) {
va->flags |= VIDEO_AUDIO_VOLUME; va->flags |= VIDEO_AUDIO_VOLUME;
va->volume = MAX(chip->left,chip->right); va->volume = max(chip->left,chip->right);
va->balance = (32768*MIN(chip->left,chip->right))/ va->balance = (32768*min(chip->left,chip->right))/
(va->volume ? va->volume : 1); (va->volume ? va->volume : 1);
} }
if (desc->flags & CHIP_HAS_BASSTREBLE) { if (desc->flags & CHIP_HAS_BASSTREBLE) {
...@@ -1500,9 +1501,9 @@ static int chip_command(struct i2c_client *client, ...@@ -1500,9 +1501,9 @@ static int chip_command(struct i2c_client *client,
struct video_audio *va = arg; struct video_audio *va = arg;
if (desc->flags & CHIP_HAS_VOLUME) { if (desc->flags & CHIP_HAS_VOLUME) {
chip->left = (MIN(65536 - va->balance,32768) * chip->left = (min(65536 - va->balance,32768) *
va->volume) / 32768; va->volume) / 32768;
chip->right = (MIN(va->balance,32768) * chip->right = (min(va->balance,(__u16)32768) *
va->volume) / 32768; va->volume) / 32768;
chip_write(chip,desc->leftreg,desc->volfunc(chip->left)); chip_write(chip,desc->leftreg,desc->volfunc(chip->left));
chip_write(chip,desc->rightreg,desc->volfunc(chip->right)); chip_write(chip,desc->rightreg,desc->volfunc(chip->right));
......
...@@ -16,8 +16,6 @@ ...@@ -16,8 +16,6 @@
#include <linux/soundcard.h> #include <linux/soundcard.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include "audiochip.h"
#include "id.h"
#define DEV_MAX 4 #define DEV_MAX 4
...@@ -136,16 +134,16 @@ static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cm ...@@ -136,16 +134,16 @@ static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cm
case MIXER_WRITE(SOUND_MIXER_VOLUME): case MIXER_WRITE(SOUND_MIXER_VOLUME):
left = mix_to_v4l(val); left = mix_to_v4l(val);
right = mix_to_v4l(val >> 8); right = mix_to_v4l(val >> 8);
va.volume = MAX(left,right); va.volume = max(left,right);
va.balance = (32768*MIN(left,right)) / (va.volume ? va.volume : 1); va.balance = (32768*min(left,right)) / (va.volume ? va.volume : 1);
va.balance = (left<right) ? (65535-va.balance) : va.balance; va.balance = (left<right) ? (65535-va.balance) : va.balance;
client->driver->command(client,VIDIOCSAUDIO,&va); client->driver->command(client,VIDIOCSAUDIO,&va);
client->driver->command(client,VIDIOCGAUDIO,&va); client->driver->command(client,VIDIOCGAUDIO,&va);
/* fall throuth */ /* fall throuth */
case MIXER_READ(SOUND_MIXER_VOLUME): case MIXER_READ(SOUND_MIXER_VOLUME):
left = (MIN(65536 - va.balance,32768) * left = (min(65536 - va.balance,32768) *
va.volume) / 32768; va.volume) / 32768;
right = (MIN(va.balance,32768) * right = (min(va.balance,32768) *
va.volume) / 32768; va.volume) / 32768;
ret = v4l_to_mix2(left,right); ret = v4l_to_mix2(left,right);
break; break;
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
# define TryLockPage TestSetPageLocked # define TryLockPage TestSetPageLocked
#endif #endif
#include "video-buf.h" #include <media/video-buf.h>
static int debug = 0; static int debug = 0;
......
...@@ -305,8 +305,6 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file, ...@@ -305,8 +305,6 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
(long long)lock->fl.fl_end, (long long)lock->fl.fl_end,
wait); wait);
/* Lock file against concurrent access */
down(&file->f_sema);
/* Get existing block (in case client is busy-waiting) */ /* Get existing block (in case client is busy-waiting) */
block = nlmsvc_lookup_block(file, lock, 0); block = nlmsvc_lookup_block(file, lock, 0);
...@@ -314,6 +312,9 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file, ...@@ -314,6 +312,9 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
lock->fl.fl_flags |= FL_LOCKD; lock->fl.fl_flags |= FL_LOCKD;
again: again:
/* Lock file against concurrent access */
down(&file->f_sema);
if (!(conflock = posix_test_lock(&file->f_file, &lock->fl))) { if (!(conflock = posix_test_lock(&file->f_file, &lock->fl))) {
error = posix_lock_file(&file->f_file, &lock->fl); error = posix_lock_file(&file->f_file, &lock->fl);
...@@ -346,7 +347,10 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file, ...@@ -346,7 +347,10 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
/* If we don't have a block, create and initialize it. Then /* If we don't have a block, create and initialize it. Then
* retry because we may have slept in kmalloc. */ * retry because we may have slept in kmalloc. */
/* We have to release f_sema as nlmsvc_create_block may try to
* to claim it while doing host garbage collection */
if (block == NULL) { if (block == NULL) {
up(&file->f_sema);
dprintk("lockd: blocking on this lock (allocating).\n"); dprintk("lockd: blocking on this lock (allocating).\n");
if (!(block = nlmsvc_create_block(rqstp, file, lock, cookie))) if (!(block = nlmsvc_create_block(rqstp, file, lock, cookie)))
return nlm_lck_denied_nolocks; return nlm_lck_denied_nolocks;
......
...@@ -294,7 +294,9 @@ int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen) ...@@ -294,7 +294,9 @@ int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
/* client */ /* client */
len = qword_get(&mesg, buf, PAGE_SIZE); len = qword_get(&mesg, buf, PAGE_SIZE);
if (len <= 0) return -EINVAL; err = -EINVAL;
if (len <= 0) goto out;
err = -ENOENT; err = -ENOENT;
dom = auth_domain_find(buf); dom = auth_domain_find(buf);
if (!dom) if (!dom)
...@@ -473,8 +475,14 @@ exp_get_by_name(svc_client *clp, struct vfsmount *mnt, struct dentry *dentry, ...@@ -473,8 +475,14 @@ exp_get_by_name(svc_client *clp, struct vfsmount *mnt, struct dentry *dentry,
exp = svc_export_lookup(&key, 0); exp = svc_export_lookup(&key, 0);
if (exp != NULL) if (exp != NULL)
if (cache_check(&svc_export_cache, &exp->h, reqp)) switch (cache_check(&svc_export_cache, &exp->h, reqp)) {
case 0: break;
case -EAGAIN:
exp = ERR_PTR(-EAGAIN);
break;
default:
exp = NULL; exp = NULL;
}
return exp; return exp;
} }
...@@ -915,7 +923,8 @@ struct flags { ...@@ -915,7 +923,8 @@ struct flags {
{ NFSEXP_UIDMAP, {"uidmap", ""}}, { NFSEXP_UIDMAP, {"uidmap", ""}},
{ NFSEXP_KERBEROS, { "kerberos", ""}}, { NFSEXP_KERBEROS, { "kerberos", ""}},
{ NFSEXP_SUNSECURE, { "sunsecure", ""}}, { NFSEXP_SUNSECURE, { "sunsecure", ""}},
{ NFSEXP_CROSSMNT, {"nohide", ""}}, { NFSEXP_NOHIDE, {"nohide", ""}},
{ NFSEXP_CROSSMNT, {"crossmnt", ""}},
{ NFSEXP_NOSUBTREECHECK, {"no_subtree_check", ""}}, { NFSEXP_NOSUBTREECHECK, {"no_subtree_check", ""}},
{ NFSEXP_NOAUTHNLM, {"insecure_locks", ""}}, { NFSEXP_NOAUTHNLM, {"insecure_locks", ""}},
#ifdef MSNFS #ifdef MSNFS
......
...@@ -79,7 +79,7 @@ static struct raparms * raparm_cache; ...@@ -79,7 +79,7 @@ static struct raparms * raparm_cache;
* N.B. After this call _both_ fhp and resfh need an fh_put * N.B. After this call _both_ fhp and resfh need an fh_put
* *
* If the lookup would cross a mountpoint, and the mounted filesystem * If the lookup would cross a mountpoint, and the mounted filesystem
* is exported to the client with NFSEXP_CROSSMNT, then the lookup is * is exported to the client with NFSEXP_NOHIDE, then the lookup is
* accepted as it stands and the mounted directory is * accepted as it stands and the mounted directory is
* returned. Otherwise the covered directory is returned. * returned. Otherwise the covered directory is returned.
* NOTE: this mountpoint crossing is not supported properly by all * NOTE: this mountpoint crossing is not supported properly by all
...@@ -115,7 +115,7 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name, ...@@ -115,7 +115,7 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name,
read_lock(&dparent_lock); read_lock(&dparent_lock);
dentry = dget(dparent->d_parent); dentry = dget(dparent->d_parent);
read_unlock(&dparent_lock); read_unlock(&dparent_lock);
} else if (!EX_CROSSMNT(exp)) } else if (!EX_NOHIDE(exp))
dentry = dget(dparent); /* .. == . just like at / */ dentry = dget(dparent); /* .. == . just like at / */
else { else {
/* checking mountpoint crossing is very different when stepping up */ /* checking mountpoint crossing is very different when stepping up */
...@@ -133,6 +133,12 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name, ...@@ -133,6 +133,12 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name,
exp2 = exp_parent(exp->ex_client, mnt, dentry, exp2 = exp_parent(exp->ex_client, mnt, dentry,
&rqstp->rq_chandle); &rqstp->rq_chandle);
if (IS_ERR(exp2)) {
err = PTR_ERR(exp2);
dput(dentry);
mntput(mnt);
goto out;
}
if (!exp2) { if (!exp2) {
dput(dentry); dput(dentry);
dentry = dget(dparent); dentry = dget(dparent);
...@@ -157,9 +163,19 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name, ...@@ -157,9 +163,19 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name,
struct dentry *mounts = dget(dentry); struct dentry *mounts = dget(dentry);
while (follow_down(&mnt,&mounts)&&d_mountpoint(mounts)) while (follow_down(&mnt,&mounts)&&d_mountpoint(mounts))
; ;
exp2 = exp_get_by_name(exp->ex_client, mnt, exp2 = exp_get_by_name(exp->ex_client, mnt,
mounts, &rqstp->rq_chandle); mounts, &rqstp->rq_chandle);
if (exp2 && EX_CROSSMNT(exp2)) { if (IS_ERR(exp2)) {
err = PTR_ERR(exp2);
dput(mounts);
dput(dentry);
mntput(mnt);
goto out;
}
if (exp2 &&
((exp->ex_flags & NFSEXP_CROSSMNT)
|| EX_NOHIDE(exp2))) {
/* successfully crossed mount point */ /* successfully crossed mount point */
exp_put(exp); exp_put(exp);
exp = exp2; exp = exp2;
......
This diff is collapsed.
This diff is collapsed.
...@@ -9,9 +9,9 @@ ...@@ -9,9 +9,9 @@
#include <linux/bitops.h> #include <linux/bitops.h>
#define NCAPINTS 4 /* Currently we have 4 32-bit words worth of info */ #define NCAPINTS 6 /* Currently we have 6 32-bit words worth of info */
/* Intel-defined CPU features, CPUID level 0x00000001, word 0 */ /* Intel-defined CPU features, CPUID level 0x00000001 (edx), word 0 */
#define X86_FEATURE_FPU (0*32+ 0) /* Onboard FPU */ #define X86_FEATURE_FPU (0*32+ 0) /* Onboard FPU */
#define X86_FEATURE_VME (0*32+ 1) /* Virtual Mode Extensions */ #define X86_FEATURE_VME (0*32+ 1) /* Virtual Mode Extensions */
#define X86_FEATURE_DE (0*32+ 2) /* Debugging Extensions */ #define X86_FEATURE_DE (0*32+ 2) /* Debugging Extensions */
...@@ -64,6 +64,11 @@ ...@@ -64,6 +64,11 @@
#define X86_FEATURE_CYRIX_ARR (3*32+ 2) /* Cyrix ARRs (= MTRRs) */ #define X86_FEATURE_CYRIX_ARR (3*32+ 2) /* Cyrix ARRs (= MTRRs) */
#define X86_FEATURE_CENTAUR_MCR (3*32+ 3) /* Centaur MCRs (= MTRRs) */ #define X86_FEATURE_CENTAUR_MCR (3*32+ 3) /* Centaur MCRs (= MTRRs) */
/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */
#define X86_FEATURE_XSTORE (5*32+ 2) /* on-CPU RNG present (xstore insn) */
#define cpu_has(c, bit) test_bit(bit, (c)->x86_capability) #define cpu_has(c, bit) test_bit(bit, (c)->x86_capability)
#define boot_cpu_has(bit) test_bit(bit, boot_cpu_data.x86_capability) #define boot_cpu_has(bit) test_bit(bit, boot_cpu_data.x86_capability)
...@@ -87,6 +92,7 @@ ...@@ -87,6 +92,7 @@
#define cpu_has_k6_mtrr boot_cpu_has(X86_FEATURE_K6_MTRR) #define cpu_has_k6_mtrr boot_cpu_has(X86_FEATURE_K6_MTRR)
#define cpu_has_cyrix_arr boot_cpu_has(X86_FEATURE_CYRIX_ARR) #define cpu_has_cyrix_arr boot_cpu_has(X86_FEATURE_CYRIX_ARR)
#define cpu_has_centaur_mcr boot_cpu_has(X86_FEATURE_CENTAUR_MCR) #define cpu_has_centaur_mcr boot_cpu_has(X86_FEATURE_CENTAUR_MCR)
#define cpu_has_xstore boot_cpu_has(X86_FEATURE_XSTORE)
#endif /* __ASM_I386_CPUFEATURE_H */ #endif /* __ASM_I386_CPUFEATURE_H */
......
...@@ -218,6 +218,7 @@ ...@@ -218,6 +218,7 @@
/* VIA Cyrix defined MSRs*/ /* VIA Cyrix defined MSRs*/
#define MSR_VIA_FCR 0x1107 #define MSR_VIA_FCR 0x1107
#define MSR_VIA_LONGHAUL 0x110a #define MSR_VIA_LONGHAUL 0x110a
#define MSR_VIA_RNG 0x110b
#define MSR_VIA_BCR2 0x1147 #define MSR_VIA_BCR2 0x1147
/* Transmeta defined MSRs */ /* Transmeta defined MSRs */
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment