Merge branch 'upstream'

This commit is contained in:
Jeff Garzik 2005-10-09 11:16:14 -04:00
commit c4052da6f0
135 changed files with 4493 additions and 1639 deletions

File diff suppressed because it is too large Load Diff

View File

@ -305,7 +305,7 @@ long execve(const char *filename, char **argv, char **envp)
"Ir" (THREAD_START_SP - sizeof(regs)),
"r" (&regs),
"Ir" (sizeof(regs))
: "r0", "r1", "r2", "r3", "ip", "memory");
: "r0", "r1", "r2", "r3", "ip", "lr", "memory");
out:
return ret;

View File

@ -504,7 +504,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
bad_access:
spin_unlock(&mm->page_table_lock);
/* simulate a read access fault */
/* simulate a write access fault */
do_DataAbort(addr, 15 + (1 << 11), regs);
return -1;
}

View File

@ -28,14 +28,15 @@
#include <linux/module.h>
#include <asm/arch/imxfb.h>
#include <asm/hardware.h>
#include <asm/arch/imx-regs.h>
#include <asm/mach/map.h>
void imx_gpio_mode(int gpio_mode)
{
unsigned int pin = gpio_mode & GPIO_PIN_MASK;
unsigned int port = (gpio_mode & GPIO_PORT_MASK) >> 5;
unsigned int ocr = (gpio_mode & GPIO_OCR_MASK) >> 10;
unsigned int port = (gpio_mode & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
unsigned int ocr = (gpio_mode & GPIO_OCR_MASK) >> GPIO_OCR_SHIFT;
unsigned int tmp;
/* Pullup enable */
@ -57,7 +58,7 @@ void imx_gpio_mode(int gpio_mode)
GPR(port) &= ~(1<<pin);
/* use as gpio? */
if( ocr == 3 )
if(gpio_mode & GPIO_GIUS)
GIUS(port) |= (1<<pin);
else
GIUS(port) &= ~(1<<pin);
@ -72,20 +73,20 @@ void imx_gpio_mode(int gpio_mode)
tmp |= (ocr << (pin*2));
OCR1(port) = tmp;
if( gpio_mode & GPIO_AOUT )
ICONFA1(port) &= ~( 3<<(pin*2));
if( gpio_mode & GPIO_BOUT )
ICONFB1(port) &= ~( 3<<(pin*2));
ICONFA1(port) &= ~( 3<<(pin*2));
ICONFA1(port) |= ((gpio_mode >> GPIO_AOUT_SHIFT) & 3) << (pin * 2);
ICONFB1(port) &= ~( 3<<(pin*2));
ICONFB1(port) |= ((gpio_mode >> GPIO_BOUT_SHIFT) & 3) << (pin * 2);
} else {
tmp = OCR2(port);
tmp &= ~( 3<<((pin-16)*2));
tmp |= (ocr << ((pin-16)*2));
OCR2(port) = tmp;
if( gpio_mode & GPIO_AOUT )
ICONFA2(port) &= ~( 3<<((pin-16)*2));
if( gpio_mode & GPIO_BOUT )
ICONFB2(port) &= ~( 3<<((pin-16)*2));
ICONFA2(port) &= ~( 3<<((pin-16)*2));
ICONFA2(port) |= ((gpio_mode >> GPIO_AOUT_SHIFT) & 3) << ((pin-16) * 2);
ICONFB2(port) &= ~( 3<<((pin-16)*2));
ICONFB2(port) |= ((gpio_mode >> GPIO_BOUT_SHIFT) & 3) << ((pin-16) * 2);
}
}

View File

@ -55,7 +55,7 @@ static void __init
mx1ads_init(void)
{
#ifdef CONFIG_LEDS
imx_gpio_mode(GPIO_PORTA | GPIO_OUT | GPIO_GPIO | 2);
imx_gpio_mode(GPIO_PORTA | GPIO_OUT | 2);
#endif
platform_add_devices(devices, ARRAY_SIZE(devices));
}

View File

@ -370,21 +370,21 @@ config CPU_BIG_ENDIAN
config CPU_ICACHE_DISABLE
bool "Disable I-Cache"
depends on CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020
depends on CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020 || CPU_V6
help
Say Y here to disable the processor instruction cache. Unless
you have a reason not to or are unsure, say N.
config CPU_DCACHE_DISABLE
bool "Disable D-Cache"
depends on CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020
depends on CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020 || CPU_V6
help
Say Y here to disable the processor data cache. Unless
you have a reason not to or are unsure, say N.
config CPU_DCACHE_WRITETHROUGH
bool "Force write through D-cache"
depends on (CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020) && !CPU_DCACHE_DISABLE
depends on (CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020 || CPU_V6) && !CPU_DCACHE_DISABLE
default y if CPU_ARM925T
help
Say Y here to use the data cache in writethrough mode. Unless you
@ -399,7 +399,7 @@ config CPU_CACHE_ROUND_ROBIN
config CPU_BPREDICT_DISABLE
bool "Disable branch prediction"
depends on CPU_ARM1020
depends on CPU_ARM1020 || CPU_V6
help
Say Y here to disable branch prediction. If unsure, say N.

View File

@ -1016,6 +1016,11 @@ ia64_mca_cmc_int_handler(int cmc_irq, void *arg, struct pt_regs *ptregs)
cmc_polling_enabled = 1;
spin_unlock(&cmc_history_lock);
/* If we're being hit with CMC interrupts, we won't
* ever execute the schedule_work() below. Need to
* disable CMC interrupts on this processor now.
*/
ia64_mca_cmc_vector_disable(NULL);
schedule_work(&cmc_disable_work);
/*

View File

@ -195,7 +195,7 @@ via_calibrate_decr(void)
;
dend = get_dec();
tb_ticks_per_jiffy = (dstart - dend) / (6 * (HZ/100));
tb_ticks_per_jiffy = (dstart - dend) / ((6 * HZ)/100);
tb_to_us = mulhwu_scale_factor(dstart - dend, 60000);
printk(KERN_INFO "via_calibrate_decr: ticks per jiffy = %u (%u ticks)\n",

View File

@ -25,62 +25,6 @@ source "init/Kconfig"
menu "General machine setup"
config VT
bool
select INPUT
default y
---help---
If you say Y here, you will get support for terminal devices with
display and keyboard devices. These are called "virtual" because you
can run several virtual terminals (also called virtual consoles) on
one physical terminal. This is rather useful, for example one
virtual terminal can collect system messages and warnings, another
one can be used for a text-mode user session, and a third could run
an X session, all in parallel. Switching between virtual terminals
is done with certain key combinations, usually Alt-<function key>.
The setterm command ("man setterm") can be used to change the
properties (such as colors or beeping) of a virtual terminal. The
man page console_codes(4) ("man console_codes") contains the special
character sequences that can be used to change those properties
directly. The fonts used on virtual terminals can be changed with
the setfont ("man setfont") command and the key bindings are defined
with the loadkeys ("man loadkeys") command.
You need at least one virtual terminal device in order to make use
of your keyboard and monitor. Therefore, only people configuring an
embedded system would want to say N here in order to save some
memory; the only way to log into such a system is then via a serial
or network connection.
If unsure, say Y, or else you won't be able to do much with your new
shiny Linux system :-)
config VT_CONSOLE
bool
default y
---help---
The system console is the device which receives all kernel messages
and warnings and which allows logins in single user mode. If you
answer Y here, a virtual terminal (the device used to interact with
a physical terminal) can be used as system console. This is the most
common mode of operations, so you should say Y here unless you want
the kernel messages be output only to a serial port (in which case
you should say Y to "Console on serial port", below).
If you do say Y here, by default the currently visible virtual
terminal (/dev/tty0) will be used as system console. You can change
that with a kernel command line option such as "console=tty3" which
would use the third virtual terminal as system console. (Try "man
bootparam" or see the documentation of your boot loader (lilo or
loadlin) about how to pass options to the kernel at boot time.)
If unsure, say Y.
config HW_CONSOLE
bool
default y
config SMP
bool "Symmetric multi-processing support (does not work on sun4/sun4c)"
depends on BROKEN

View File

@ -457,7 +457,7 @@ void __init time_init(void)
sbus_time_init();
}
extern __inline__ unsigned long do_gettimeoffset(void)
static inline unsigned long do_gettimeoffset(void)
{
return (*master_l10_counter >> 10) & 0x1fffff;
}

View File

@ -260,7 +260,7 @@ static inline pte_t srmmu_pte_modify(pte_t pte, pgprot_t newprot)
{ return __pte((pte_val(pte) & SRMMU_CHG_MASK) | pgprot_val(newprot)); }
/* to find an entry in a top-level page table... */
extern inline pgd_t *srmmu_pgd_offset(struct mm_struct * mm, unsigned long address)
static inline pgd_t *srmmu_pgd_offset(struct mm_struct * mm, unsigned long address)
{ return mm->pgd + (address >> SRMMU_PGDIR_SHIFT); }
/* Find an entry in the second-level page table.. */

View File

@ -97,8 +97,8 @@ do_fpdis:
faddd %f0, %f2, %f4
fmuld %f0, %f2, %f6
ldxa [%g3] ASI_DMMU, %g5
cplus_fptrap_insn_1:
sethi %hi(0), %g2
sethi %hi(sparc64_kern_sec_context), %g2
ldx [%g2 + %lo(sparc64_kern_sec_context)], %g2
stxa %g2, [%g3] ASI_DMMU
membar #Sync
add %g6, TI_FPREGS + 0xc0, %g2
@ -126,8 +126,8 @@ cplus_fptrap_insn_1:
fzero %f34
ldxa [%g3] ASI_DMMU, %g5
add %g6, TI_FPREGS, %g1
cplus_fptrap_insn_2:
sethi %hi(0), %g2
sethi %hi(sparc64_kern_sec_context), %g2
ldx [%g2 + %lo(sparc64_kern_sec_context)], %g2
stxa %g2, [%g3] ASI_DMMU
membar #Sync
add %g6, TI_FPREGS + 0x40, %g2
@ -153,8 +153,8 @@ cplus_fptrap_insn_2:
3: mov SECONDARY_CONTEXT, %g3
add %g6, TI_FPREGS, %g1
ldxa [%g3] ASI_DMMU, %g5
cplus_fptrap_insn_3:
sethi %hi(0), %g2
sethi %hi(sparc64_kern_sec_context), %g2
ldx [%g2 + %lo(sparc64_kern_sec_context)], %g2
stxa %g2, [%g3] ASI_DMMU
membar #Sync
mov 0x40, %g2
@ -319,8 +319,8 @@ do_fptrap_after_fsr:
stx %g3, [%g6 + TI_GSR]
mov SECONDARY_CONTEXT, %g3
ldxa [%g3] ASI_DMMU, %g5
cplus_fptrap_insn_4:
sethi %hi(0), %g2
sethi %hi(sparc64_kern_sec_context), %g2
ldx [%g2 + %lo(sparc64_kern_sec_context)], %g2
stxa %g2, [%g3] ASI_DMMU
membar #Sync
add %g6, TI_FPREGS, %g2
@ -341,33 +341,6 @@ cplus_fptrap_insn_4:
ba,pt %xcc, etrap
wr %g0, 0, %fprs
cplus_fptrap_1:
sethi %hi(CTX_CHEETAH_PLUS_CTX0), %g2
.globl cheetah_plus_patch_fpdis
cheetah_plus_patch_fpdis:
/* We configure the dTLB512_0 for 4MB pages and the
* dTLB512_1 for 8K pages when in context zero.
*/
sethi %hi(cplus_fptrap_1), %o0
lduw [%o0 + %lo(cplus_fptrap_1)], %o1
set cplus_fptrap_insn_1, %o2
stw %o1, [%o2]
flush %o2
set cplus_fptrap_insn_2, %o2
stw %o1, [%o2]
flush %o2
set cplus_fptrap_insn_3, %o2
stw %o1, [%o2]
flush %o2
set cplus_fptrap_insn_4, %o2
stw %o1, [%o2]
flush %o2
retl
nop
/* The registers for cross calls will be:
*
* DATA 0: [low 32-bits] Address of function to call, jmp to this

View File

@ -68,12 +68,8 @@ etrap_irq:
wrpr %g3, 0, %otherwin
wrpr %g2, 0, %wstate
cplus_etrap_insn_1:
sethi %hi(0), %g3
sllx %g3, 32, %g3
cplus_etrap_insn_2:
sethi %hi(0), %g2
or %g3, %g2, %g3
sethi %hi(sparc64_kern_pri_context), %g2
ldx [%g2 + %lo(sparc64_kern_pri_context)], %g3
stxa %g3, [%l4] ASI_DMMU
flush %l6
wr %g0, ASI_AIUS, %asi
@ -215,12 +211,8 @@ scetrap: rdpr %pil, %g2
mov PRIMARY_CONTEXT, %l4
wrpr %g3, 0, %otherwin
wrpr %g2, 0, %wstate
cplus_etrap_insn_3:
sethi %hi(0), %g3
sllx %g3, 32, %g3
cplus_etrap_insn_4:
sethi %hi(0), %g2
or %g3, %g2, %g3
sethi %hi(sparc64_kern_pri_context), %g2
ldx [%g2 + %lo(sparc64_kern_pri_context)], %g3
stxa %g3, [%l4] ASI_DMMU
flush %l6
@ -264,38 +256,3 @@ cplus_etrap_insn_4:
#undef TASK_REGOFF
#undef ETRAP_PSTATE1
cplus_einsn_1:
sethi %uhi(CTX_CHEETAH_PLUS_NUC), %g3
cplus_einsn_2:
sethi %hi(CTX_CHEETAH_PLUS_CTX0), %g2
.globl cheetah_plus_patch_etrap
cheetah_plus_patch_etrap:
/* We configure the dTLB512_0 for 4MB pages and the
* dTLB512_1 for 8K pages when in context zero.
*/
sethi %hi(cplus_einsn_1), %o0
sethi %hi(cplus_etrap_insn_1), %o2
lduw [%o0 + %lo(cplus_einsn_1)], %o1
or %o2, %lo(cplus_etrap_insn_1), %o2
stw %o1, [%o2]
flush %o2
sethi %hi(cplus_etrap_insn_3), %o2
or %o2, %lo(cplus_etrap_insn_3), %o2
stw %o1, [%o2]
flush %o2
sethi %hi(cplus_einsn_2), %o0
sethi %hi(cplus_etrap_insn_2), %o2
lduw [%o0 + %lo(cplus_einsn_2)], %o1
or %o2, %lo(cplus_etrap_insn_2), %o2
stw %o1, [%o2]
flush %o2
sethi %hi(cplus_etrap_insn_4), %o2
or %o2, %lo(cplus_etrap_insn_4), %o2
stw %o1, [%o2]
flush %o2
retl
nop

View File

@ -325,23 +325,7 @@ cheetah_tlb_fixup:
1: sethi %hi(tlb_type), %g1
stw %g2, [%g1 + %lo(tlb_type)]
BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g7,1f)
ba,pt %xcc, 2f
nop
1: /* Patch context register writes to support nucleus page
* size correctly.
*/
call cheetah_plus_patch_etrap
nop
call cheetah_plus_patch_rtrap
nop
call cheetah_plus_patch_fpdis
nop
call cheetah_plus_patch_winfixup
nop
2: /* Patch copy/page operations to cheetah optimized versions. */
/* Patch copy/page operations to cheetah optimized versions. */
call cheetah_patch_copyops
nop
call cheetah_patch_copy_page
@ -484,20 +468,13 @@ spitfire_vpte_base:
call prom_set_trap_table
sethi %hi(sparc64_ttable_tl0), %o0
BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g2,g3,1f)
ba,pt %xcc, 2f
nop
1: /* Start using proper page size encodings in ctx register. */
sethi %uhi(CTX_CHEETAH_PLUS_NUC), %g3
/* Start using proper page size encodings in ctx register. */
sethi %hi(sparc64_kern_pri_context), %g3
ldx [%g3 + %lo(sparc64_kern_pri_context)], %g2
mov PRIMARY_CONTEXT, %g1
sllx %g3, 32, %g3
sethi %hi(CTX_CHEETAH_PLUS_CTX0), %g2
or %g3, %g2, %g3
stxa %g3, [%g1] ASI_DMMU
stxa %g2, [%g1] ASI_DMMU
membar #Sync
2:
rdpr %pstate, %o1
or %o1, PSTATE_IE, %o1
wrpr %o1, 0, %pstate

View File

@ -256,9 +256,8 @@ rt_continue: ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1
brnz,pn %l3, kern_rtt
mov PRIMARY_CONTEXT, %l7
ldxa [%l7 + %l7] ASI_DMMU, %l0
cplus_rtrap_insn_1:
sethi %hi(0), %l1
sllx %l1, 32, %l1
sethi %hi(sparc64_kern_pri_nuc_bits), %l1
ldx [%l1 + %lo(sparc64_kern_pri_nuc_bits)], %l1
or %l0, %l1, %l0
stxa %l0, [%l7] ASI_DMMU
flush %g6
@ -345,21 +344,3 @@ kern_fpucheck: ldub [%g6 + TI_FPDEPTH], %l5
wr %g0, FPRS_DU, %fprs
ba,pt %xcc, rt_continue
stb %l5, [%g6 + TI_FPDEPTH]
cplus_rinsn_1:
sethi %uhi(CTX_CHEETAH_PLUS_NUC), %l1
.globl cheetah_plus_patch_rtrap
cheetah_plus_patch_rtrap:
/* We configure the dTLB512_0 for 4MB pages and the
* dTLB512_1 for 8K pages when in context zero.
*/
sethi %hi(cplus_rinsn_1), %o0
sethi %hi(cplus_rtrap_insn_1), %o2
lduw [%o0 + %lo(cplus_rinsn_1)], %o1
or %o2, %lo(cplus_rtrap_insn_1), %o2
stw %o1, [%o2]
flush %o2
retl
nop

View File

@ -187,17 +187,13 @@ int prom_callback(long *args)
}
if ((va >= KERNBASE) && (va < (KERNBASE + (4 * 1024 * 1024)))) {
unsigned long kernel_pctx = 0;
if (tlb_type == cheetah_plus)
kernel_pctx |= (CTX_CHEETAH_PLUS_NUC |
CTX_CHEETAH_PLUS_CTX0);
extern unsigned long sparc64_kern_pri_context;
/* Spitfire Errata #32 workaround */
__asm__ __volatile__("stxa %0, [%1] %2\n\t"
"flush %%g6"
: /* No outputs */
: "r" (kernel_pctx),
: "r" (sparc64_kern_pri_context),
"r" (PRIMARY_CONTEXT),
"i" (ASI_DMMU));

View File

@ -336,20 +336,13 @@ do_unlock:
call init_irqwork_curcpu
nop
BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g2,g3,1f)
ba,pt %xcc, 2f
nop
1: /* Start using proper page size encodings in ctx register. */
sethi %uhi(CTX_CHEETAH_PLUS_NUC), %g3
/* Start using proper page size encodings in ctx register. */
sethi %hi(sparc64_kern_pri_context), %g3
ldx [%g3 + %lo(sparc64_kern_pri_context)], %g2
mov PRIMARY_CONTEXT, %g1
sllx %g3, 32, %g3
sethi %hi(CTX_CHEETAH_PLUS_CTX0), %g2
or %g3, %g2, %g3
stxa %g3, [%g1] ASI_DMMU
stxa %g2, [%g1] ASI_DMMU
membar #Sync
2:
rdpr %pstate, %o1
or %o1, PSTATE_IE, %o1
wrpr %o1, 0, %pstate

View File

@ -16,23 +16,14 @@
.text
set_pcontext:
cplus_winfixup_insn_1:
sethi %hi(0), %l1
sethi %hi(sparc64_kern_pri_context), %l1
ldx [%l1 + %lo(sparc64_kern_pri_context)], %l1
mov PRIMARY_CONTEXT, %g1
sllx %l1, 32, %l1
cplus_winfixup_insn_2:
sethi %hi(0), %g2
or %l1, %g2, %l1
stxa %l1, [%g1] ASI_DMMU
flush %g6
retl
nop
cplus_wfinsn_1:
sethi %uhi(CTX_CHEETAH_PLUS_NUC), %l1
cplus_wfinsn_2:
sethi %hi(CTX_CHEETAH_PLUS_CTX0), %g2
.align 32
/* Here are the rules, pay attention.
@ -395,23 +386,3 @@ window_dax_from_user_common:
add %sp, PTREGS_OFF, %o0
ba,pt %xcc, rtrap
clr %l6
.globl cheetah_plus_patch_winfixup
cheetah_plus_patch_winfixup:
sethi %hi(cplus_wfinsn_1), %o0
sethi %hi(cplus_winfixup_insn_1), %o2
lduw [%o0 + %lo(cplus_wfinsn_1)], %o1
or %o2, %lo(cplus_winfixup_insn_1), %o2
stw %o1, [%o2]
flush %o2
sethi %hi(cplus_wfinsn_2), %o0
sethi %hi(cplus_winfixup_insn_2), %o2
lduw [%o0 + %lo(cplus_wfinsn_2)], %o1
or %o2, %lo(cplus_winfixup_insn_2), %o2
stw %o1, [%o2]
flush %o2
retl
nop

View File

@ -133,6 +133,12 @@ extern unsigned int sparc_ramdisk_size;
struct page *mem_map_zero __read_mostly;
unsigned int sparc64_highest_unlocked_tlb_ent __read_mostly;
unsigned long sparc64_kern_pri_context __read_mostly;
unsigned long sparc64_kern_pri_nuc_bits __read_mostly;
unsigned long sparc64_kern_sec_context __read_mostly;
int bigkernel = 0;
/* XXX Tune this... */
@ -362,6 +368,7 @@ struct linux_prom_translation {
unsigned long data;
};
static struct linux_prom_translation prom_trans[512] __initdata;
static unsigned int prom_trans_ents __initdata;
extern unsigned long prom_boot_page;
extern void prom_remap(unsigned long physpage, unsigned long virtpage, int mmu_ihandle);
@ -375,57 +382,7 @@ unsigned long kern_locked_tte_data;
unsigned long prom_pmd_phys __read_mostly;
unsigned int swapper_pgd_zero __read_mostly;
/* Allocate power-of-2 aligned chunks from the end of the
* kernel image. Return physical address.
*/
static inline unsigned long early_alloc_phys(unsigned long size)
{
unsigned long base;
BUILD_BUG_ON(size & (size - 1));
kern_size = (kern_size + (size - 1)) & ~(size - 1);
base = kern_base + kern_size;
kern_size += size;
return base;
}
static inline unsigned long load_phys32(unsigned long pa)
{
unsigned long val;
__asm__ __volatile__("lduwa [%1] %2, %0"
: "=&r" (val)
: "r" (pa), "i" (ASI_PHYS_USE_EC));
return val;
}
static inline unsigned long load_phys64(unsigned long pa)
{
unsigned long val;
__asm__ __volatile__("ldxa [%1] %2, %0"
: "=&r" (val)
: "r" (pa), "i" (ASI_PHYS_USE_EC));
return val;
}
static inline void store_phys32(unsigned long pa, unsigned long val)
{
__asm__ __volatile__("stwa %0, [%1] %2"
: /* no outputs */
: "r" (val), "r" (pa), "i" (ASI_PHYS_USE_EC));
}
static inline void store_phys64(unsigned long pa, unsigned long val)
{
__asm__ __volatile__("stxa %0, [%1] %2"
: /* no outputs */
: "r" (val), "r" (pa), "i" (ASI_PHYS_USE_EC));
}
static pmd_t *prompmd __read_mostly;
#define BASE_PAGE_SIZE 8192
@ -435,34 +392,28 @@ static inline void store_phys64(unsigned long pa, unsigned long val)
*/
unsigned long prom_virt_to_phys(unsigned long promva, int *error)
{
unsigned long pmd_phys = (prom_pmd_phys +
((promva >> 23) & 0x7ff) * sizeof(pmd_t));
unsigned long pte_phys;
pmd_t pmd_ent;
pte_t pte_ent;
pmd_t *pmdp = prompmd + ((promva >> 23) & 0x7ff);
pte_t *ptep;
unsigned long base;
pmd_val(pmd_ent) = load_phys32(pmd_phys);
if (pmd_none(pmd_ent)) {
if (pmd_none(*pmdp)) {
if (error)
*error = 1;
return 0;
}
pte_phys = (unsigned long)pmd_val(pmd_ent) << 11UL;
pte_phys += ((promva >> 13) & 0x3ff) * sizeof(pte_t);
pte_val(pte_ent) = load_phys64(pte_phys);
if (!pte_present(pte_ent)) {
ptep = (pte_t *)__pmd_page(*pmdp) + ((promva >> 13) & 0x3ff);
if (!pte_present(*ptep)) {
if (error)
*error = 1;
return 0;
}
if (error) {
*error = 0;
return pte_val(pte_ent);
return pte_val(*ptep);
}
base = pte_val(pte_ent) & _PAGE_PADDR;
return (base + (promva & (BASE_PAGE_SIZE - 1)));
base = pte_val(*ptep) & _PAGE_PADDR;
return base + (promva & (BASE_PAGE_SIZE - 1));
}
/* The obp translations are saved based on 8k pagesize, since obp can
@ -475,25 +426,20 @@ static void __init build_obp_range(unsigned long start, unsigned long end, unsig
unsigned long vaddr;
for (vaddr = start; vaddr < end; vaddr += BASE_PAGE_SIZE) {
unsigned long val, pte_phys, pmd_phys;
pmd_t pmd_ent;
int i;
unsigned long val;
pmd_t *pmd;
pte_t *pte;
pmd_phys = (prom_pmd_phys +
(((vaddr >> 23) & 0x7ff) * sizeof(pmd_t)));
pmd_val(pmd_ent) = load_phys32(pmd_phys);
if (pmd_none(pmd_ent)) {
pte_phys = early_alloc_phys(BASE_PAGE_SIZE);
for (i = 0; i < BASE_PAGE_SIZE / sizeof(pte_t); i++)
store_phys64(pte_phys+i*sizeof(pte_t),0);
pmd_val(pmd_ent) = pte_phys >> 11UL;
store_phys32(pmd_phys, pmd_val(pmd_ent));
pmd = prompmd + ((vaddr >> 23) & 0x7ff);
if (pmd_none(*pmd)) {
pte = __alloc_bootmem(BASE_PAGE_SIZE, BASE_PAGE_SIZE,
PAGE_SIZE);
if (!pte)
prom_halt();
memset(pte, 0, BASE_PAGE_SIZE);
pmd_set(pmd, pte);
}
pte_phys = (unsigned long)pmd_val(pmd_ent) << 11UL;
pte_phys += (((vaddr >> 13) & 0x3ff) * sizeof(pte_t));
pte = (pte_t *) __pmd_page(*pmd) + ((vaddr >> 13) & 0x3ff);
val = data;
@ -501,7 +447,8 @@ static void __init build_obp_range(unsigned long start, unsigned long end, unsig
if (tlb_type == spitfire)
val &= ~0x0003fe0000000000UL;
store_phys64(pte_phys, val | _PAGE_MODIFIED);
set_pte_at(&init_mm, vaddr, pte,
__pte(val | _PAGE_MODIFIED));
data += BASE_PAGE_SIZE;
}
@ -514,13 +461,17 @@ static inline int in_obp_range(unsigned long vaddr)
}
#define OBP_PMD_SIZE 2048
static void __init build_obp_pgtable(int prom_trans_ents)
static void __init build_obp_pgtable(void)
{
unsigned long i;
prom_pmd_phys = early_alloc_phys(OBP_PMD_SIZE);
for (i = 0; i < OBP_PMD_SIZE; i += 4)
store_phys32(prom_pmd_phys + i, 0);
prompmd = __alloc_bootmem(OBP_PMD_SIZE, OBP_PMD_SIZE, PAGE_SIZE);
if (!prompmd)
prom_halt();
memset(prompmd, 0, OBP_PMD_SIZE);
prom_pmd_phys = __pa(prompmd);
for (i = 0; i < prom_trans_ents; i++) {
unsigned long start, end;
@ -540,7 +491,7 @@ static void __init build_obp_pgtable(int prom_trans_ents)
/* Read OBP translations property into 'prom_trans[]'.
* Return the number of entries.
*/
static int __init read_obp_translations(void)
static void __init read_obp_translations(void)
{
int n, node;
@ -561,8 +512,10 @@ static int __init read_obp_translations(void)
prom_printf("prom_mappings: Couldn't get property.\n");
prom_halt();
}
n = n / sizeof(struct linux_prom_translation);
return n;
prom_trans_ents = n;
}
static void __init remap_kernel(void)
@ -582,28 +535,38 @@ static void __init remap_kernel(void)
prom_dtlb_load(tlb_ent, tte_data, tte_vaddr);
prom_itlb_load(tlb_ent, tte_data, tte_vaddr);
if (bigkernel) {
prom_dtlb_load(tlb_ent - 1,
tlb_ent -= 1;
prom_dtlb_load(tlb_ent,
tte_data + 0x400000,
tte_vaddr + 0x400000);
prom_itlb_load(tlb_ent - 1,
prom_itlb_load(tlb_ent,
tte_data + 0x400000,
tte_vaddr + 0x400000);
}
sparc64_highest_unlocked_tlb_ent = tlb_ent - 1;
if (tlb_type == cheetah_plus) {
sparc64_kern_pri_context = (CTX_CHEETAH_PLUS_CTX0 |
CTX_CHEETAH_PLUS_NUC);
sparc64_kern_pri_nuc_bits = CTX_CHEETAH_PLUS_NUC;
sparc64_kern_sec_context = CTX_CHEETAH_PLUS_CTX0;
}
}
static void __init inherit_prom_mappings(void)
{
int n;
n = read_obp_translations();
build_obp_pgtable(n);
static void __init inherit_prom_mappings_pre(void)
{
read_obp_translations();
/* Now fixup OBP's idea about where we really are mapped. */
prom_printf("Remapping the kernel... ");
remap_kernel();
prom_printf("done.\n");
}
static void __init inherit_prom_mappings_post(void)
{
build_obp_pgtable();
register_prom_callbacks();
}
@ -788,8 +751,8 @@ void inherit_locked_prom_mappings(int save_p)
}
}
if (tlb_type == spitfire) {
int high = SPITFIRE_HIGHEST_LOCKED_TLBENT - bigkernel;
for (i = 0; i < high; i++) {
int high = sparc64_highest_unlocked_tlb_ent;
for (i = 0; i <= high; i++) {
unsigned long data;
/* Spitfire Errata #32 workaround */
@ -877,9 +840,9 @@ void inherit_locked_prom_mappings(int save_p)
}
}
} else if (tlb_type == cheetah || tlb_type == cheetah_plus) {
int high = CHEETAH_HIGHEST_LOCKED_TLBENT - bigkernel;
int high = sparc64_highest_unlocked_tlb_ent;
for (i = 0; i < high; i++) {
for (i = 0; i <= high; i++) {
unsigned long data;
data = cheetah_get_ldtlb_data(i);
@ -1556,8 +1519,7 @@ void __init paging_init(void)
swapper_pgd_zero = pgd_val(swapper_pg_dir[0]);
/* Inherit non-locked OBP mappings. */
inherit_prom_mappings();
inherit_prom_mappings_pre();
/* Ok, we can use our TLB miss and window trap handlers safely.
* We need to do a quick peek here to see if we are on StarFire
@ -1568,15 +1530,23 @@ void __init paging_init(void)
extern void setup_tba(int);
setup_tba(this_is_starfire);
}
inherit_locked_prom_mappings(1);
__flush_tlb_all();
/* Everything from this point forward, until we are done with
* inherit_prom_mappings_post(), must complete successfully
* without calling into the firmware. The firwmare page tables
* have not been built, but we are running on the Linux kernel's
* trap table.
*/
/* Setup bootmem... */
pages_avail = 0;
last_valid_pfn = end_pfn = bootmem_init(&pages_avail);
inherit_prom_mappings_post();
inherit_locked_prom_mappings(1);
#ifdef CONFIG_DEBUG_PAGEALLOC
kernel_physical_mapping_init();
#endif

View File

@ -15,16 +15,6 @@ extern void save_registers(int pid, union uml_pt_regs *regs);
extern void restore_registers(int pid, union uml_pt_regs *regs);
extern void init_registers(int pid);
extern void get_safe_registers(unsigned long * regs);
extern void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer);
#endif
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-file-style: "linux"
* End:
*/

View File

@ -218,10 +218,6 @@ struct syscall_args {
case RBP: UPT_RBP(regs) = __upt_val; break; \
case ORIG_RAX: UPT_ORIG_RAX(regs) = __upt_val; break; \
case CS: UPT_CS(regs) = __upt_val; break; \
case DS: UPT_DS(regs) = __upt_val; break; \
case ES: UPT_ES(regs) = __upt_val; break; \
case FS: UPT_FS(regs) = __upt_val; break; \
case GS: UPT_GS(regs) = __upt_val; break; \
case EFLAGS: UPT_EFLAGS(regs) = __upt_val; break; \
default : \
panic("Bad register in UPT_SET : %d\n", reg); \

View File

@ -62,13 +62,7 @@ void show_stack(struct task_struct *task, unsigned long *esp)
if (esp == NULL) {
if (task != current && task != NULL) {
/* XXX: Isn't this bogus? I.e. isn't this the
* *userspace* stack of this task? If not so, use this
* even when task == current (as in i386).
*/
esp = (unsigned long *) KSTK_ESP(task);
/* Which one? No actual difference - just coding style.*/
//esp = (unsigned long *) PT_REGS_IP(&task->thread.regs);
} else {
esp = (unsigned long *) &esp;
}
@ -84,5 +78,5 @@ void show_stack(struct task_struct *task, unsigned long *esp)
}
printk("Call Trace: \n");
show_trace(current, esp);
show_trace(task, esp);
}

View File

@ -5,6 +5,7 @@
#include <errno.h>
#include <string.h>
#include <setjmp.h>
#include "sysdep/ptrace_user.h"
#include "sysdep/ptrace.h"
#include "uml-config.h"
@ -126,13 +127,11 @@ void get_safe_registers(unsigned long *regs)
memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long));
}
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-file-style: "linux"
* End:
*/
void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer)
{
struct __jmp_buf_tag *jmpbuf = buffer;
UPT_SET(uml_regs, EIP, jmpbuf->__jmpbuf[JB_PC]);
UPT_SET(uml_regs, UESP, jmpbuf->__jmpbuf[JB_SP]);
UPT_SET(uml_regs, EBP, jmpbuf->__jmpbuf[JB_BP]);
}

View File

@ -5,6 +5,7 @@
#include <errno.h>
#include <string.h>
#include <setjmp.h>
#include "ptrace_user.h"
#include "uml-config.h"
#include "skas_ptregs.h"
@ -74,13 +75,11 @@ void get_safe_registers(unsigned long *regs)
memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long));
}
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-file-style: "linux"
* End:
*/
void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer)
{
struct __jmp_buf_tag *jmpbuf = buffer;
UPT_SET(uml_regs, RIP, jmpbuf->__jmpbuf[JB_PC]);
UPT_SET(uml_regs, RSP, jmpbuf->__jmpbuf[JB_RSP]);
UPT_SET(uml_regs, RBP, jmpbuf->__jmpbuf[JB_RBP]);
}

View File

@ -88,9 +88,7 @@ void show_trace(struct task_struct* task, unsigned long * stack)
task = current;
if (task != current) {
//ebp = (unsigned long) KSTK_EBP(task);
/* Which one? No actual difference - just coding style.*/
ebp = (unsigned long) PT_REGS_EBP(&task->thread.regs);
ebp = (unsigned long) KSTK_EBP(task);
} else {
asm ("movl %%ebp, %0" : "=r" (ebp) : );
}
@ -99,15 +97,6 @@ void show_trace(struct task_struct* task, unsigned long * stack)
((unsigned long)stack & (~(THREAD_SIZE - 1)));
print_context_stack(context, stack, ebp);
/*while (((long) stack & (THREAD_SIZE-1)) != 0) {
addr = *stack;
if (__kernel_text_address(addr)) {
printk("%08lx: [<%08lx>]", (unsigned long) stack, addr);
print_symbol(" %s", addr);
printk("\n");
}
stack++;
}*/
printk("\n");
}

View File

@ -46,7 +46,7 @@ void foo(void)
OFFSET(HOST_SC_FP_ST, _fpstate, _st);
OFFSET(HOST_SC_FXSR_ENV, _fpstate, _fxsr_env);
DEFINE_LONGS(HOST_FRAME_SIZE, FRAME_SIZE);
DEFINE(HOST_FRAME_SIZE, FRAME_SIZE);
DEFINE_LONGS(HOST_FP_SIZE, sizeof(struct user_i387_struct));
DEFINE_LONGS(HOST_XFP_SIZE, sizeof(struct user_fxsr_struct));

View File

@ -270,26 +270,26 @@ ENTRY(level3_kernel_pgt)
.org 0x4000
ENTRY(level2_ident_pgt)
/* 40MB for bootup. */
.quad 0x0000000000000183
.quad 0x0000000000200183
.quad 0x0000000000400183
.quad 0x0000000000600183
.quad 0x0000000000800183
.quad 0x0000000000A00183
.quad 0x0000000000C00183
.quad 0x0000000000E00183
.quad 0x0000000001000183
.quad 0x0000000001200183
.quad 0x0000000001400183
.quad 0x0000000001600183
.quad 0x0000000001800183
.quad 0x0000000001A00183
.quad 0x0000000001C00183
.quad 0x0000000001E00183
.quad 0x0000000002000183
.quad 0x0000000002200183
.quad 0x0000000002400183
.quad 0x0000000002600183
.quad 0x0000000000000083
.quad 0x0000000000200083
.quad 0x0000000000400083
.quad 0x0000000000600083
.quad 0x0000000000800083
.quad 0x0000000000A00083
.quad 0x0000000000C00083
.quad 0x0000000000E00083
.quad 0x0000000001000083
.quad 0x0000000001200083
.quad 0x0000000001400083
.quad 0x0000000001600083
.quad 0x0000000001800083
.quad 0x0000000001A00083
.quad 0x0000000001C00083
.quad 0x0000000001E00083
.quad 0x0000000002000083
.quad 0x0000000002200083
.quad 0x0000000002400083
.quad 0x0000000002600083
/* Temporary mappings for the super early allocator in arch/x86_64/mm/init.c */
.globl temp_boot_pmds
temp_boot_pmds:

View File

@ -178,14 +178,12 @@ fore200e_irq_itoa(int irq)
static void*
fore200e_kmalloc(int size, int flags)
fore200e_kmalloc(int size, unsigned int __nocast flags)
{
void* chunk = kmalloc(size, flags);
void *chunk = kzalloc(size, flags);
if (chunk)
memset(chunk, 0x00, size);
else
printk(FORE200E "kmalloc() failed, requested size = %d, flags = 0x%x\n", size, flags);
if (!chunk)
printk(FORE200E "kmalloc() failed, requested size = %d, flags = 0x%x\n", size, flags);
return chunk;
}

View File

@ -47,7 +47,7 @@ MODULE_PARM_DESC(cards_limit, "Maximum number of graphics cards");
MODULE_PARM_DESC(debug, "Enable debug output");
module_param_named(cards_limit, drm_cards_limit, int, 0444);
module_param_named(debug, drm_debug, int, 0666);
module_param_named(debug, drm_debug, int, 0600);
drm_head_t **drm_heads;
struct drm_sysfs_class *drm_class;

View File

@ -69,7 +69,8 @@ int cn_already_initialized = 0;
* a new message.
*
*/
int cn_netlink_send(struct cn_msg *msg, u32 __group, int gfp_mask)
int cn_netlink_send(struct cn_msg *msg, u32 __group,
unsigned int __nocast gfp_mask)
{
struct cn_callback_entry *__cbq;
unsigned int size;

View File

@ -503,6 +503,25 @@ err_free_aux:
return err;
}
static void mthca_free_icms(struct mthca_dev *mdev)
{
u8 status;
mthca_free_icm_table(mdev, mdev->mcg_table.table);
if (mdev->mthca_flags & MTHCA_FLAG_SRQ)
mthca_free_icm_table(mdev, mdev->srq_table.table);
mthca_free_icm_table(mdev, mdev->cq_table.table);
mthca_free_icm_table(mdev, mdev->qp_table.rdb_table);
mthca_free_icm_table(mdev, mdev->qp_table.eqp_table);
mthca_free_icm_table(mdev, mdev->qp_table.qp_table);
mthca_free_icm_table(mdev, mdev->mr_table.mpt_table);
mthca_free_icm_table(mdev, mdev->mr_table.mtt_table);
mthca_unmap_eq_icm(mdev);
mthca_UNMAP_ICM_AUX(mdev, &status);
mthca_free_icm(mdev, mdev->fw.arbel.aux_icm);
}
static int __devinit mthca_init_arbel(struct mthca_dev *mdev)
{
struct mthca_dev_lim dev_lim;
@ -580,18 +599,7 @@ static int __devinit mthca_init_arbel(struct mthca_dev *mdev)
return 0;
err_free_icm:
if (mdev->mthca_flags & MTHCA_FLAG_SRQ)
mthca_free_icm_table(mdev, mdev->srq_table.table);
mthca_free_icm_table(mdev, mdev->cq_table.table);
mthca_free_icm_table(mdev, mdev->qp_table.rdb_table);
mthca_free_icm_table(mdev, mdev->qp_table.eqp_table);
mthca_free_icm_table(mdev, mdev->qp_table.qp_table);
mthca_free_icm_table(mdev, mdev->mr_table.mpt_table);
mthca_free_icm_table(mdev, mdev->mr_table.mtt_table);
mthca_unmap_eq_icm(mdev);
mthca_UNMAP_ICM_AUX(mdev, &status);
mthca_free_icm(mdev, mdev->fw.arbel.aux_icm);
mthca_free_icms(mdev);
err_stop_fw:
mthca_UNMAP_FA(mdev, &status);
@ -611,18 +619,7 @@ static void mthca_close_hca(struct mthca_dev *mdev)
mthca_CLOSE_HCA(mdev, 0, &status);
if (mthca_is_memfree(mdev)) {
if (mdev->mthca_flags & MTHCA_FLAG_SRQ)
mthca_free_icm_table(mdev, mdev->srq_table.table);
mthca_free_icm_table(mdev, mdev->cq_table.table);
mthca_free_icm_table(mdev, mdev->qp_table.rdb_table);
mthca_free_icm_table(mdev, mdev->qp_table.eqp_table);
mthca_free_icm_table(mdev, mdev->qp_table.qp_table);
mthca_free_icm_table(mdev, mdev->mr_table.mpt_table);
mthca_free_icm_table(mdev, mdev->mr_table.mtt_table);
mthca_unmap_eq_icm(mdev);
mthca_UNMAP_ICM_AUX(mdev, &status);
mthca_free_icm(mdev, mdev->fw.arbel.aux_icm);
mthca_free_icms(mdev);
mthca_UNMAP_FA(mdev, &status);
mthca_free_icm(mdev, mdev->fw.arbel.fw_icm);

View File

@ -474,7 +474,7 @@ err:
spin_unlock(&priv->lock);
}
static void path_lookup(struct sk_buff *skb, struct net_device *dev)
static void ipoib_path_lookup(struct sk_buff *skb, struct net_device *dev)
{
struct ipoib_dev_priv *priv = netdev_priv(skb->dev);
@ -569,7 +569,7 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (skb->dst && skb->dst->neighbour) {
if (unlikely(!*to_ipoib_neigh(skb->dst->neighbour))) {
path_lookup(skb, dev);
ipoib_path_lookup(skb, dev);
goto out;
}

View File

@ -642,8 +642,6 @@ static void __exit ucb1x00_exit(void)
module_init(ucb1x00_init);
module_exit(ucb1x00_exit);
EXPORT_SYMBOL(ucb1x00_class);
EXPORT_SYMBOL(ucb1x00_io_set_dir);
EXPORT_SYMBOL(ucb1x00_io_write);
EXPORT_SYMBOL(ucb1x00_io_read);

View File

@ -106,8 +106,6 @@ struct ucb1x00_irq {
void (*fn)(int, void *);
};
extern struct class ucb1x00_class;
struct ucb1x00 {
spinlock_t lock;
struct mcp *mcp;

View File

@ -1655,7 +1655,7 @@ config LAN_SAA9730
config NET_POCKET
bool "Pocket and portable adapters"
depends on NET_ETHERNET && ISA
depends on NET_ETHERNET && PARPORT
---help---
Cute little network (Ethernet) devices which attach to the parallel
port ("pocket adapters"), commonly used with laptops. If you have
@ -1679,7 +1679,7 @@ config NET_POCKET
config ATP
tristate "AT-LAN-TEC/RealTek pocket adapter support"
depends on NET_POCKET && ISA && X86
depends on NET_POCKET && PARPORT && X86
select CRC32
---help---
This is a network (Ethernet) device which attaches to your parallel
@ -1694,7 +1694,7 @@ config ATP
config DE600
tristate "D-Link DE600 pocket adapter support"
depends on NET_POCKET && ISA
depends on NET_POCKET && PARPORT
---help---
This is a network (Ethernet) device which attaches to your parallel
port. Read <file:Documentation/networking/DLINK.txt> as well as the
@ -1709,7 +1709,7 @@ config DE600
config DE620
tristate "D-Link DE620 pocket adapter support"
depends on NET_POCKET && ISA
depends on NET_POCKET && PARPORT
---help---
This is a network (Ethernet) device which attaches to your parallel
port. Read <file:Documentation/networking/DLINK.txt> as well as the

View File

@ -487,6 +487,8 @@
* * Added xmit_hash_policy_layer34()
* - Modified by Jay Vosburgh <fubar@us.ibm.com> to also support mode 4.
* Set version to 2.6.3.
* 2005/09/26 - Jay Vosburgh <fubar@us.ibm.com>
* - Removed backwards compatibility for old ifenslaves. Version 2.6.4.
*/
//#define BONDING_DEBUG 1
@ -595,14 +597,7 @@ static int arp_ip_count = 0;
static int bond_mode = BOND_MODE_ROUNDROBIN;
static int xmit_hashtype= BOND_XMIT_POLICY_LAYER2;
static int lacp_fast = 0;
static int app_abi_ver = 0;
static int orig_app_abi_ver = -1; /* This is used to save the first ABI version
* we receive from the application. Once set,
* it won't be changed, and the module will
* refuse to enslave/release interfaces if the
* command comes from an application using
* another ABI version.
*/
struct bond_parm_tbl {
char *modename;
int mode;
@ -1294,12 +1289,13 @@ static void bond_mc_list_destroy(struct bonding *bond)
/*
* Copy all the Multicast addresses from src to the bonding device dst
*/
static int bond_mc_list_copy(struct dev_mc_list *mc_list, struct bonding *bond, int gpf_flag)
static int bond_mc_list_copy(struct dev_mc_list *mc_list, struct bonding *bond,
unsigned int __nocast gfp_flag)
{
struct dev_mc_list *dmi, *new_dmi;
for (dmi = mc_list; dmi; dmi = dmi->next) {
new_dmi = kmalloc(sizeof(struct dev_mc_list), gpf_flag);
new_dmi = kmalloc(sizeof(struct dev_mc_list), gfp_flag);
if (!new_dmi) {
/* FIXME: Potential memory leak !!! */
@ -1702,51 +1698,29 @@ static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_de
}
}
if (app_abi_ver >= 1) {
/* The application is using an ABI, which requires the
* slave interface to be closed.
*/
if ((slave_dev->flags & IFF_UP)) {
printk(KERN_ERR DRV_NAME
": Error: %s is up\n",
slave_dev->name);
res = -EPERM;
goto err_undo_flags;
}
/*
* Old ifenslave binaries are no longer supported. These can
* be identified with moderate accurary by the state of the slave:
* the current ifenslave will set the interface down prior to
* enslaving it; the old ifenslave will not.
*/
if ((slave_dev->flags & IFF_UP)) {
printk(KERN_ERR DRV_NAME ": %s is up. "
"This may be due to an out of date ifenslave.\n",
slave_dev->name);
res = -EPERM;
goto err_undo_flags;
}
if (slave_dev->set_mac_address == NULL) {
printk(KERN_ERR DRV_NAME
": Error: The slave device you specified does "
"not support setting the MAC address.\n");
printk(KERN_ERR
"Your kernel likely does not support slave "
"devices.\n");
if (slave_dev->set_mac_address == NULL) {
printk(KERN_ERR DRV_NAME
": Error: The slave device you specified does "
"not support setting the MAC address.\n");
printk(KERN_ERR
"Your kernel likely does not support slave devices.\n");
res = -EOPNOTSUPP;
goto err_undo_flags;
}
} else {
/* The application is not using an ABI, which requires the
* slave interface to be open.
*/
if (!(slave_dev->flags & IFF_UP)) {
printk(KERN_ERR DRV_NAME
": Error: %s is not running\n",
slave_dev->name);
res = -EINVAL;
goto err_undo_flags;
}
if ((bond->params.mode == BOND_MODE_8023AD) ||
(bond->params.mode == BOND_MODE_TLB) ||
(bond->params.mode == BOND_MODE_ALB)) {
printk(KERN_ERR DRV_NAME
": Error: to use %s mode, you must upgrade "
"ifenslave.\n",
bond_mode_name(bond->params.mode));
res = -EOPNOTSUPP;
goto err_undo_flags;
}
res = -EOPNOTSUPP;
goto err_undo_flags;
}
new_slave = kmalloc(sizeof(struct slave), GFP_KERNEL);
@ -1762,41 +1736,36 @@ static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_de
*/
new_slave->original_flags = slave_dev->flags;
if (app_abi_ver >= 1) {
/* save slave's original ("permanent") mac address for
* modes that needs it, and for restoring it upon release,
* and then set it to the master's address
*/
memcpy(new_slave->perm_hwaddr, slave_dev->dev_addr, ETH_ALEN);
/*
* Save slave's original ("permanent") mac address for modes
* that need it, and for restoring it upon release, and then
* set it to the master's address
*/
memcpy(new_slave->perm_hwaddr, slave_dev->dev_addr, ETH_ALEN);
/* set slave to master's mac address
* The application already set the master's
* mac address to that of the first slave
*/
memcpy(addr.sa_data, bond_dev->dev_addr, bond_dev->addr_len);
addr.sa_family = slave_dev->type;
res = dev_set_mac_address(slave_dev, &addr);
if (res) {
dprintk("Error %d calling set_mac_address\n", res);
goto err_free;
}
/*
* Set slave to master's mac address. The application already
* set the master's mac address to that of the first slave
*/
memcpy(addr.sa_data, bond_dev->dev_addr, bond_dev->addr_len);
addr.sa_family = slave_dev->type;
res = dev_set_mac_address(slave_dev, &addr);
if (res) {
dprintk("Error %d calling set_mac_address\n", res);
goto err_free;
}
/* open the slave since the application closed it */
res = dev_open(slave_dev);
if (res) {
dprintk("Openning slave %s failed\n", slave_dev->name);
goto err_restore_mac;
}
/* open the slave since the application closed it */
res = dev_open(slave_dev);
if (res) {
dprintk("Openning slave %s failed\n", slave_dev->name);
goto err_restore_mac;
}
res = netdev_set_master(slave_dev, bond_dev);
if (res) {
dprintk("Error %d calling netdev_set_master\n", res);
if (app_abi_ver < 1) {
goto err_free;
} else {
goto err_close;
}
goto err_close;
}
new_slave->dev = slave_dev;
@ -1997,39 +1966,6 @@ static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_de
write_unlock_bh(&bond->lock);
if (app_abi_ver < 1) {
/*
* !!! This is to support old versions of ifenslave.
* We can remove this in 2.5 because our ifenslave takes
* care of this for us.
* We check to see if the master has a mac address yet.
* If not, we'll give it the mac address of our slave device.
*/
int ndx = 0;
for (ndx = 0; ndx < bond_dev->addr_len; ndx++) {
dprintk("Checking ndx=%d of bond_dev->dev_addr\n",
ndx);
if (bond_dev->dev_addr[ndx] != 0) {
dprintk("Found non-zero byte at ndx=%d\n",
ndx);
break;
}
}
if (ndx == bond_dev->addr_len) {
/*
* We got all the way through the address and it was
* all 0's.
*/
dprintk("%s doesn't have a MAC address yet. \n",
bond_dev->name);
dprintk("Going to give assign it from %s.\n",
slave_dev->name);
bond_sethwaddr(bond_dev, slave_dev);
}
}
printk(KERN_INFO DRV_NAME
": %s: enslaving %s as a%s interface with a%s link.\n",
bond_dev->name, slave_dev->name,
@ -2227,12 +2163,10 @@ static int bond_release(struct net_device *bond_dev, struct net_device *slave_de
/* close slave before restoring its mac address */
dev_close(slave_dev);
if (app_abi_ver >= 1) {
/* restore original ("permanent") mac address */
memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN);
addr.sa_family = slave_dev->type;
dev_set_mac_address(slave_dev, &addr);
}
/* restore original ("permanent") mac address */
memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN);
addr.sa_family = slave_dev->type;
dev_set_mac_address(slave_dev, &addr);
/* restore the original state of the
* IFF_NOARP flag that might have been
@ -2320,12 +2254,10 @@ static int bond_release_all(struct net_device *bond_dev)
/* close slave before restoring its mac address */
dev_close(slave_dev);
if (app_abi_ver >= 1) {
/* restore original ("permanent") mac address*/
memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN);
addr.sa_family = slave_dev->type;
dev_set_mac_address(slave_dev, &addr);
}
/* restore original ("permanent") mac address*/
memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN);
addr.sa_family = slave_dev->type;
dev_set_mac_address(slave_dev, &addr);
/* restore the original state of the IFF_NOARP flag that might have
* been set by bond_set_slave_inactive_flags()
@ -2423,57 +2355,6 @@ static int bond_ioctl_change_active(struct net_device *bond_dev, struct net_devi
return res;
}
static int bond_ethtool_ioctl(struct net_device *bond_dev, struct ifreq *ifr)
{
struct ethtool_drvinfo info;
void __user *addr = ifr->ifr_data;
uint32_t cmd;
if (get_user(cmd, (uint32_t __user *)addr)) {
return -EFAULT;
}
switch (cmd) {
case ETHTOOL_GDRVINFO:
if (copy_from_user(&info, addr, sizeof(info))) {
return -EFAULT;
}
if (strcmp(info.driver, "ifenslave") == 0) {
int new_abi_ver;
char *endptr;
new_abi_ver = simple_strtoul(info.fw_version,
&endptr, 0);
if (*endptr) {
printk(KERN_ERR DRV_NAME
": Error: got invalid ABI "
"version from application\n");
return -EINVAL;
}
if (orig_app_abi_ver == -1) {
orig_app_abi_ver = new_abi_ver;
}
app_abi_ver = new_abi_ver;
}
strncpy(info.driver, DRV_NAME, 32);
strncpy(info.version, DRV_VERSION, 32);
snprintf(info.fw_version, 32, "%d", BOND_ABI_VERSION);
if (copy_to_user(addr, &info, sizeof(info))) {
return -EFAULT;
}
return 0;
default:
return -EOPNOTSUPP;
}
}
static int bond_info_query(struct net_device *bond_dev, struct ifbond *info)
{
struct bonding *bond = bond_dev->priv;
@ -3442,16 +3323,11 @@ static void bond_info_show_slave(struct seq_file *seq, const struct slave *slave
seq_printf(seq, "Link Failure Count: %d\n",
slave->link_failure_count);
if (app_abi_ver >= 1) {
seq_printf(seq,
"Permanent HW addr: %02x:%02x:%02x:%02x:%02x:%02x\n",
slave->perm_hwaddr[0],
slave->perm_hwaddr[1],
slave->perm_hwaddr[2],
slave->perm_hwaddr[3],
slave->perm_hwaddr[4],
slave->perm_hwaddr[5]);
}
seq_printf(seq,
"Permanent HW addr: %02x:%02x:%02x:%02x:%02x:%02x\n",
slave->perm_hwaddr[0], slave->perm_hwaddr[1],
slave->perm_hwaddr[2], slave->perm_hwaddr[3],
slave->perm_hwaddr[4], slave->perm_hwaddr[5]);
if (bond->params.mode == BOND_MODE_8023AD) {
const struct aggregator *agg
@ -4010,15 +3886,12 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
struct ifslave k_sinfo;
struct ifslave __user *u_sinfo = NULL;
struct mii_ioctl_data *mii = NULL;
int prev_abi_ver = orig_app_abi_ver;
int res = 0;
dprintk("bond_ioctl: master=%s, cmd=%d\n",
bond_dev->name, cmd);
switch (cmd) {
case SIOCETHTOOL:
return bond_ethtool_ioctl(bond_dev, ifr);
case SIOCGMIIPHY:
mii = if_mii(ifr);
if (!mii) {
@ -4090,21 +3963,6 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
return -EPERM;
}
if (orig_app_abi_ver == -1) {
/* no orig_app_abi_ver was provided yet, so we'll use the
* current one from now on, even if it's 0
*/
orig_app_abi_ver = app_abi_ver;
} else if (orig_app_abi_ver != app_abi_ver) {
printk(KERN_ERR DRV_NAME
": Error: already using ifenslave ABI version %d; to "
"upgrade ifenslave to version %d, you must first "
"reload bonding.\n",
orig_app_abi_ver, app_abi_ver);
return -EINVAL;
}
slave_dev = dev_get_by_name(ifr->ifr_slave);
dprintk("slave_dev=%p: \n", slave_dev);
@ -4137,14 +3995,6 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
dev_put(slave_dev);
}
if (res < 0) {
/* The ioctl failed, so there's no point in changing the
* orig_app_abi_ver. We'll restore it's value just in case
* we've changed it earlier in this function.
*/
orig_app_abi_ver = prev_abi_ver;
}
return res;
}
@ -4578,9 +4428,18 @@ static inline void bond_set_mode_ops(struct bonding *bond, int mode)
}
}
static void bond_ethtool_get_drvinfo(struct net_device *bond_dev,
struct ethtool_drvinfo *drvinfo)
{
strncpy(drvinfo->driver, DRV_NAME, 32);
strncpy(drvinfo->version, DRV_VERSION, 32);
snprintf(drvinfo->fw_version, 32, "%d", BOND_ABI_VERSION);
}
static struct ethtool_ops bond_ethtool_ops = {
.get_tx_csum = ethtool_op_get_tx_csum,
.get_sg = ethtool_op_get_sg,
.get_drvinfo = bond_ethtool_get_drvinfo,
};
/*

View File

@ -40,8 +40,8 @@
#include "bond_3ad.h"
#include "bond_alb.h"
#define DRV_VERSION "2.6.3"
#define DRV_RELDATE "June 8, 2005"
#define DRV_VERSION "2.6.4"
#define DRV_RELDATE "September 26, 2005"
#define DRV_NAME "bonding"
#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"

View File

@ -1875,6 +1875,9 @@ static int emac_init_device(struct ocp_device *ocpdev, struct ibm_ocp_mal *mal)
rc = -ENODEV;
goto bail;
}
/* Disable any PHY features not supported by the platform */
ep->phy_mii.def->features &= ~emacdata->phy_feat_exc;
/* Setup initial PHY config & startup aneg */
if (ep->phy_mii.def->ops->init)
@ -1882,6 +1885,34 @@ static int emac_init_device(struct ocp_device *ocpdev, struct ibm_ocp_mal *mal)
netif_carrier_off(ndev);
if (ep->phy_mii.def->features & SUPPORTED_Autoneg)
ep->want_autoneg = 1;
else {
ep->want_autoneg = 0;
/* Select highest supported speed/duplex */
if (ep->phy_mii.def->features & SUPPORTED_1000baseT_Full) {
ep->phy_mii.speed = SPEED_1000;
ep->phy_mii.duplex = DUPLEX_FULL;
} else if (ep->phy_mii.def->features &
SUPPORTED_1000baseT_Half) {
ep->phy_mii.speed = SPEED_1000;
ep->phy_mii.duplex = DUPLEX_HALF;
} else if (ep->phy_mii.def->features &
SUPPORTED_100baseT_Full) {
ep->phy_mii.speed = SPEED_100;
ep->phy_mii.duplex = DUPLEX_FULL;
} else if (ep->phy_mii.def->features &
SUPPORTED_100baseT_Half) {
ep->phy_mii.speed = SPEED_100;
ep->phy_mii.duplex = DUPLEX_HALF;
} else if (ep->phy_mii.def->features &
SUPPORTED_10baseT_Full) {
ep->phy_mii.speed = SPEED_10;
ep->phy_mii.duplex = DUPLEX_FULL;
} else {
ep->phy_mii.speed = SPEED_10;
ep->phy_mii.duplex = DUPLEX_HALF;
}
}
emac_start_link(ep, NULL);
/* read the MAC Address */

View File

@ -584,7 +584,7 @@ static inline int ns83820_add_rx_skb(struct ns83820 *dev, struct sk_buff *skb)
return 0;
}
static inline int rx_refill(struct net_device *ndev, int gfp)
static inline int rx_refill(struct net_device *ndev, unsigned int __nocast gfp)
{
struct ns83820 *dev = PRIV(ndev);
unsigned i;

View File

@ -1832,7 +1832,7 @@ static void fill_multicast_tbl(int count, struct dev_mc_list *addrs,
{
struct dev_mc_list *mc_addr;
for (mc_addr = addrs; mc_addr && --count > 0; mc_addr = mc_addr->next) {
for (mc_addr = addrs; mc_addr && count-- > 0; mc_addr = mc_addr->next) {
u_int position = ether_crc(6, mc_addr->dmi_addr);
#ifndef final_version /* Verify multicast address. */
if ((mc_addr->dmi_addr[0] & 1) == 0)

View File

@ -2837,21 +2837,29 @@ static void skge_netpoll(struct net_device *dev)
static int skge_set_mac_address(struct net_device *dev, void *p)
{
struct skge_port *skge = netdev_priv(dev);
struct sockaddr *addr = p;
int err = 0;
struct skge_hw *hw = skge->hw;
unsigned port = skge->port;
const struct sockaddr *addr = p;
if (!is_valid_ether_addr(addr->sa_data))
return -EADDRNOTAVAIL;
skge_down(dev);
spin_lock_bh(&hw->phy_lock);
memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
memcpy_toio(skge->hw->regs + B2_MAC_1 + skge->port*8,
memcpy_toio(hw->regs + B2_MAC_1 + port*8,
dev->dev_addr, ETH_ALEN);
memcpy_toio(skge->hw->regs + B2_MAC_2 + skge->port*8,
memcpy_toio(hw->regs + B2_MAC_2 + port*8,
dev->dev_addr, ETH_ALEN);
if (dev->flags & IFF_UP)
err = skge_up(dev);
return err;
if (hw->chip_id == CHIP_ID_GENESIS)
xm_outaddr(hw, port, XM_SA, dev->dev_addr);
else {
gma_set_addr(hw, port, GM_SRC_ADDR_1L, dev->dev_addr);
gma_set_addr(hw, port, GM_SRC_ADDR_2L, dev->dev_addr);
}
spin_unlock_bh(&hw->phy_lock);
return 0;
}
static const struct {

View File

@ -133,14 +133,18 @@
- finally added firmware (GPL'ed by Adaptec)
- removed compatibility code for 2.2.x
LK1.4.2.1 (Ion Badulescu)
- fixed 32/64 bit issues on i386 + CONFIG_HIGHMEM
- added 32-bit padding to outgoing skb's, removed previous workaround
TODO: - fix forced speed/duplexing code (broken a long time ago, when
somebody converted the driver to use the generic MII code)
- fix VLAN support
*/
#define DRV_NAME "starfire"
#define DRV_VERSION "1.03+LK1.4.2"
#define DRV_RELDATE "January 19, 2005"
#define DRV_VERSION "1.03+LK1.4.2.1"
#define DRV_RELDATE "October 3, 2005"
#include <linux/config.h>
#include <linux/version.h>
@ -165,6 +169,14 @@ TODO: - fix forced speed/duplexing code (broken a long time ago, when
* of length 1. If and when this is fixed, the #define below can be removed.
*/
#define HAS_BROKEN_FIRMWARE
/*
* If using the broken firmware, data must be padded to the next 32-bit boundary.
*/
#ifdef HAS_BROKEN_FIRMWARE
#define PADDING_MASK 3
#endif
/*
* Define this if using the driver with the zero-copy patch
*/
@ -257,9 +269,10 @@ static int full_duplex[MAX_UNITS] = {0, };
* This SUCKS.
* We need a much better method to determine if dma_addr_t is 64-bit.
*/
#if (defined(__i386__) && defined(CONFIG_HIGHMEM) && (LINUX_VERSION_CODE > 0x20500 || defined(CONFIG_HIGHMEM64G))) || defined(__x86_64__) || defined (__ia64__) || defined(__mips64__) || (defined(__mips__) && defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR))
#if (defined(__i386__) && defined(CONFIG_HIGHMEM64G)) || defined(__x86_64__) || defined (__ia64__) || defined(__mips64__) || (defined(__mips__) && defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR))
/* 64-bit dma_addr_t */
#define ADDR_64BITS /* This chip uses 64 bit addresses. */
#define netdrv_addr_t u64
#define cpu_to_dma(x) cpu_to_le64(x)
#define dma_to_cpu(x) le64_to_cpu(x)
#define RX_DESC_Q_ADDR_SIZE RxDescQAddr64bit
@ -268,6 +281,7 @@ static int full_duplex[MAX_UNITS] = {0, };
#define TX_COMPL_Q_ADDR_SIZE TxComplQAddr64bit
#define RX_DESC_ADDR_SIZE RxDescAddr64bit
#else /* 32-bit dma_addr_t */
#define netdrv_addr_t u32
#define cpu_to_dma(x) cpu_to_le32(x)
#define dma_to_cpu(x) le32_to_cpu(x)
#define RX_DESC_Q_ADDR_SIZE RxDescQAddr32bit
@ -1333,21 +1347,10 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev)
}
#if defined(ZEROCOPY) && defined(HAS_BROKEN_FIRMWARE)
{
int has_bad_length = 0;
if (skb_first_frag_len(skb) == 1)
has_bad_length = 1;
else {
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
if (skb_shinfo(skb)->frags[i].size == 1) {
has_bad_length = 1;
break;
}
}
if (has_bad_length)
skb_checksum_help(skb, 0);
if (skb->ip_summed == CHECKSUM_HW) {
skb = skb_padto(skb, (skb->len + PADDING_MASK) & ~PADDING_MASK);
if (skb == NULL)
return NETDEV_TX_OK;
}
#endif /* ZEROCOPY && HAS_BROKEN_FIRMWARE */
@ -2127,13 +2130,12 @@ static int __init starfire_init (void)
#endif
#endif
#ifndef ADDR_64BITS
/* we can do this test only at run-time... sigh */
if (sizeof(dma_addr_t) == sizeof(u64)) {
printk("This driver has not been ported to this 64-bit architecture yet\n");
if (sizeof(dma_addr_t) != sizeof(netdrv_addr_t)) {
printk("This driver has dma_addr_t issues, please send email to maintainer\n");
return -ENODEV;
}
#endif /* not ADDR_64BITS */
return pci_module_init (&starfire_driver);
}

View File

@ -1035,7 +1035,8 @@ struct gem {
#define ALIGNED_RX_SKB_ADDR(addr) \
((((unsigned long)(addr) + (64UL - 1UL)) & ~(64UL - 1UL)) - (unsigned long)(addr))
static __inline__ struct sk_buff *gem_alloc_skb(int size, int gfp_flags)
static __inline__ struct sk_buff *gem_alloc_skb(int size,
unsigned int __nocast gfp_flags)
{
struct sk_buff *skb = alloc_skb(size + 64, gfp_flags);

View File

@ -531,7 +531,6 @@ static int __devinit ibmtr_probe1(struct net_device *dev, int PIOaddr)
if (!time_after(jiffies, timeout)) continue;
DPRINTK( "Hardware timeout during initialization.\n");
iounmap(t_mmio);
kfree(ti);
return -ENODEV;
}
ti->sram_phys =
@ -645,7 +644,6 @@ static int __devinit ibmtr_probe1(struct net_device *dev, int PIOaddr)
DPRINTK("Unknown shared ram paging info %01X\n",
ti->shared_ram_paging);
iounmap(t_mmio);
kfree(ti);
return -ENODEV;
break;
} /*end switch shared_ram_paging */
@ -675,7 +673,6 @@ static int __devinit ibmtr_probe1(struct net_device *dev, int PIOaddr)
"driver limit (%05x), adapter not started.\n",
chk_base, ibmtr_mem_base + IBMTR_SHARED_RAM_SIZE);
iounmap(t_mmio);
kfree(ti);
return -ENODEV;
} else { /* seems cool, record what we have figured out */
ti->sram_base = new_base >> 12;
@ -690,7 +687,6 @@ static int __devinit ibmtr_probe1(struct net_device *dev, int PIOaddr)
DPRINTK("Could not grab irq %d. Halting Token Ring driver.\n",
irq);
iounmap(t_mmio);
kfree(ti);
return -ENODEV;
}
/*?? Now, allocate some of the PIO PORTs for this driver.. */
@ -699,7 +695,6 @@ static int __devinit ibmtr_probe1(struct net_device *dev, int PIOaddr)
DPRINTK("Could not grab PIO range. Halting driver.\n");
free_irq(dev->irq, dev);
iounmap(t_mmio);
kfree(ti);
return -EBUSY;
}

View File

@ -172,7 +172,7 @@ void t21142_lnk_change(struct net_device *dev, int csr5)
int i;
for (i = 0; i < tp->mtable->leafcount; i++)
if (tp->mtable->mleaf[i].media == dev->if_port) {
int startup = ! ((tp->chip_id == DC21143 && tp->revision == 65));
int startup = ! ((tp->chip_id == DC21143 && (tp->revision == 48 || tp->revision == 65)));
tp->cur_index = i;
tulip_select_media(dev, startup);
setup_done = 1;

View File

@ -503,9 +503,14 @@ static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
return 0;
}
/* Length of the packet body */
/* FIXME: what if the skb is smaller than this? */
len = max_t(int,skb->len - ETH_HLEN, ETH_ZLEN - ETH_HLEN);
/* Check packet length, pad short packets, round up odd length */
len = max_t(int, ALIGN(skb->len, 2), ETH_ZLEN);
if (skb->len < len) {
skb = skb_padto(skb, len);
if (skb == NULL)
goto fail;
}
len -= ETH_HLEN;
eh = (struct ethhdr *)skb->data;
@ -557,8 +562,7 @@ static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
p = skb->data;
}
/* Round up for odd length packets */
err = hermes_bap_pwrite(hw, USER_BAP, p, ALIGN(data_len, 2),
err = hermes_bap_pwrite(hw, USER_BAP, p, data_len,
txfid, data_off);
if (err) {
printk(KERN_ERR "%s: Error %d writing packet to BAP\n",

View File

@ -686,6 +686,7 @@ struct qeth_seqno {
__u32 pdu_hdr;
__u32 pdu_hdr_ack;
__u16 ipa;
__u32 pkt_seqno;
};
struct qeth_reply {
@ -848,6 +849,7 @@ qeth_realloc_headroom(struct qeth_card *card, struct sk_buff **skb, int size)
"on interface %s", QETH_CARD_IFNAME(card));
return -ENOMEM;
}
kfree_skb(*skb);
*skb = new_skb;
}
return 0;

View File

@ -511,7 +511,7 @@ static int
__qeth_set_offline(struct ccwgroup_device *cgdev, int recovery_mode)
{
struct qeth_card *card = (struct qeth_card *) cgdev->dev.driver_data;
int rc = 0;
int rc = 0, rc2 = 0, rc3 = 0;
enum qeth_card_states recover_flag;
QETH_DBF_TEXT(setup, 3, "setoffl");
@ -523,11 +523,13 @@ __qeth_set_offline(struct ccwgroup_device *cgdev, int recovery_mode)
CARD_BUS_ID(card));
return -ERESTARTSYS;
}
if ((rc = ccw_device_set_offline(CARD_DDEV(card))) ||
(rc = ccw_device_set_offline(CARD_WDEV(card))) ||
(rc = ccw_device_set_offline(CARD_RDEV(card)))) {
rc = ccw_device_set_offline(CARD_DDEV(card));
rc2 = ccw_device_set_offline(CARD_WDEV(card));
rc3 = ccw_device_set_offline(CARD_RDEV(card));
if (!rc)
rc = (rc2) ? rc2 : rc3;
if (rc)
QETH_DBF_TEXT_(setup, 2, "1err%d", rc);
}
if (recover_flag == CARD_STATE_UP)
card->state = CARD_STATE_RECOVER;
qeth_notify_processes();
@ -1046,6 +1048,7 @@ qeth_setup_card(struct qeth_card *card)
spin_lock_init(&card->vlanlock);
card->vlangrp = NULL;
#endif
spin_lock_init(&card->lock);
spin_lock_init(&card->ip_lock);
spin_lock_init(&card->thread_mask_lock);
card->thread_start_mask = 0;
@ -1626,16 +1629,6 @@ qeth_cmd_timeout(unsigned long data)
spin_unlock_irqrestore(&reply->card->lock, flags);
}
static void
qeth_reset_ip_addresses(struct qeth_card *card)
{
QETH_DBF_TEXT(trace, 2, "rstipadd");
qeth_clear_ip_list(card, 0, 1);
/* this function will also schedule the SET_IP_THREAD */
qeth_set_multicast_list(card->dev);
}
static struct qeth_ipa_cmd *
qeth_check_ipa_data(struct qeth_card *card, struct qeth_cmd_buffer *iob)
{
@ -1664,9 +1657,8 @@ qeth_check_ipa_data(struct qeth_card *card, struct qeth_cmd_buffer *iob)
"IP address reset.\n",
QETH_CARD_IFNAME(card),
card->info.chpid);
card->lan_online = 1;
netif_carrier_on(card->dev);
qeth_reset_ip_addresses(card);
qeth_schedule_recovery(card);
return NULL;
case IPA_CMD_REGISTER_LOCAL_ADDR:
QETH_DBF_TEXT(trace,3, "irla");
@ -2387,6 +2379,7 @@ qeth_layer2_rebuild_skb(struct qeth_card *card, struct sk_buff *skb,
skb_pull(skb, VLAN_HLEN);
}
#endif
*((__u32 *)skb->cb) = ++card->seqno.pkt_seqno;
return vlan_id;
}
@ -3014,7 +3007,7 @@ qeth_alloc_buffer_pool(struct qeth_card *card)
return -ENOMEM;
}
for(j = 0; j < QETH_MAX_BUFFER_ELEMENTS(card); ++j){
ptr = (void *) __get_free_page(GFP_KERNEL);
ptr = (void *) __get_free_page(GFP_KERNEL|GFP_DMA);
if (!ptr) {
while (j > 0)
free_page((unsigned long)
@ -3058,7 +3051,8 @@ qeth_alloc_qdio_buffers(struct qeth_card *card)
if (card->qdio.state == QETH_QDIO_ALLOCATED)
return 0;
card->qdio.in_q = kmalloc(sizeof(struct qeth_qdio_q), GFP_KERNEL);
card->qdio.in_q = kmalloc(sizeof(struct qeth_qdio_q),
GFP_KERNEL|GFP_DMA);
if (!card->qdio.in_q)
return - ENOMEM;
QETH_DBF_TEXT(setup, 2, "inq");
@ -3083,7 +3077,7 @@ qeth_alloc_qdio_buffers(struct qeth_card *card)
}
for (i = 0; i < card->qdio.no_out_queues; ++i){
card->qdio.out_qs[i] = kmalloc(sizeof(struct qeth_qdio_out_q),
GFP_KERNEL);
GFP_KERNEL|GFP_DMA);
if (!card->qdio.out_qs[i]){
while (i > 0)
kfree(card->qdio.out_qs[--i]);
@ -6470,6 +6464,9 @@ qeth_query_ipassists_cb(struct qeth_card *card, struct qeth_reply *reply,
if (cmd->hdr.prot_version == QETH_PROT_IPV4) {
card->options.ipa4.supported_funcs = cmd->hdr.ipa_supported;
card->options.ipa4.enabled_funcs = cmd->hdr.ipa_enabled;
/* Disable IPV6 support hard coded for Hipersockets */
if(card->info.type == QETH_CARD_TYPE_IQD)
card->options.ipa4.supported_funcs &= ~IPA_IPV6;
} else {
#ifdef CONFIG_QETH_IPV6
card->options.ipa6.supported_funcs = cmd->hdr.ipa_supported;

View File

@ -521,6 +521,14 @@ config SCSI_SATA_SIL
If unsure, say N.
config SCSI_SATA_SIL24
tristate "Silicon Image 3124/3132 SATA support"
depends on SCSI_SATA && PCI && EXPERIMENTAL
help
This option enables support for Silicon Image 3124/3132 Serial ATA.
If unsure, say N.
config SCSI_SATA_SIS
tristate "SiS 964/180 SATA support"
depends on SCSI_SATA && PCI && EXPERIMENTAL

View File

@ -130,6 +130,7 @@ obj-$(CONFIG_SCSI_ATA_PIIX) += libata.o ata_piix.o
obj-$(CONFIG_SCSI_SATA_PROMISE) += libata.o sata_promise.o
obj-$(CONFIG_SCSI_SATA_QSTOR) += libata.o sata_qstor.o
obj-$(CONFIG_SCSI_SATA_SIL) += libata.o sata_sil.o
obj-$(CONFIG_SCSI_SATA_SIL24) += libata.o sata_sil24.o
obj-$(CONFIG_SCSI_SATA_VIA) += libata.o sata_via.o
obj-$(CONFIG_SCSI_SATA_VITESSE) += libata.o sata_vsc.o
obj-$(CONFIG_SCSI_SATA_SIS) += libata.o sata_sis.o

View File

@ -680,17 +680,36 @@ static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs *
for (i = 0; i < host_set->n_ports; i++) {
struct ata_port *ap;
u32 tmp;
VPRINTK("port %u\n", i);
if (!(irq_stat & (1 << i)))
continue;
ap = host_set->ports[i];
tmp = irq_stat & (1 << i);
if (tmp && ap) {
if (ap) {
struct ata_queued_cmd *qc;
qc = ata_qc_from_tag(ap, ap->active_tag);
if (ahci_host_intr(ap, qc))
irq_ack |= (1 << i);
if (!ahci_host_intr(ap, qc))
if (ata_ratelimit()) {
struct pci_dev *pdev =
to_pci_dev(ap->host_set->dev);
printk(KERN_WARNING
"ahci(%s): unhandled interrupt on port %u\n",
pci_name(pdev), i);
}
VPRINTK("port %u\n", i);
} else {
VPRINTK("port %u (no irq)\n", i);
if (ata_ratelimit()) {
struct pci_dev *pdev =
to_pci_dev(ap->host_set->dev);
printk(KERN_WARNING
"ahci(%s): interrupt on disabled port %u\n",
pci_name(pdev), i);
}
}
irq_ack |= (1 << i);
}
if (irq_ack) {

View File

@ -48,6 +48,7 @@
#include <linux/completion.h>
#include <linux/suspend.h>
#include <linux/workqueue.h>
#include <linux/jiffies.h>
#include <scsi/scsi.h>
#include "scsi.h"
#include "scsi_priv.h"
@ -62,6 +63,7 @@
static unsigned int ata_busy_sleep (struct ata_port *ap,
unsigned long tmout_pat,
unsigned long tmout);
static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev);
static void ata_set_mode(struct ata_port *ap);
static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev);
static unsigned int ata_get_mode_mask(struct ata_port *ap, int shift);
@ -69,7 +71,6 @@ static int fgb(u32 bitmap);
static int ata_choose_xfer_mode(struct ata_port *ap,
u8 *xfer_mode_out,
unsigned int *xfer_shift_out);
static int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat);
static void __ata_qc_complete(struct ata_queued_cmd *qc);
static unsigned int ata_unique_id = 1;
@ -1131,7 +1132,7 @@ static inline void ata_dump_id(struct ata_device *dev)
static void ata_dev_identify(struct ata_port *ap, unsigned int device)
{
struct ata_device *dev = &ap->device[device];
unsigned int i;
unsigned int major_version;
u16 tmp;
unsigned long xfer_modes;
u8 status;
@ -1229,9 +1230,9 @@ retry:
* common ATA, ATAPI feature tests
*/
/* we require LBA and DMA support (bits 8 & 9 of word 49) */
if (!ata_id_has_dma(dev->id) || !ata_id_has_lba(dev->id)) {
printk(KERN_DEBUG "ata%u: no dma/lba\n", ap->id);
/* we require DMA support (bits 8 of word 49) */
if (!ata_id_has_dma(dev->id)) {
printk(KERN_DEBUG "ata%u: no dma\n", ap->id);
goto err_out_nosup;
}
@ -1251,32 +1252,69 @@ retry:
if (!ata_id_is_ata(dev->id)) /* sanity check */
goto err_out_nosup;
/* get major version */
tmp = dev->id[ATA_ID_MAJOR_VER];
for (i = 14; i >= 1; i--)
if (tmp & (1 << i))
for (major_version = 14; major_version >= 1; major_version--)
if (tmp & (1 << major_version))
break;
/* we require at least ATA-3 */
if (i < 3) {
printk(KERN_DEBUG "ata%u: no ATA-3\n", ap->id);
goto err_out_nosup;
}
/*
* The exact sequence expected by certain pre-ATA4 drives is:
* SRST RESET
* IDENTIFY
* INITIALIZE DEVICE PARAMETERS
* anything else..
* Some drives were very specific about that exact sequence.
*/
if (major_version < 4 || (!ata_id_has_lba(dev->id)))
ata_dev_init_params(ap, dev);
if (ata_id_has_lba(dev->id)) {
dev->flags |= ATA_DFLAG_LBA;
if (ata_id_has_lba48(dev->id)) {
dev->flags |= ATA_DFLAG_LBA48;
dev->n_sectors = ata_id_u64(dev->id, 100);
} else {
dev->n_sectors = ata_id_u32(dev->id, 60);
}
/* print device info to dmesg */
printk(KERN_INFO "ata%u: dev %u ATA-%d, max %s, %Lu sectors:%s\n",
ap->id, device,
major_version,
ata_mode_string(xfer_modes),
(unsigned long long)dev->n_sectors,
dev->flags & ATA_DFLAG_LBA48 ? " LBA48" : " LBA");
} else {
/* CHS */
/* Default translation */
dev->cylinders = dev->id[1];
dev->heads = dev->id[3];
dev->sectors = dev->id[6];
dev->n_sectors = dev->cylinders * dev->heads * dev->sectors;
if (ata_id_current_chs_valid(dev->id)) {
/* Current CHS translation is valid. */
dev->cylinders = dev->id[54];
dev->heads = dev->id[55];
dev->sectors = dev->id[56];
dev->n_sectors = ata_id_u32(dev->id, 57);
}
/* print device info to dmesg */
printk(KERN_INFO "ata%u: dev %u ATA-%d, max %s, %Lu sectors: CHS %d/%d/%d\n",
ap->id, device,
major_version,
ata_mode_string(xfer_modes),
(unsigned long long)dev->n_sectors,
(int)dev->cylinders, (int)dev->heads, (int)dev->sectors);
if (ata_id_has_lba48(dev->id)) {
dev->flags |= ATA_DFLAG_LBA48;
dev->n_sectors = ata_id_u64(dev->id, 100);
} else {
dev->n_sectors = ata_id_u32(dev->id, 60);
}
ap->host->max_cmd_len = 16;
/* print device info to dmesg */
printk(KERN_INFO "ata%u: dev %u ATA, max %s, %Lu sectors:%s\n",
ap->id, device,
ata_mode_string(xfer_modes),
(unsigned long long)dev->n_sectors,
dev->flags & ATA_DFLAG_LBA48 ? " lba48" : "");
}
/* ATAPI-specific feature tests */
@ -2143,6 +2181,54 @@ static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev)
DPRINTK("EXIT\n");
}
/**
* ata_dev_init_params - Issue INIT DEV PARAMS command
* @ap: Port associated with device @dev
* @dev: Device to which command will be sent
*
* LOCKING:
*/
static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev)
{
DECLARE_COMPLETION(wait);
struct ata_queued_cmd *qc;
int rc;
unsigned long flags;
u16 sectors = dev->id[6];
u16 heads = dev->id[3];
/* Number of sectors per track 1-255. Number of heads 1-16 */
if (sectors < 1 || sectors > 255 || heads < 1 || heads > 16)
return;
/* set up init dev params taskfile */
DPRINTK("init dev params \n");
qc = ata_qc_new_init(ap, dev);
BUG_ON(qc == NULL);
qc->tf.command = ATA_CMD_INIT_DEV_PARAMS;
qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
qc->tf.protocol = ATA_PROT_NODATA;
qc->tf.nsect = sectors;
qc->tf.device |= (heads - 1) & 0x0f; /* max head = num. of heads - 1 */
qc->waiting = &wait;
qc->complete_fn = ata_qc_complete_noop;
spin_lock_irqsave(&ap->host_set->lock, flags);
rc = ata_qc_issue(qc);
spin_unlock_irqrestore(&ap->host_set->lock, flags);
if (rc)
ata_port_disable(ap);
else
wait_for_completion(&wait);
DPRINTK("EXIT\n");
}
/**
* ata_sg_clean - Unmap DMA memory associated with command
* @qc: Command containing DMA memory to be released
@ -2507,20 +2593,20 @@ void ata_poll_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
static unsigned long ata_pio_poll(struct ata_port *ap)
{
u8 status;
unsigned int poll_state = PIO_ST_UNKNOWN;
unsigned int reg_state = PIO_ST_UNKNOWN;
const unsigned int tmout_state = PIO_ST_TMOUT;
unsigned int poll_state = HSM_ST_UNKNOWN;
unsigned int reg_state = HSM_ST_UNKNOWN;
const unsigned int tmout_state = HSM_ST_TMOUT;
switch (ap->pio_task_state) {
case PIO_ST:
case PIO_ST_POLL:
poll_state = PIO_ST_POLL;
reg_state = PIO_ST;
switch (ap->hsm_task_state) {
case HSM_ST:
case HSM_ST_POLL:
poll_state = HSM_ST_POLL;
reg_state = HSM_ST;
break;
case PIO_ST_LAST:
case PIO_ST_LAST_POLL:
poll_state = PIO_ST_LAST_POLL;
reg_state = PIO_ST_LAST;
case HSM_ST_LAST:
case HSM_ST_LAST_POLL:
poll_state = HSM_ST_LAST_POLL;
reg_state = HSM_ST_LAST;
break;
default:
BUG();
@ -2530,14 +2616,14 @@ static unsigned long ata_pio_poll(struct ata_port *ap)
status = ata_chk_status(ap);
if (status & ATA_BUSY) {
if (time_after(jiffies, ap->pio_task_timeout)) {
ap->pio_task_state = tmout_state;
ap->hsm_task_state = tmout_state;
return 0;
}
ap->pio_task_state = poll_state;
ap->hsm_task_state = poll_state;
return ATA_SHORT_PAUSE;
}
ap->pio_task_state = reg_state;
ap->hsm_task_state = reg_state;
return 0;
}
@ -2562,14 +2648,14 @@ static int ata_pio_complete (struct ata_port *ap)
* we enter, BSY will be cleared in a chk-status or two. If not,
* the drive is probably seeking or something. Snooze for a couple
* msecs, then chk-status again. If still busy, fall back to
* PIO_ST_POLL state.
* HSM_ST_POLL state.
*/
drv_stat = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 10);
if (drv_stat & (ATA_BUSY | ATA_DRQ)) {
msleep(2);
drv_stat = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 10);
if (drv_stat & (ATA_BUSY | ATA_DRQ)) {
ap->pio_task_state = PIO_ST_LAST_POLL;
ap->hsm_task_state = HSM_ST_LAST_POLL;
ap->pio_task_timeout = jiffies + ATA_TMOUT_PIO;
return 0;
}
@ -2577,14 +2663,14 @@ static int ata_pio_complete (struct ata_port *ap)
drv_stat = ata_wait_idle(ap);
if (!ata_ok(drv_stat)) {
ap->pio_task_state = PIO_ST_ERR;
ap->hsm_task_state = HSM_ST_ERR;
return 0;
}
qc = ata_qc_from_tag(ap, ap->active_tag);
assert(qc != NULL);
ap->pio_task_state = PIO_ST_IDLE;
ap->hsm_task_state = HSM_ST_IDLE;
ata_poll_qc_complete(qc, drv_stat);
@ -2744,7 +2830,7 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
unsigned char *buf;
if (qc->cursect == (qc->nsect - 1))
ap->pio_task_state = PIO_ST_LAST;
ap->hsm_task_state = HSM_ST_LAST;
page = sg[qc->cursg].page;
offset = sg[qc->cursg].offset + qc->cursg_ofs * ATA_SECT_SIZE;
@ -2794,7 +2880,7 @@ static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes)
unsigned int offset, count;
if (qc->curbytes + bytes >= qc->nbytes)
ap->pio_task_state = PIO_ST_LAST;
ap->hsm_task_state = HSM_ST_LAST;
next_sg:
if (unlikely(qc->cursg >= qc->n_elem)) {
@ -2816,7 +2902,7 @@ next_sg:
for (i = 0; i < words; i++)
ata_data_xfer(ap, (unsigned char*)pad_buf, 2, do_write);
ap->pio_task_state = PIO_ST_LAST;
ap->hsm_task_state = HSM_ST_LAST;
return;
}
@ -2897,7 +2983,7 @@ static void atapi_pio_bytes(struct ata_queued_cmd *qc)
err_out:
printk(KERN_INFO "ata%u: dev %u: ATAPI check failed\n",
ap->id, dev->devno);
ap->pio_task_state = PIO_ST_ERR;
ap->hsm_task_state = HSM_ST_ERR;
}
/**
@ -2919,14 +3005,14 @@ static void ata_pio_block(struct ata_port *ap)
* a chk-status or two. If not, the drive is probably seeking
* or something. Snooze for a couple msecs, then
* chk-status again. If still busy, fall back to
* PIO_ST_POLL state.
* HSM_ST_POLL state.
*/
status = ata_busy_wait(ap, ATA_BUSY, 5);
if (status & ATA_BUSY) {
msleep(2);
status = ata_busy_wait(ap, ATA_BUSY, 10);
if (status & ATA_BUSY) {
ap->pio_task_state = PIO_ST_POLL;
ap->hsm_task_state = HSM_ST_POLL;
ap->pio_task_timeout = jiffies + ATA_TMOUT_PIO;
return;
}
@ -2938,7 +3024,7 @@ static void ata_pio_block(struct ata_port *ap)
if (is_atapi_taskfile(&qc->tf)) {
/* no more data to transfer or unsupported ATAPI command */
if ((status & ATA_DRQ) == 0) {
ap->pio_task_state = PIO_ST_LAST;
ap->hsm_task_state = HSM_ST_LAST;
return;
}
@ -2946,7 +3032,7 @@ static void ata_pio_block(struct ata_port *ap)
} else {
/* handle BSY=0, DRQ=0 as error */
if ((status & ATA_DRQ) == 0) {
ap->pio_task_state = PIO_ST_ERR;
ap->hsm_task_state = HSM_ST_ERR;
return;
}
@ -2966,7 +3052,7 @@ static void ata_pio_error(struct ata_port *ap)
printk(KERN_WARNING "ata%u: PIO error, drv_stat 0x%x\n",
ap->id, drv_stat);
ap->pio_task_state = PIO_ST_IDLE;
ap->hsm_task_state = HSM_ST_IDLE;
ata_poll_qc_complete(qc, drv_stat | ATA_ERR);
}
@ -2981,25 +3067,25 @@ fsm_start:
timeout = 0;
qc_completed = 0;
switch (ap->pio_task_state) {
case PIO_ST_IDLE:
switch (ap->hsm_task_state) {
case HSM_ST_IDLE:
return;
case PIO_ST:
case HSM_ST:
ata_pio_block(ap);
break;
case PIO_ST_LAST:
case HSM_ST_LAST:
qc_completed = ata_pio_complete(ap);
break;
case PIO_ST_POLL:
case PIO_ST_LAST_POLL:
case HSM_ST_POLL:
case HSM_ST_LAST_POLL:
timeout = ata_pio_poll(ap);
break;
case PIO_ST_TMOUT:
case PIO_ST_ERR:
case HSM_ST_TMOUT:
case HSM_ST_ERR:
ata_pio_error(ap);
return;
}
@ -3010,52 +3096,6 @@ fsm_start:
goto fsm_start;
}
static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
struct scsi_cmnd *cmd)
{
DECLARE_COMPLETION(wait);
struct ata_queued_cmd *qc;
unsigned long flags;
int rc;
DPRINTK("ATAPI request sense\n");
qc = ata_qc_new_init(ap, dev);
BUG_ON(qc == NULL);
/* FIXME: is this needed? */
memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer));
ata_sg_init_one(qc, cmd->sense_buffer, sizeof(cmd->sense_buffer));
qc->dma_dir = DMA_FROM_DEVICE;
memset(&qc->cdb, 0, ap->cdb_len);
qc->cdb[0] = REQUEST_SENSE;
qc->cdb[4] = SCSI_SENSE_BUFFERSIZE;
qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
qc->tf.command = ATA_CMD_PACKET;
qc->tf.protocol = ATA_PROT_ATAPI;
qc->tf.lbam = (8 * 1024) & 0xff;
qc->tf.lbah = (8 * 1024) >> 8;
qc->nbytes = SCSI_SENSE_BUFFERSIZE;
qc->waiting = &wait;
qc->complete_fn = ata_qc_complete_noop;
spin_lock_irqsave(&ap->host_set->lock, flags);
rc = ata_qc_issue(qc);
spin_unlock_irqrestore(&ap->host_set->lock, flags);
if (rc)
ata_port_disable(ap);
else
wait_for_completion(&wait);
DPRINTK("EXIT\n");
}
/**
* ata_qc_timeout - Handle timeout of queued command
* @qc: Command that timed out
@ -3173,14 +3213,14 @@ void ata_eng_timeout(struct ata_port *ap)
DPRINTK("ENTER\n");
qc = ata_qc_from_tag(ap, ap->active_tag);
if (!qc) {
if (qc)
ata_qc_timeout(qc);
else {
printk(KERN_ERR "ata%u: BUG: timeout without command\n",
ap->id);
goto out;
}
ata_qc_timeout(qc);
out:
DPRINTK("EXIT\n");
}
@ -3238,14 +3278,18 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
ata_tf_init(ap, &qc->tf, dev->devno);
if (dev->flags & ATA_DFLAG_LBA48)
qc->tf.flags |= ATA_TFLAG_LBA48;
if (dev->flags & ATA_DFLAG_LBA) {
qc->tf.flags |= ATA_TFLAG_LBA;
if (dev->flags & ATA_DFLAG_LBA48)
qc->tf.flags |= ATA_TFLAG_LBA48;
}
}
return qc;
}
static int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat)
int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat)
{
return 0;
}
@ -3442,7 +3486,7 @@ int ata_qc_issue_prot(struct ata_queued_cmd *qc)
case ATA_PROT_PIO: /* load tf registers, initiate polling pio */
ata_qc_set_polling(qc);
ata_tf_to_host_nolock(ap, &qc->tf);
ap->pio_task_state = PIO_ST;
ap->hsm_task_state = HSM_ST;
queue_work(ata_wq, &ap->pio_task);
break;
@ -3668,7 +3712,7 @@ u8 ata_bmdma_status(struct ata_port *ap)
void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr;
host_stat = readb(mmio + ATA_DMA_STATUS);
} else
host_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
host_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
return host_stat;
}
@ -3888,7 +3932,7 @@ static void atapi_packet_task(void *_data)
ata_data_xfer(ap, qc->cdb, ap->cdb_len, 1);
/* PIO commands are handled by polling */
ap->pio_task_state = PIO_ST;
ap->hsm_task_state = HSM_ST;
queue_work(ata_wq, &ap->pio_task);
}
@ -4202,7 +4246,7 @@ int ata_device_add(struct ata_probe_ent *ent)
for (i = 0; i < count; i++) {
struct ata_port *ap = host_set->ports[i];
scsi_scan_host(ap->host);
ata_scsi_scan_host(ap);
}
dev_set_drvdata(dev, host_set);
@ -4362,85 +4406,87 @@ void ata_pci_host_stop (struct ata_host_set *host_set)
* ata_pci_init_native_mode - Initialize native-mode driver
* @pdev: pci device to be initialized
* @port: array[2] of pointers to port info structures.
* @ports: bitmap of ports present
*
* Utility function which allocates and initializes an
* ata_probe_ent structure for a standard dual-port
* PIO-based IDE controller. The returned ata_probe_ent
* structure can be passed to ata_device_add(). The returned
* ata_probe_ent structure should then be freed with kfree().
*
* The caller need only pass the address of the primary port, the
* secondary will be deduced automatically. If the device has non
* standard secondary port mappings this function can be called twice,
* once for each interface.
*/
struct ata_probe_ent *
ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port)
ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int ports)
{
struct ata_probe_ent *probe_ent =
ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]);
int p = 0;
if (!probe_ent)
return NULL;
probe_ent->n_ports = 2;
probe_ent->irq = pdev->irq;
probe_ent->irq_flags = SA_SHIRQ;
probe_ent->port[0].cmd_addr = pci_resource_start(pdev, 0);
probe_ent->port[0].altstatus_addr =
probe_ent->port[0].ctl_addr =
pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS;
probe_ent->port[0].bmdma_addr = pci_resource_start(pdev, 4);
if (ports & ATA_PORT_PRIMARY) {
probe_ent->port[p].cmd_addr = pci_resource_start(pdev, 0);
probe_ent->port[p].altstatus_addr =
probe_ent->port[p].ctl_addr =
pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS;
probe_ent->port[p].bmdma_addr = pci_resource_start(pdev, 4);
ata_std_ports(&probe_ent->port[p]);
p++;
}
probe_ent->port[1].cmd_addr = pci_resource_start(pdev, 2);
probe_ent->port[1].altstatus_addr =
probe_ent->port[1].ctl_addr =
pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS;
probe_ent->port[1].bmdma_addr = pci_resource_start(pdev, 4) + 8;
ata_std_ports(&probe_ent->port[0]);
ata_std_ports(&probe_ent->port[1]);
if (ports & ATA_PORT_SECONDARY) {
probe_ent->port[p].cmd_addr = pci_resource_start(pdev, 2);
probe_ent->port[p].altstatus_addr =
probe_ent->port[p].ctl_addr =
pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS;
probe_ent->port[p].bmdma_addr = pci_resource_start(pdev, 4) + 8;
ata_std_ports(&probe_ent->port[p]);
p++;
}
probe_ent->n_ports = p;
return probe_ent;
}
static struct ata_probe_ent *
ata_pci_init_legacy_mode(struct pci_dev *pdev, struct ata_port_info **port,
struct ata_probe_ent **ppe2)
static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, struct ata_port_info **port, int port_num)
{
struct ata_probe_ent *probe_ent, *probe_ent2;
struct ata_probe_ent *probe_ent;
probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]);
if (!probe_ent)
return NULL;
probe_ent2 = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[1]);
if (!probe_ent2) {
kfree(probe_ent);
return NULL;
}
probe_ent->n_ports = 1;
probe_ent->irq = 14;
probe_ent->hard_port_no = 0;
probe_ent->legacy_mode = 1;
probe_ent->n_ports = 1;
probe_ent->hard_port_no = port_num;
probe_ent2->n_ports = 1;
probe_ent2->irq = 15;
probe_ent2->hard_port_no = 1;
probe_ent2->legacy_mode = 1;
probe_ent->port[0].cmd_addr = 0x1f0;
probe_ent->port[0].altstatus_addr =
probe_ent->port[0].ctl_addr = 0x3f6;
probe_ent->port[0].bmdma_addr = pci_resource_start(pdev, 4);
probe_ent2->port[0].cmd_addr = 0x170;
probe_ent2->port[0].altstatus_addr =
probe_ent2->port[0].ctl_addr = 0x376;
probe_ent2->port[0].bmdma_addr = pci_resource_start(pdev, 4)+8;
switch(port_num)
{
case 0:
probe_ent->irq = 14;
probe_ent->port[0].cmd_addr = 0x1f0;
probe_ent->port[0].altstatus_addr =
probe_ent->port[0].ctl_addr = 0x3f6;
break;
case 1:
probe_ent->irq = 15;
probe_ent->port[0].cmd_addr = 0x170;
probe_ent->port[0].altstatus_addr =
probe_ent->port[0].ctl_addr = 0x376;
break;
}
probe_ent->port[0].bmdma_addr = pci_resource_start(pdev, 4) + 8 * port_num;
ata_std_ports(&probe_ent->port[0]);
ata_std_ports(&probe_ent2->port[0]);
*ppe2 = probe_ent2;
return probe_ent;
}
@ -4469,7 +4515,7 @@ ata_pci_init_legacy_mode(struct pci_dev *pdev, struct ata_port_info **port,
int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
unsigned int n_ports)
{
struct ata_probe_ent *probe_ent, *probe_ent2 = NULL;
struct ata_probe_ent *probe_ent = NULL, *probe_ent2 = NULL;
struct ata_port_info *port[2];
u8 tmp8, mask;
unsigned int legacy_mode = 0;
@ -4486,7 +4532,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
if ((port[0]->host_flags & ATA_FLAG_NO_LEGACY) == 0
&& (pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
/* TODO: support transitioning to native mode? */
/* TODO: What if one channel is in native mode ... */
pci_read_config_byte(pdev, PCI_CLASS_PROG, &tmp8);
mask = (1 << 2) | (1 << 0);
if ((tmp8 & mask) != mask)
@ -4494,11 +4540,20 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
}
/* FIXME... */
if ((!legacy_mode) && (n_ports > 1)) {
printk(KERN_ERR "ata: BUG: native mode, n_ports > 1\n");
return -EINVAL;
if ((!legacy_mode) && (n_ports > 2)) {
printk(KERN_ERR "ata: BUG: native mode, n_ports > 2\n");
n_ports = 2;
/* For now */
}
/* FIXME: Really for ATA it isn't safe because the device may be
multi-purpose and we want to leave it alone if it was already
enabled. Secondly for shared use as Arjan says we want refcounting
Checking dev->is_enabled is insufficient as this is not set at
boot for the primary video which is BIOS enabled
*/
rc = pci_enable_device(pdev);
if (rc)
return rc;
@ -4509,6 +4564,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
goto err_out;
}
/* FIXME: Should use platform specific mappers for legacy port ranges */
if (legacy_mode) {
if (!request_region(0x1f0, 8, "libata")) {
struct resource *conflict, res;
@ -4553,10 +4609,17 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
goto err_out_regions;
if (legacy_mode) {
probe_ent = ata_pci_init_legacy_mode(pdev, port, &probe_ent2);
} else
probe_ent = ata_pci_init_native_mode(pdev, port);
if (!probe_ent) {
if (legacy_mode & (1 << 0))
probe_ent = ata_pci_init_legacy_port(pdev, port, 0);
if (legacy_mode & (1 << 1))
probe_ent2 = ata_pci_init_legacy_port(pdev, port, 1);
} else {
if (n_ports == 2)
probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
else
probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY);
}
if (!probe_ent && !probe_ent2) {
rc = -ENOMEM;
goto err_out_regions;
}
@ -4668,6 +4731,27 @@ static void __exit ata_exit(void)
module_init(ata_init);
module_exit(ata_exit);
static unsigned long ratelimit_time;
static spinlock_t ata_ratelimit_lock = SPIN_LOCK_UNLOCKED;
int ata_ratelimit(void)
{
int rc;
unsigned long flags;
spin_lock_irqsave(&ata_ratelimit_lock, flags);
if (time_after(jiffies, ratelimit_time)) {
rc = 1;
ratelimit_time = jiffies + (HZ/5);
} else
rc = 0;
spin_unlock_irqrestore(&ata_ratelimit_lock, flags);
return rc;
}
/*
* libata is essentially a library of internal helper functions for
* low-level ATA host controller drivers. As such, the API/ABI is
@ -4709,6 +4793,7 @@ EXPORT_SYMBOL_GPL(sata_phy_reset);
EXPORT_SYMBOL_GPL(__sata_phy_reset);
EXPORT_SYMBOL_GPL(ata_bus_reset);
EXPORT_SYMBOL_GPL(ata_port_disable);
EXPORT_SYMBOL_GPL(ata_ratelimit);
EXPORT_SYMBOL_GPL(ata_scsi_ioctl);
EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
EXPORT_SYMBOL_GPL(ata_scsi_error);

View File

@ -49,6 +49,14 @@ static struct ata_device *
ata_scsi_find_dev(struct ata_port *ap, struct scsi_device *scsidev);
static void ata_scsi_invalid_field(struct scsi_cmnd *cmd,
void (*done)(struct scsi_cmnd *))
{
ata_scsi_set_sense(cmd, ILLEGAL_REQUEST, 0x24, 0x0);
/* "Invalid field in cbd" */
done(cmd);
}
/**
* ata_std_bios_param - generic bios head/sector/cylinder calculator used by sd.
* @sdev: SCSI device for which BIOS geometry is to be determined
@ -182,7 +190,6 @@ void ata_to_sense_error(struct ata_queued_cmd *qc, u8 drv_stat)
{
struct scsi_cmnd *cmd = qc->scsicmd;
u8 err = 0;
unsigned char *sb = cmd->sense_buffer;
/* Based on the 3ware driver translation table */
static unsigned char sense_table[][4] = {
/* BBD|ECC|ID|MAR */
@ -225,8 +232,6 @@ void ata_to_sense_error(struct ata_queued_cmd *qc, u8 drv_stat)
};
int i = 0;
cmd->result = SAM_STAT_CHECK_CONDITION;
/*
* Is this an error we can process/parse
*/
@ -281,11 +286,9 @@ void ata_to_sense_error(struct ata_queued_cmd *qc, u8 drv_stat)
/* Look for best matches first */
if((sense_table[i][0] & err) == sense_table[i][0])
{
sb[0] = 0x70;
sb[2] = sense_table[i][1];
sb[7] = 0x0a;
sb[12] = sense_table[i][2];
sb[13] = sense_table[i][3];
ata_scsi_set_sense(cmd, sense_table[i][1] /* sk */,
sense_table[i][2] /* asc */,
sense_table[i][3] /* ascq */ );
return;
}
i++;
@ -300,11 +303,9 @@ void ata_to_sense_error(struct ata_queued_cmd *qc, u8 drv_stat)
{
if(stat_table[i][0] & drv_stat)
{
sb[0] = 0x70;
sb[2] = stat_table[i][1];
sb[7] = 0x0a;
sb[12] = stat_table[i][2];
sb[13] = stat_table[i][3];
ata_scsi_set_sense(cmd, sense_table[i][1] /* sk */,
sense_table[i][2] /* asc */,
sense_table[i][3] /* ascq */ );
return;
}
i++;
@ -313,15 +314,12 @@ void ata_to_sense_error(struct ata_queued_cmd *qc, u8 drv_stat)
printk(KERN_ERR "ata%u: called with no error (%02X)!\n", qc->ap->id, drv_stat);
/* additional-sense-code[-qualifier] */
sb[0] = 0x70;
sb[2] = MEDIUM_ERROR;
sb[7] = 0x0A;
if (cmd->sc_data_direction == DMA_FROM_DEVICE) {
sb[12] = 0x11; /* "unrecovered read error" */
sb[13] = 0x04;
ata_scsi_set_sense(cmd, MEDIUM_ERROR, 0x11, 0x4);
/* "unrecovered read error" */
} else {
sb[12] = 0x0C; /* "write error - */
sb[13] = 0x02; /* auto-reallocation failed" */
ata_scsi_set_sense(cmd, MEDIUM_ERROR, 0xc, 0x2);
/* "write error - auto-reallocation failed" */
}
}
@ -440,15 +438,26 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc,
; /* ignore IMMED bit, violates sat-r05 */
}
if (scsicmd[4] & 0x2)
return 1; /* LOEJ bit set not supported */
goto invalid_fld; /* LOEJ bit set not supported */
if (((scsicmd[4] >> 4) & 0xf) != 0)
return 1; /* power conditions not supported */
goto invalid_fld; /* power conditions not supported */
if (scsicmd[4] & 0x1) {
tf->nsect = 1; /* 1 sector, lba=0 */
tf->lbah = 0x0;
tf->lbam = 0x0;
tf->lbal = 0x0;
tf->device |= ATA_LBA;
if (qc->dev->flags & ATA_DFLAG_LBA) {
qc->tf.flags |= ATA_TFLAG_LBA;
tf->lbah = 0x0;
tf->lbam = 0x0;
tf->lbal = 0x0;
tf->device |= ATA_LBA;
} else {
/* CHS */
tf->lbal = 0x1; /* sect */
tf->lbam = 0x0; /* cyl low */
tf->lbah = 0x0; /* cyl high */
}
tf->command = ATA_CMD_VERIFY; /* READ VERIFY */
} else {
tf->nsect = 0; /* time period value (0 implies now) */
@ -463,6 +472,11 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc,
*/
return 0;
invalid_fld:
ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x0);
/* "Invalid field in cbd" */
return 1;
}
@ -497,6 +511,99 @@ static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
return 0;
}
/**
* scsi_6_lba_len - Get LBA and transfer length
* @scsicmd: SCSI command to translate
*
* Calculate LBA and transfer length for 6-byte commands.
*
* RETURNS:
* @plba: the LBA
* @plen: the transfer length
*/
static void scsi_6_lba_len(u8 *scsicmd, u64 *plba, u32 *plen)
{
u64 lba = 0;
u32 len = 0;
VPRINTK("six-byte command\n");
lba |= ((u64)scsicmd[2]) << 8;
lba |= ((u64)scsicmd[3]);
len |= ((u32)scsicmd[4]);
*plba = lba;
*plen = len;
}
/**
* scsi_10_lba_len - Get LBA and transfer length
* @scsicmd: SCSI command to translate
*
* Calculate LBA and transfer length for 10-byte commands.
*
* RETURNS:
* @plba: the LBA
* @plen: the transfer length
*/
static void scsi_10_lba_len(u8 *scsicmd, u64 *plba, u32 *plen)
{
u64 lba = 0;
u32 len = 0;
VPRINTK("ten-byte command\n");
lba |= ((u64)scsicmd[2]) << 24;
lba |= ((u64)scsicmd[3]) << 16;
lba |= ((u64)scsicmd[4]) << 8;
lba |= ((u64)scsicmd[5]);
len |= ((u32)scsicmd[7]) << 8;
len |= ((u32)scsicmd[8]);
*plba = lba;
*plen = len;
}
/**
* scsi_16_lba_len - Get LBA and transfer length
* @scsicmd: SCSI command to translate
*
* Calculate LBA and transfer length for 16-byte commands.
*
* RETURNS:
* @plba: the LBA
* @plen: the transfer length
*/
static void scsi_16_lba_len(u8 *scsicmd, u64 *plba, u32 *plen)
{
u64 lba = 0;
u32 len = 0;
VPRINTK("sixteen-byte command\n");
lba |= ((u64)scsicmd[2]) << 56;
lba |= ((u64)scsicmd[3]) << 48;
lba |= ((u64)scsicmd[4]) << 40;
lba |= ((u64)scsicmd[5]) << 32;
lba |= ((u64)scsicmd[6]) << 24;
lba |= ((u64)scsicmd[7]) << 16;
lba |= ((u64)scsicmd[8]) << 8;
lba |= ((u64)scsicmd[9]);
len |= ((u32)scsicmd[10]) << 24;
len |= ((u32)scsicmd[11]) << 16;
len |= ((u32)scsicmd[12]) << 8;
len |= ((u32)scsicmd[13]);
*plba = lba;
*plen = len;
}
/**
* ata_scsi_verify_xlat - Translate SCSI VERIFY command into an ATA one
* @qc: Storage for translated ATA taskfile
@ -514,79 +621,102 @@ static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
{
struct ata_taskfile *tf = &qc->tf;
struct ata_device *dev = qc->dev;
unsigned int lba = tf->flags & ATA_TFLAG_LBA;
unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48;
u64 dev_sectors = qc->dev->n_sectors;
u64 sect = 0;
u32 n_sect = 0;
u64 block;
u32 n_block;
tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
tf->protocol = ATA_PROT_NODATA;
tf->device |= ATA_LBA;
if (scsicmd[0] == VERIFY) {
sect |= ((u64)scsicmd[2]) << 24;
sect |= ((u64)scsicmd[3]) << 16;
sect |= ((u64)scsicmd[4]) << 8;
sect |= ((u64)scsicmd[5]);
n_sect |= ((u32)scsicmd[7]) << 8;
n_sect |= ((u32)scsicmd[8]);
}
else if (scsicmd[0] == VERIFY_16) {
sect |= ((u64)scsicmd[2]) << 56;
sect |= ((u64)scsicmd[3]) << 48;
sect |= ((u64)scsicmd[4]) << 40;
sect |= ((u64)scsicmd[5]) << 32;
sect |= ((u64)scsicmd[6]) << 24;
sect |= ((u64)scsicmd[7]) << 16;
sect |= ((u64)scsicmd[8]) << 8;
sect |= ((u64)scsicmd[9]);
n_sect |= ((u32)scsicmd[10]) << 24;
n_sect |= ((u32)scsicmd[11]) << 16;
n_sect |= ((u32)scsicmd[12]) << 8;
n_sect |= ((u32)scsicmd[13]);
}
if (scsicmd[0] == VERIFY)
scsi_10_lba_len(scsicmd, &block, &n_block);
else if (scsicmd[0] == VERIFY_16)
scsi_16_lba_len(scsicmd, &block, &n_block);
else
return 1;
goto invalid_fld;
if (!n_sect)
return 1;
if (sect >= dev_sectors)
return 1;
if ((sect + n_sect) > dev_sectors)
return 1;
if (!n_block)
goto nothing_to_do;
if (block >= dev_sectors)
goto out_of_range;
if ((block + n_block) > dev_sectors)
goto out_of_range;
if (lba48) {
if (n_sect > (64 * 1024))
return 1;
if (n_block > (64 * 1024))
goto invalid_fld;
} else {
if (n_sect > 256)
return 1;
if (n_block > 256)
goto invalid_fld;
}
if (lba48) {
tf->command = ATA_CMD_VERIFY_EXT;
if (lba) {
if (lba48) {
tf->command = ATA_CMD_VERIFY_EXT;
tf->hob_nsect = (n_sect >> 8) & 0xff;
tf->hob_nsect = (n_block >> 8) & 0xff;
tf->hob_lbah = (sect >> 40) & 0xff;
tf->hob_lbam = (sect >> 32) & 0xff;
tf->hob_lbal = (sect >> 24) & 0xff;
tf->hob_lbah = (block >> 40) & 0xff;
tf->hob_lbam = (block >> 32) & 0xff;
tf->hob_lbal = (block >> 24) & 0xff;
} else {
tf->command = ATA_CMD_VERIFY;
tf->device |= (block >> 24) & 0xf;
}
tf->nsect = n_block & 0xff;
tf->lbah = (block >> 16) & 0xff;
tf->lbam = (block >> 8) & 0xff;
tf->lbal = block & 0xff;
tf->device |= ATA_LBA;
} else {
/* CHS */
u32 sect, head, cyl, track;
/* Convert LBA to CHS */
track = (u32)block / dev->sectors;
cyl = track / dev->heads;
head = track % dev->heads;
sect = (u32)block % dev->sectors + 1;
DPRINTK("block %u track %u cyl %u head %u sect %u\n",
(u32)block, track, cyl, head, sect);
/* Check whether the converted CHS can fit.
Cylinder: 0-65535
Head: 0-15
Sector: 1-255*/
if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect))
goto out_of_range;
tf->command = ATA_CMD_VERIFY;
tf->device |= (sect >> 24) & 0xf;
tf->nsect = n_block & 0xff; /* Sector count 0 means 256 sectors */
tf->lbal = sect;
tf->lbam = cyl;
tf->lbah = cyl >> 8;
tf->device |= head;
}
tf->nsect = n_sect & 0xff;
tf->lbah = (sect >> 16) & 0xff;
tf->lbam = (sect >> 8) & 0xff;
tf->lbal = sect & 0xff;
return 0;
invalid_fld:
ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x0);
/* "Invalid field in cbd" */
return 1;
out_of_range:
ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x21, 0x0);
/* "Logical Block Address out of range" */
return 1;
nothing_to_do:
qc->scsicmd->result = SAM_STAT_GOOD;
return 1;
}
/**
@ -612,11 +742,14 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
{
struct ata_taskfile *tf = &qc->tf;
struct ata_device *dev = qc->dev;
unsigned int lba = tf->flags & ATA_TFLAG_LBA;
unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48;
u64 block;
u32 n_block;
tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
tf->protocol = qc->dev->xfer_protocol;
tf->device |= ATA_LBA;
if (scsicmd[0] == READ_10 || scsicmd[0] == READ_6 ||
scsicmd[0] == READ_16) {
@ -626,89 +759,115 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
tf->flags |= ATA_TFLAG_WRITE;
}
if (scsicmd[0] == READ_10 || scsicmd[0] == WRITE_10) {
/* Calculate the SCSI LBA and transfer length. */
switch (scsicmd[0]) {
case READ_10:
case WRITE_10:
scsi_10_lba_len(scsicmd, &block, &n_block);
break;
case READ_6:
case WRITE_6:
scsi_6_lba_len(scsicmd, &block, &n_block);
/* for 6-byte r/w commands, transfer length 0
* means 256 blocks of data, not 0 block.
*/
if (!n_block)
n_block = 256;
break;
case READ_16:
case WRITE_16:
scsi_16_lba_len(scsicmd, &block, &n_block);
break;
default:
DPRINTK("no-byte command\n");
goto invalid_fld;
}
/* Check and compose ATA command */
if (!n_block)
/* For 10-byte and 16-byte SCSI R/W commands, transfer
* length 0 means transfer 0 block of data.
* However, for ATA R/W commands, sector count 0 means
* 256 or 65536 sectors, not 0 sectors as in SCSI.
*/
goto nothing_to_do;
if (lba) {
if (lba48) {
tf->hob_nsect = scsicmd[7];
tf->hob_lbal = scsicmd[2];
/* The request -may- be too large for LBA48. */
if ((block >> 48) || (n_block > 65536))
goto out_of_range;
qc->nsect = ((unsigned int)scsicmd[7] << 8) |
scsicmd[8];
} else {
/* if we don't support LBA48 addressing, the request
* -may- be too large. */
if ((scsicmd[2] & 0xf0) || scsicmd[7])
return 1;
tf->hob_nsect = (n_block >> 8) & 0xff;
/* stores LBA27:24 in lower 4 bits of device reg */
tf->device |= scsicmd[2];
tf->hob_lbah = (block >> 40) & 0xff;
tf->hob_lbam = (block >> 32) & 0xff;
tf->hob_lbal = (block >> 24) & 0xff;
} else {
/* LBA28 */
qc->nsect = scsicmd[8];
/* The request -may- be too large for LBA28. */
if ((block >> 28) || (n_block > 256))
goto out_of_range;
tf->device |= (block >> 24) & 0xf;
}
tf->nsect = scsicmd[8];
tf->lbal = scsicmd[5];
tf->lbam = scsicmd[4];
tf->lbah = scsicmd[3];
qc->nsect = n_block;
tf->nsect = n_block & 0xff;
VPRINTK("ten-byte command\n");
if (qc->nsect == 0) /* we don't support length==0 cmds */
return 1;
return 0;
tf->lbah = (block >> 16) & 0xff;
tf->lbam = (block >> 8) & 0xff;
tf->lbal = block & 0xff;
tf->device |= ATA_LBA;
} else {
/* CHS */
u32 sect, head, cyl, track;
/* The request -may- be too large for CHS addressing. */
if ((block >> 28) || (n_block > 256))
goto out_of_range;
/* Convert LBA to CHS */
track = (u32)block / dev->sectors;
cyl = track / dev->heads;
head = track % dev->heads;
sect = (u32)block % dev->sectors + 1;
DPRINTK("block %u track %u cyl %u head %u sect %u\n",
(u32)block, track, cyl, head, sect);
/* Check whether the converted CHS can fit.
Cylinder: 0-65535
Head: 0-15
Sector: 1-255*/
if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect))
goto out_of_range;
qc->nsect = n_block;
tf->nsect = n_block & 0xff; /* Sector count 0 means 256 sectors */
tf->lbal = sect;
tf->lbam = cyl;
tf->lbah = cyl >> 8;
tf->device |= head;
}
if (scsicmd[0] == READ_6 || scsicmd[0] == WRITE_6) {
qc->nsect = tf->nsect = scsicmd[4];
if (!qc->nsect) {
qc->nsect = 256;
if (lba48)
tf->hob_nsect = 1;
}
return 0;
tf->lbal = scsicmd[3];
tf->lbam = scsicmd[2];
tf->lbah = scsicmd[1] & 0x1f; /* mask out reserved bits */
invalid_fld:
ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x0);
/* "Invalid field in cbd" */
return 1;
VPRINTK("six-byte command\n");
return 0;
}
out_of_range:
ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x21, 0x0);
/* "Logical Block Address out of range" */
return 1;
if (scsicmd[0] == READ_16 || scsicmd[0] == WRITE_16) {
/* rule out impossible LBAs and sector counts */
if (scsicmd[2] || scsicmd[3] || scsicmd[10] || scsicmd[11])
return 1;
if (lba48) {
tf->hob_nsect = scsicmd[12];
tf->hob_lbal = scsicmd[6];
tf->hob_lbam = scsicmd[5];
tf->hob_lbah = scsicmd[4];
qc->nsect = ((unsigned int)scsicmd[12] << 8) |
scsicmd[13];
} else {
/* once again, filter out impossible non-zero values */
if (scsicmd[4] || scsicmd[5] || scsicmd[12] ||
(scsicmd[6] & 0xf0))
return 1;
/* stores LBA27:24 in lower 4 bits of device reg */
tf->device |= scsicmd[6];
qc->nsect = scsicmd[13];
}
tf->nsect = scsicmd[13];
tf->lbal = scsicmd[9];
tf->lbam = scsicmd[8];
tf->lbah = scsicmd[7];
VPRINTK("sixteen-byte command\n");
if (qc->nsect == 0) /* we don't support length==0 cmds */
return 1;
return 0;
}
DPRINTK("no-byte command\n");
nothing_to_do:
qc->scsicmd->result = SAM_STAT_GOOD;
return 1;
}
@ -741,6 +900,12 @@ static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
* This function sets up an ata_queued_cmd structure for the
* SCSI command, and sends that ata_queued_cmd to the hardware.
*
* The xlat_func argument (actor) returns 0 if ready to execute
* ATA command, else 1 to finish translation. If 1 is returned
* then cmd->result (and possibly cmd->sense_buffer) are assumed
* to be set reflecting an error condition or clean (early)
* termination.
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
*/
@ -757,7 +922,7 @@ static void ata_scsi_translate(struct ata_port *ap, struct ata_device *dev,
qc = ata_scsi_qc_new(ap, dev, cmd, done);
if (!qc)
return;
goto err_mem;
/* data is present; dma-map it */
if (cmd->sc_data_direction == DMA_FROM_DEVICE ||
@ -765,7 +930,7 @@ static void ata_scsi_translate(struct ata_port *ap, struct ata_device *dev,
if (unlikely(cmd->request_bufflen < 1)) {
printk(KERN_WARNING "ata%u(%u): WARNING: zero len r/w req\n",
ap->id, dev->devno);
goto err_out;
goto err_did;
}
if (cmd->use_sg)
@ -780,19 +945,28 @@ static void ata_scsi_translate(struct ata_port *ap, struct ata_device *dev,
qc->complete_fn = ata_scsi_qc_complete;
if (xlat_func(qc, scsicmd))
goto err_out;
goto early_finish;
/* select device, send command to hardware */
if (ata_qc_issue(qc))
goto err_out;
goto err_did;
VPRINTK("EXIT\n");
return;
err_out:
early_finish:
ata_qc_free(qc);
done(cmd);
DPRINTK("EXIT - early finish (good or error)\n");
return;
err_did:
ata_qc_free(qc);
ata_bad_cdb(cmd, done);
DPRINTK("EXIT - badcmd\n");
err_mem:
cmd->result = (DID_ERROR << 16);
done(cmd);
DPRINTK("EXIT - internal\n");
return;
}
/**
@ -859,7 +1033,8 @@ static inline void ata_scsi_rbuf_put(struct scsi_cmnd *cmd, u8 *buf)
* Mapping the response buffer, calling the command's handler,
* and handling the handler's return value. This return value
* indicates whether the handler wishes the SCSI command to be
* completed successfully, or not.
* completed successfully (0), or not (in which case cmd->result
* and sense buffer are assumed to be set).
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
@ -878,12 +1053,9 @@ void ata_scsi_rbuf_fill(struct ata_scsi_args *args,
rc = actor(args, rbuf, buflen);
ata_scsi_rbuf_put(cmd, rbuf);
if (rc)
ata_bad_cdb(cmd, args->done);
else {
if (rc == 0)
cmd->result = SAM_STAT_GOOD;
args->done(cmd);
}
args->done(cmd);
}
/**
@ -1189,8 +1361,16 @@ unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf,
* in the same manner)
*/
page_control = scsicmd[2] >> 6;
if ((page_control != 0) && (page_control != 3))
return 1;
switch (page_control) {
case 0: /* current */
break; /* supported */
case 3: /* saved */
goto saving_not_supp;
case 1: /* changeable */
case 2: /* defaults */
default:
goto invalid_fld;
}
if (six_byte)
output_len = 4;
@ -1221,7 +1401,7 @@ unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf,
break;
default: /* invalid page code */
return 1;
goto invalid_fld;
}
if (six_byte) {
@ -1234,6 +1414,16 @@ unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf,
}
return 0;
invalid_fld:
ata_scsi_set_sense(args->cmd, ILLEGAL_REQUEST, 0x24, 0x0);
/* "Invalid field in cbd" */
return 1;
saving_not_supp:
ata_scsi_set_sense(args->cmd, ILLEGAL_REQUEST, 0x39, 0x0);
/* "Saving parameters not supported" */
return 1;
}
/**
@ -1256,10 +1446,20 @@ unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf,
VPRINTK("ENTER\n");
if (ata_id_has_lba48(args->id))
n_sectors = ata_id_u64(args->id, 100);
else
n_sectors = ata_id_u32(args->id, 60);
if (ata_id_has_lba(args->id)) {
if (ata_id_has_lba48(args->id))
n_sectors = ata_id_u64(args->id, 100);
else
n_sectors = ata_id_u32(args->id, 60);
} else {
/* CHS default translation */
n_sectors = args->id[1] * args->id[3] * args->id[6];
if (ata_id_current_chs_valid(args->id))
/* CHS current translation */
n_sectors = ata_id_u32(args->id, 57);
}
n_sectors--; /* ATA TotalUserSectors - 1 */
if (args->cmd->cmnd[0] == READ_CAPACITY) {
@ -1322,6 +1522,34 @@ unsigned int ata_scsiop_report_luns(struct ata_scsi_args *args, u8 *rbuf,
return 0;
}
/**
* ata_scsi_set_sense - Set SCSI sense data and status
* @cmd: SCSI request to be handled
* @sk: SCSI-defined sense key
* @asc: SCSI-defined additional sense code
* @ascq: SCSI-defined additional sense code qualifier
*
* Helper function that builds a valid fixed format, current
* response code and the given sense key (sk), additional sense
* code (asc) and additional sense code qualifier (ascq) with
* a SCSI command status of %SAM_STAT_CHECK_CONDITION and
* DRIVER_SENSE set in the upper bits of scsi_cmnd::result .
*
* LOCKING:
* Not required
*/
void ata_scsi_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq)
{
cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
cmd->sense_buffer[0] = 0x70; /* fixed format, current */
cmd->sense_buffer[2] = sk;
cmd->sense_buffer[7] = 18 - 8; /* additional sense length */
cmd->sense_buffer[12] = asc;
cmd->sense_buffer[13] = ascq;
}
/**
* ata_scsi_badcmd - End a SCSI request with an error
* @cmd: SCSI request to be handled
@ -1340,30 +1568,84 @@ unsigned int ata_scsiop_report_luns(struct ata_scsi_args *args, u8 *rbuf,
void ata_scsi_badcmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), u8 asc, u8 ascq)
{
DPRINTK("ENTER\n");
cmd->result = SAM_STAT_CHECK_CONDITION;
cmd->sense_buffer[0] = 0x70;
cmd->sense_buffer[2] = ILLEGAL_REQUEST;
cmd->sense_buffer[7] = 14 - 8; /* addnl. sense len. FIXME: correct? */
cmd->sense_buffer[12] = asc;
cmd->sense_buffer[13] = ascq;
ata_scsi_set_sense(cmd, ILLEGAL_REQUEST, asc, ascq);
done(cmd);
}
void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
struct scsi_cmnd *cmd)
{
DECLARE_COMPLETION(wait);
struct ata_queued_cmd *qc;
unsigned long flags;
int rc;
DPRINTK("ATAPI request sense\n");
qc = ata_qc_new_init(ap, dev);
BUG_ON(qc == NULL);
/* FIXME: is this needed? */
memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer));
ata_sg_init_one(qc, cmd->sense_buffer, sizeof(cmd->sense_buffer));
qc->dma_dir = DMA_FROM_DEVICE;
memset(&qc->cdb, 0, ap->cdb_len);
qc->cdb[0] = REQUEST_SENSE;
qc->cdb[4] = SCSI_SENSE_BUFFERSIZE;
qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
qc->tf.command = ATA_CMD_PACKET;
qc->tf.protocol = ATA_PROT_ATAPI;
qc->tf.lbam = (8 * 1024) & 0xff;
qc->tf.lbah = (8 * 1024) >> 8;
qc->nbytes = SCSI_SENSE_BUFFERSIZE;
qc->waiting = &wait;
qc->complete_fn = ata_qc_complete_noop;
spin_lock_irqsave(&ap->host_set->lock, flags);
rc = ata_qc_issue(qc);
spin_unlock_irqrestore(&ap->host_set->lock, flags);
if (rc)
ata_port_disable(ap);
else
wait_for_completion(&wait);
DPRINTK("EXIT\n");
}
static int atapi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
{
struct scsi_cmnd *cmd = qc->scsicmd;
if (unlikely(drv_stat & (ATA_ERR | ATA_BUSY | ATA_DRQ))) {
VPRINTK("ENTER, drv_stat == 0x%x\n", drv_stat);
if (unlikely(drv_stat & (ATA_BUSY | ATA_DRQ)))
ata_to_sense_error(qc, drv_stat);
else if (unlikely(drv_stat & ATA_ERR)) {
DPRINTK("request check condition\n");
/* FIXME: command completion with check condition
* but no sense causes the error handler to run,
* which then issues REQUEST SENSE, fills in the sense
* buffer, and completes the command (for the second
* time). We need to issue REQUEST SENSE some other
* way, to avoid completing the command twice.
*/
cmd->result = SAM_STAT_CHECK_CONDITION;
qc->scsidone(cmd);
return 1;
} else {
}
else {
u8 *scsicmd = cmd->cmnd;
if (scsicmd[0] == INQUIRY) {
@ -1371,15 +1653,30 @@ static int atapi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
unsigned int buflen;
buflen = ata_scsi_rbuf_get(cmd, &buf);
buf[2] = 0x5;
buf[3] = (buf[3] & 0xf0) | 2;
/* ATAPI devices typically report zero for their SCSI version,
* and sometimes deviate from the spec WRT response data
* format. If SCSI version is reported as zero like normal,
* then we make the following fixups: 1) Fake MMC-5 version,
* to indicate to the Linux scsi midlayer this is a modern
* device. 2) Ensure response data format / ATAPI information
* are always correct.
*/
/* FIXME: do we ever override EVPD pages and the like, with
* this code?
*/
if (buf[2] == 0) {
buf[2] = 0x5;
buf[3] = 0x32;
}
ata_scsi_rbuf_put(cmd, buf);
}
cmd->result = SAM_STAT_GOOD;
}
qc->scsidone(cmd);
return 0;
}
/**
@ -1640,7 +1937,7 @@ void ata_scsi_simulate(u16 *id,
case INQUIRY:
if (scsicmd[1] & 2) /* is CmdDt set? */
ata_bad_cdb(cmd, done);
ata_scsi_invalid_field(cmd, done);
else if ((scsicmd[1] & 1) == 0) /* is EVPD clear? */
ata_scsi_rbuf_fill(&args, ata_scsiop_inq_std);
else if (scsicmd[2] == 0x00)
@ -1650,7 +1947,7 @@ void ata_scsi_simulate(u16 *id,
else if (scsicmd[2] == 0x83)
ata_scsi_rbuf_fill(&args, ata_scsiop_inq_83);
else
ata_bad_cdb(cmd, done);
ata_scsi_invalid_field(cmd, done);
break;
case MODE_SENSE:
@ -1660,7 +1957,7 @@ void ata_scsi_simulate(u16 *id,
case MODE_SELECT: /* unconditionally return */
case MODE_SELECT_10: /* bad-field-in-cdb */
ata_bad_cdb(cmd, done);
ata_scsi_invalid_field(cmd, done);
break;
case READ_CAPACITY:
@ -1671,7 +1968,7 @@ void ata_scsi_simulate(u16 *id,
if ((scsicmd[1] & 0x1f) == SAI_READ_CAPACITY_16)
ata_scsi_rbuf_fill(&args, ata_scsiop_read_cap);
else
ata_bad_cdb(cmd, done);
ata_scsi_invalid_field(cmd, done);
break;
case REPORT_LUNS:
@ -1683,8 +1980,26 @@ void ata_scsi_simulate(u16 *id,
/* all other commands */
default:
ata_bad_scsiop(cmd, done);
ata_scsi_set_sense(cmd, ILLEGAL_REQUEST, 0x20, 0x0);
/* "Invalid command operation code" */
done(cmd);
break;
}
}
void ata_scsi_scan_host(struct ata_port *ap)
{
struct ata_device *dev;
unsigned int i;
if (ap->flags & ATA_FLAG_PORT_DISABLED)
return;
for (i = 0; i < ATA_MAX_DEVICES; i++) {
dev = &ap->device[i];
if (ata_dev_present(dev))
scsi_scan_target(&ap->host->shost_gendev, 0, i, 0, 0);
}
}

View File

@ -39,6 +39,7 @@ struct ata_scsi_args {
/* libata-core.c */
extern int atapi_enabled;
extern int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat);
extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
struct ata_device *dev);
extern void ata_qc_free(struct ata_queued_cmd *qc);
@ -51,6 +52,9 @@ extern void swap_buf_le16(u16 *buf, unsigned int buf_words);
/* libata-scsi.c */
extern void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
struct scsi_cmnd *cmd);
extern void ata_scsi_scan_host(struct ata_port *ap);
extern void ata_to_sense_error(struct ata_queued_cmd *qc, u8 drv_stat);
extern int ata_scsi_error(struct Scsi_Host *host);
extern unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf,
@ -76,18 +80,10 @@ extern unsigned int ata_scsiop_report_luns(struct ata_scsi_args *args, u8 *rbuf,
extern void ata_scsi_badcmd(struct scsi_cmnd *cmd,
void (*done)(struct scsi_cmnd *),
u8 asc, u8 ascq);
extern void ata_scsi_set_sense(struct scsi_cmnd *cmd,
u8 sk, u8 asc, u8 ascq);
extern void ata_scsi_rbuf_fill(struct ata_scsi_args *args,
unsigned int (*actor) (struct ata_scsi_args *args,
u8 *rbuf, unsigned int buflen));
static inline void ata_bad_scsiop(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
{
ata_scsi_badcmd(cmd, done, 0x20, 0x00);
}
static inline void ata_bad_cdb(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
{
ata_scsi_badcmd(cmd, done, 0x24, 0x00);
}
#endif /* __LIBATA_H__ */

View File

@ -34,6 +34,7 @@
#include <linux/delay.h>
#include <linux/uio.h>
#include <asm/uaccess.h>
#include <linux/fs.h>
#include <linux/compat.h>
#include <scsi/scsi.h>

File diff suppressed because it is too large Load Diff

View File

@ -29,6 +29,8 @@
* NV-specific details such as register offsets, SATA phy location,
* hotplug info, etc.
*
* 0.09
* - Fixed bug introduced by 0.08's MCP51 and MCP55 support.
*
* 0.08
* - Added support for MCP51 and MCP55.
@ -132,9 +134,7 @@ enum nv_host_type
GENERIC,
NFORCE2,
NFORCE3,
CK804,
MCP51,
MCP55
CK804
};
static struct pci_device_id nv_pci_tbl[] = {
@ -153,13 +153,13 @@ static struct pci_device_id nv_pci_tbl[] = {
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, CK804 },
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, MCP51 },
PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, MCP51 },
PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, MCP55 },
PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, MCP55 },
PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
{ PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
PCI_ANY_ID, PCI_ANY_ID,
PCI_CLASS_STORAGE_IDE<<8, 0xffff00, GENERIC },
@ -405,7 +405,7 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
rc = -ENOMEM;
ppi = &nv_port_info;
probe_ent = ata_pci_init_native_mode(pdev, &ppi);
probe_ent = ata_pci_init_native_mode(pdev, &ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
if (!probe_ent)
goto err_out_regions;

View File

@ -438,11 +438,11 @@ static inline unsigned int pdc_host_intr( struct ata_port *ap,
break;
default:
ap->stats.idle_irq++;
break;
ap->stats.idle_irq++;
break;
}
return handled;
return handled;
}
static void pdc_irq_clear(struct ata_port *ap)

875
drivers/scsi/sata_sil24.c Normal file
View File

@ -0,0 +1,875 @@
/*
* sata_sil24.c - Driver for Silicon Image 3124/3132 SATA-2 controllers
*
* Copyright 2005 Tejun Heo
*
* Based on preview driver from Silicon Image.
*
* NOTE: No NCQ/ATAPI support yet. The preview driver didn't support
* NCQ nor ATAPI, and, unfortunately, I couldn't find out how to make
* those work. Enabling those shouldn't be difficult. Basic
* structure is all there (in libata-dev tree). If you have any
* information about this hardware, please contact me or linux-ide.
* Info is needed on...
*
* - How to issue tagged commands and turn on sactive on issue accordingly.
* - Where to put an ATAPI command and how to tell the device to send it.
* - How to enable/use 64bit.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
#include <scsi/scsi_host.h>
#include "scsi.h"
#include <linux/libata.h>
#include <asm/io.h>
#define DRV_NAME "sata_sil24"
#define DRV_VERSION "0.22" /* Silicon Image's preview driver was 0.10 */
/*
* Port request block (PRB) 32 bytes
*/
struct sil24_prb {
u16 ctrl;
u16 prot;
u32 rx_cnt;
u8 fis[6 * 4];
};
/*
* Scatter gather entry (SGE) 16 bytes
*/
struct sil24_sge {
u64 addr;
u32 cnt;
u32 flags;
};
/*
* Port multiplier
*/
struct sil24_port_multiplier {
u32 diag;
u32 sactive;
};
enum {
/*
* Global controller registers (128 bytes @ BAR0)
*/
/* 32 bit regs */
HOST_SLOT_STAT = 0x00, /* 32 bit slot stat * 4 */
HOST_CTRL = 0x40,
HOST_IRQ_STAT = 0x44,
HOST_PHY_CFG = 0x48,
HOST_BIST_CTRL = 0x50,
HOST_BIST_PTRN = 0x54,
HOST_BIST_STAT = 0x58,
HOST_MEM_BIST_STAT = 0x5c,
HOST_FLASH_CMD = 0x70,
/* 8 bit regs */
HOST_FLASH_DATA = 0x74,
HOST_TRANSITION_DETECT = 0x75,
HOST_GPIO_CTRL = 0x76,
HOST_I2C_ADDR = 0x78, /* 32 bit */
HOST_I2C_DATA = 0x7c,
HOST_I2C_XFER_CNT = 0x7e,
HOST_I2C_CTRL = 0x7f,
/* HOST_SLOT_STAT bits */
HOST_SSTAT_ATTN = (1 << 31),
/*
* Port registers
* (8192 bytes @ +0x0000, +0x2000, +0x4000 and +0x6000 @ BAR2)
*/
PORT_REGS_SIZE = 0x2000,
PORT_PRB = 0x0000, /* (32 bytes PRB + 16 bytes SGEs * 6) * 31 (3968 bytes) */
PORT_PM = 0x0f80, /* 8 bytes PM * 16 (128 bytes) */
/* 32 bit regs */
PORT_CTRL_STAT = 0x1000, /* write: ctrl-set, read: stat */
PORT_CTRL_CLR = 0x1004, /* write: ctrl-clear */
PORT_IRQ_STAT = 0x1008, /* high: status, low: interrupt */
PORT_IRQ_ENABLE_SET = 0x1010, /* write: enable-set */
PORT_IRQ_ENABLE_CLR = 0x1014, /* write: enable-clear */
PORT_ACTIVATE_UPPER_ADDR= 0x101c,
PORT_EXEC_FIFO = 0x1020, /* command execution fifo */
PORT_CMD_ERR = 0x1024, /* command error number */
PORT_FIS_CFG = 0x1028,
PORT_FIFO_THRES = 0x102c,
/* 16 bit regs */
PORT_DECODE_ERR_CNT = 0x1040,
PORT_DECODE_ERR_THRESH = 0x1042,
PORT_CRC_ERR_CNT = 0x1044,
PORT_CRC_ERR_THRESH = 0x1046,
PORT_HSHK_ERR_CNT = 0x1048,
PORT_HSHK_ERR_THRESH = 0x104a,
/* 32 bit regs */
PORT_PHY_CFG = 0x1050,
PORT_SLOT_STAT = 0x1800,
PORT_CMD_ACTIVATE = 0x1c00, /* 64 bit cmd activate * 31 (248 bytes) */
PORT_EXEC_DIAG = 0x1e00, /* 32bit exec diag * 16 (64 bytes, 0-10 used on 3124) */
PORT_PSD_DIAG = 0x1e40, /* 32bit psd diag * 16 (64 bytes, 0-8 used on 3124) */
PORT_SCONTROL = 0x1f00,
PORT_SSTATUS = 0x1f04,
PORT_SERROR = 0x1f08,
PORT_SACTIVE = 0x1f0c,
/* PORT_CTRL_STAT bits */
PORT_CS_PORT_RST = (1 << 0), /* port reset */
PORT_CS_DEV_RST = (1 << 1), /* device reset */
PORT_CS_INIT = (1 << 2), /* port initialize */
PORT_CS_IRQ_WOC = (1 << 3), /* interrupt write one to clear */
PORT_CS_RESUME = (1 << 6), /* port resume */
PORT_CS_32BIT_ACTV = (1 << 10), /* 32-bit activation */
PORT_CS_PM_EN = (1 << 13), /* port multiplier enable */
PORT_CS_RDY = (1 << 31), /* port ready to accept commands */
/* PORT_IRQ_STAT/ENABLE_SET/CLR */
/* bits[11:0] are masked */
PORT_IRQ_COMPLETE = (1 << 0), /* command(s) completed */
PORT_IRQ_ERROR = (1 << 1), /* command execution error */
PORT_IRQ_PORTRDY_CHG = (1 << 2), /* port ready change */
PORT_IRQ_PWR_CHG = (1 << 3), /* power management change */
PORT_IRQ_PHYRDY_CHG = (1 << 4), /* PHY ready change */
PORT_IRQ_COMWAKE = (1 << 5), /* COMWAKE received */
PORT_IRQ_UNK_FIS = (1 << 6), /* Unknown FIS received */
PORT_IRQ_SDB_FIS = (1 << 11), /* SDB FIS received */
/* bits[27:16] are unmasked (raw) */
PORT_IRQ_RAW_SHIFT = 16,
PORT_IRQ_MASKED_MASK = 0x7ff,
PORT_IRQ_RAW_MASK = (0x7ff << PORT_IRQ_RAW_SHIFT),
/* ENABLE_SET/CLR specific, intr steering - 2 bit field */
PORT_IRQ_STEER_SHIFT = 30,
PORT_IRQ_STEER_MASK = (3 << PORT_IRQ_STEER_SHIFT),
/* PORT_CMD_ERR constants */
PORT_CERR_DEV = 1, /* Error bit in D2H Register FIS */
PORT_CERR_SDB = 2, /* Error bit in SDB FIS */
PORT_CERR_DATA = 3, /* Error in data FIS not detected by dev */
PORT_CERR_SEND = 4, /* Initial cmd FIS transmission failure */
PORT_CERR_INCONSISTENT = 5, /* Protocol mismatch */
PORT_CERR_DIRECTION = 6, /* Data direction mismatch */
PORT_CERR_UNDERRUN = 7, /* Ran out of SGEs while writing */
PORT_CERR_OVERRUN = 8, /* Ran out of SGEs while reading */
PORT_CERR_PKT_PROT = 11, /* DIR invalid in 1st PIO setup of ATAPI */
PORT_CERR_SGT_BOUNDARY = 16, /* PLD ecode 00 - SGT not on qword boundary */
PORT_CERR_SGT_TGTABRT = 17, /* PLD ecode 01 - target abort */
PORT_CERR_SGT_MSTABRT = 18, /* PLD ecode 10 - master abort */
PORT_CERR_SGT_PCIPERR = 19, /* PLD ecode 11 - PCI parity err while fetching SGT */
PORT_CERR_CMD_BOUNDARY = 24, /* ctrl[15:13] 001 - PRB not on qword boundary */
PORT_CERR_CMD_TGTABRT = 25, /* ctrl[15:13] 010 - target abort */
PORT_CERR_CMD_MSTABRT = 26, /* ctrl[15:13] 100 - master abort */
PORT_CERR_CMD_PCIPERR = 27, /* ctrl[15:13] 110 - PCI parity err while fetching PRB */
PORT_CERR_XFR_UNDEF = 32, /* PSD ecode 00 - undefined */
PORT_CERR_XFR_TGTABRT = 33, /* PSD ecode 01 - target abort */
PORT_CERR_XFR_MSGABRT = 34, /* PSD ecode 10 - master abort */
PORT_CERR_XFR_PCIPERR = 35, /* PSD ecode 11 - PCI prity err during transfer */
PORT_CERR_SENDSERVICE = 36, /* FIS received while sending service */
/*
* Other constants
*/
SGE_TRM = (1 << 31), /* Last SGE in chain */
PRB_SOFT_RST = (1 << 7), /* Soft reset request (ign BSY?) */
/* board id */
BID_SIL3124 = 0,
BID_SIL3132 = 1,
BID_SIL3131 = 2,
IRQ_STAT_4PORTS = 0xf,
};
struct sil24_cmd_block {
struct sil24_prb prb;
struct sil24_sge sge[LIBATA_MAX_PRD];
};
/*
* ap->private_data
*
* The preview driver always returned 0 for status. We emulate it
* here from the previous interrupt.
*/
struct sil24_port_priv {
struct sil24_cmd_block *cmd_block; /* 32 cmd blocks */
dma_addr_t cmd_block_dma; /* DMA base addr for them */
struct ata_taskfile tf; /* Cached taskfile registers */
};
/* ap->host_set->private_data */
struct sil24_host_priv {
void *host_base; /* global controller control (128 bytes @BAR0) */
void *port_base; /* port registers (4 * 8192 bytes @BAR2) */
};
static u8 sil24_check_status(struct ata_port *ap);
static u8 sil24_check_err(struct ata_port *ap);
static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg);
static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val);
static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
static void sil24_phy_reset(struct ata_port *ap);
static void sil24_qc_prep(struct ata_queued_cmd *qc);
static int sil24_qc_issue(struct ata_queued_cmd *qc);
static void sil24_irq_clear(struct ata_port *ap);
static void sil24_eng_timeout(struct ata_port *ap);
static irqreturn_t sil24_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
static int sil24_port_start(struct ata_port *ap);
static void sil24_port_stop(struct ata_port *ap);
static void sil24_host_stop(struct ata_host_set *host_set);
static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
static struct pci_device_id sil24_pci_tbl[] = {
{ 0x1095, 0x3124, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3124 },
{ 0x1095, 0x3132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3132 },
{ 0x1095, 0x3131, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3131 },
{ 0x1095, 0x3531, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3131 },
{ } /* terminate list */
};
static struct pci_driver sil24_pci_driver = {
.name = DRV_NAME,
.id_table = sil24_pci_tbl,
.probe = sil24_init_one,
.remove = ata_pci_remove_one, /* safe? */
};
static Scsi_Host_Template sil24_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
.max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
.proc_name = DRV_NAME,
.dma_boundary = ATA_DMA_BOUNDARY,
.slave_configure = ata_scsi_slave_config,
.bios_param = ata_std_bios_param,
.ordered_flush = 1, /* NCQ not supported yet */
};
static struct ata_port_operations sil24_ops = {
.port_disable = ata_port_disable,
.check_status = sil24_check_status,
.check_altstatus = sil24_check_status,
.check_err = sil24_check_err,
.dev_select = ata_noop_dev_select,
.tf_read = sil24_tf_read,
.phy_reset = sil24_phy_reset,
.qc_prep = sil24_qc_prep,
.qc_issue = sil24_qc_issue,
.eng_timeout = sil24_eng_timeout,
.irq_handler = sil24_interrupt,
.irq_clear = sil24_irq_clear,
.scr_read = sil24_scr_read,
.scr_write = sil24_scr_write,
.port_start = sil24_port_start,
.port_stop = sil24_port_stop,
.host_stop = sil24_host_stop,
};
/*
* Use bits 30-31 of host_flags to encode available port numbers.
* Current maxium is 4.
*/
#define SIL24_NPORTS2FLAG(nports) ((((unsigned)(nports) - 1) & 0x3) << 30)
#define SIL24_FLAG2NPORTS(flag) ((((flag) >> 30) & 0x3) + 1)
static struct ata_port_info sil24_port_info[] = {
/* sil_3124 */
{
.sht = &sil24_sht,
.host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(4),
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = 0x3f, /* udma0-5 */
.port_ops = &sil24_ops,
},
/* sil_3132 */
{
.sht = &sil24_sht,
.host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(2),
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = 0x3f, /* udma0-5 */
.port_ops = &sil24_ops,
},
/* sil_3131/sil_3531 */
{
.sht = &sil24_sht,
.host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(1),
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = 0x3f, /* udma0-5 */
.port_ops = &sil24_ops,
},
};
static inline void sil24_update_tf(struct ata_port *ap)
{
struct sil24_port_priv *pp = ap->private_data;
void *port = (void *)ap->ioaddr.cmd_addr;
struct sil24_prb *prb = port;
ata_tf_from_fis(prb->fis, &pp->tf);
}
static u8 sil24_check_status(struct ata_port *ap)
{
struct sil24_port_priv *pp = ap->private_data;
return pp->tf.command;
}
static u8 sil24_check_err(struct ata_port *ap)
{
struct sil24_port_priv *pp = ap->private_data;
return pp->tf.feature;
}
static int sil24_scr_map[] = {
[SCR_CONTROL] = 0,
[SCR_STATUS] = 1,
[SCR_ERROR] = 2,
[SCR_ACTIVE] = 3,
};
static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg)
{
void *scr_addr = (void *)ap->ioaddr.scr_addr;
if (sc_reg < ARRAY_SIZE(sil24_scr_map)) {
void *addr;
addr = scr_addr + sil24_scr_map[sc_reg] * 4;
return readl(scr_addr + sil24_scr_map[sc_reg] * 4);
}
return 0xffffffffU;
}
static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val)
{
void *scr_addr = (void *)ap->ioaddr.scr_addr;
if (sc_reg < ARRAY_SIZE(sil24_scr_map)) {
void *addr;
addr = scr_addr + sil24_scr_map[sc_reg] * 4;
writel(val, scr_addr + sil24_scr_map[sc_reg] * 4);
}
}
static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
{
struct sil24_port_priv *pp = ap->private_data;
*tf = pp->tf;
}
static void sil24_phy_reset(struct ata_port *ap)
{
__sata_phy_reset(ap);
/*
* No ATAPI yet. Just unconditionally indicate ATA device.
* If ATAPI device is attached, it will fail ATA_CMD_ID_ATA
* and libata core will ignore the device.
*/
if (!(ap->flags & ATA_FLAG_PORT_DISABLED))
ap->device[0].class = ATA_DEV_ATA;
}
static inline void sil24_fill_sg(struct ata_queued_cmd *qc,
struct sil24_cmd_block *cb)
{
struct scatterlist *sg = qc->sg;
struct sil24_sge *sge = cb->sge;
unsigned i;
for (i = 0; i < qc->n_elem; i++, sg++, sge++) {
sge->addr = cpu_to_le64(sg_dma_address(sg));
sge->cnt = cpu_to_le32(sg_dma_len(sg));
sge->flags = 0;
sge->flags = i < qc->n_elem - 1 ? 0 : cpu_to_le32(SGE_TRM);
}
}
static void sil24_qc_prep(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct sil24_port_priv *pp = ap->private_data;
struct sil24_cmd_block *cb = pp->cmd_block + qc->tag;
struct sil24_prb *prb = &cb->prb;
switch (qc->tf.protocol) {
case ATA_PROT_PIO:
case ATA_PROT_DMA:
case ATA_PROT_NODATA:
break;
default:
/* ATAPI isn't supported yet */
BUG();
}
ata_tf_to_fis(&qc->tf, prb->fis, 0);
if (qc->flags & ATA_QCFLAG_DMAMAP)
sil24_fill_sg(qc, cb);
}
static int sil24_qc_issue(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
void *port = (void *)ap->ioaddr.cmd_addr;
struct sil24_port_priv *pp = ap->private_data;
dma_addr_t paddr = pp->cmd_block_dma + qc->tag * sizeof(*pp->cmd_block);
writel((u32)paddr, port + PORT_CMD_ACTIVATE);
return 0;
}
static void sil24_irq_clear(struct ata_port *ap)
{
/* unused */
}
static int __sil24_reset_controller(void *port)
{
int cnt;
u32 tmp;
/* Reset controller state. Is this correct? */
writel(PORT_CS_DEV_RST, port + PORT_CTRL_STAT);
readl(port + PORT_CTRL_STAT); /* sync */
/* Max ~100ms */
for (cnt = 0; cnt < 1000; cnt++) {
udelay(100);
tmp = readl(port + PORT_CTRL_STAT);
if (!(tmp & PORT_CS_DEV_RST))
break;
}
if (tmp & PORT_CS_DEV_RST)
return -1;
return 0;
}
static void sil24_reset_controller(struct ata_port *ap)
{
printk(KERN_NOTICE DRV_NAME
" ata%u: resetting controller...\n", ap->id);
if (__sil24_reset_controller((void *)ap->ioaddr.cmd_addr))
printk(KERN_ERR DRV_NAME
" ata%u: failed to reset controller\n", ap->id);
}
static void sil24_eng_timeout(struct ata_port *ap)
{
struct ata_queued_cmd *qc;
qc = ata_qc_from_tag(ap, ap->active_tag);
if (!qc) {
printk(KERN_ERR "ata%u: BUG: tiemout without command\n",
ap->id);
return;
}
/*
* hack alert! We cannot use the supplied completion
* function from inside the ->eh_strategy_handler() thread.
* libata is the only user of ->eh_strategy_handler() in
* any kernel, so the default scsi_done() assumes it is
* not being called from the SCSI EH.
*/
printk(KERN_ERR "ata%u: command timeout\n", ap->id);
qc->scsidone = scsi_finish_command;
ata_qc_complete(qc, ATA_ERR);
sil24_reset_controller(ap);
}
static void sil24_error_intr(struct ata_port *ap, u32 slot_stat)
{
struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag);
struct sil24_port_priv *pp = ap->private_data;
void *port = (void *)ap->ioaddr.cmd_addr;
u32 irq_stat, cmd_err, sstatus, serror;
irq_stat = readl(port + PORT_IRQ_STAT);
writel(irq_stat, port + PORT_IRQ_STAT); /* clear irq */
if (!(irq_stat & PORT_IRQ_ERROR)) {
/* ignore non-completion, non-error irqs for now */
printk(KERN_WARNING DRV_NAME
"ata%u: non-error exception irq (irq_stat %x)\n",
ap->id, irq_stat);
return;
}
cmd_err = readl(port + PORT_CMD_ERR);
sstatus = readl(port + PORT_SSTATUS);
serror = readl(port + PORT_SERROR);
if (serror)
writel(serror, port + PORT_SERROR);
printk(KERN_ERR DRV_NAME " ata%u: error interrupt on port%d\n"
" stat=0x%x irq=0x%x cmd_err=%d sstatus=0x%x serror=0x%x\n",
ap->id, ap->port_no, slot_stat, irq_stat, cmd_err, sstatus, serror);
if (cmd_err == PORT_CERR_DEV || cmd_err == PORT_CERR_SDB) {
/*
* Device is reporting error, tf registers are valid.
*/
sil24_update_tf(ap);
} else {
/*
* Other errors. libata currently doesn't have any
* mechanism to report these errors. Just turn on
* ATA_ERR.
*/
pp->tf.command = ATA_ERR;
}
if (qc)
ata_qc_complete(qc, pp->tf.command);
sil24_reset_controller(ap);
}
static inline void sil24_host_intr(struct ata_port *ap)
{
struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag);
void *port = (void *)ap->ioaddr.cmd_addr;
u32 slot_stat;
slot_stat = readl(port + PORT_SLOT_STAT);
if (!(slot_stat & HOST_SSTAT_ATTN)) {
struct sil24_port_priv *pp = ap->private_data;
/*
* !HOST_SSAT_ATTN guarantees successful completion,
* so reading back tf registers is unnecessary for
* most commands. TODO: read tf registers for
* commands which require these values on successful
* completion (EXECUTE DEVICE DIAGNOSTIC, CHECK POWER,
* DEVICE RESET and READ PORT MULTIPLIER (any more?).
*/
sil24_update_tf(ap);
if (qc)
ata_qc_complete(qc, pp->tf.command);
} else
sil24_error_intr(ap, slot_stat);
}
static irqreturn_t sil24_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
{
struct ata_host_set *host_set = dev_instance;
struct sil24_host_priv *hpriv = host_set->private_data;
unsigned handled = 0;
u32 status;
int i;
status = readl(hpriv->host_base + HOST_IRQ_STAT);
if (status == 0xffffffff) {
printk(KERN_ERR DRV_NAME ": IRQ status == 0xffffffff, "
"PCI fault or device removal?\n");
goto out;
}
if (!(status & IRQ_STAT_4PORTS))
goto out;
spin_lock(&host_set->lock);
for (i = 0; i < host_set->n_ports; i++)
if (status & (1 << i)) {
struct ata_port *ap = host_set->ports[i];
if (ap && !(ap->flags & ATA_FLAG_PORT_DISABLED)) {
sil24_host_intr(host_set->ports[i]);
handled++;
} else
printk(KERN_ERR DRV_NAME
": interrupt from disabled port %d\n", i);
}
spin_unlock(&host_set->lock);
out:
return IRQ_RETVAL(handled);
}
static int sil24_port_start(struct ata_port *ap)
{
struct device *dev = ap->host_set->dev;
struct sil24_port_priv *pp;
struct sil24_cmd_block *cb;
size_t cb_size = sizeof(*cb);
dma_addr_t cb_dma;
pp = kmalloc(sizeof(*pp), GFP_KERNEL);
if (!pp)
return -ENOMEM;
memset(pp, 0, sizeof(*pp));
pp->tf.command = ATA_DRDY;
cb = dma_alloc_coherent(dev, cb_size, &cb_dma, GFP_KERNEL);
if (!cb) {
kfree(pp);
return -ENOMEM;
}
memset(cb, 0, cb_size);
pp->cmd_block = cb;
pp->cmd_block_dma = cb_dma;
ap->private_data = pp;
return 0;
}
static void sil24_port_stop(struct ata_port *ap)
{
struct device *dev = ap->host_set->dev;
struct sil24_port_priv *pp = ap->private_data;
size_t cb_size = sizeof(*pp->cmd_block);
dma_free_coherent(dev, cb_size, pp->cmd_block, pp->cmd_block_dma);
kfree(pp);
}
static void sil24_host_stop(struct ata_host_set *host_set)
{
struct sil24_host_priv *hpriv = host_set->private_data;
iounmap(hpriv->host_base);
iounmap(hpriv->port_base);
kfree(hpriv);
}
static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version = 0;
unsigned int board_id = (unsigned int)ent->driver_data;
struct ata_port_info *pinfo = &sil24_port_info[board_id];
struct ata_probe_ent *probe_ent = NULL;
struct sil24_host_priv *hpriv = NULL;
void *host_base = NULL, *port_base = NULL;
int i, rc;
if (!printed_version++)
printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
rc = pci_enable_device(pdev);
if (rc)
return rc;
rc = pci_request_regions(pdev, DRV_NAME);
if (rc)
goto out_disable;
rc = -ENOMEM;
/* ioremap mmio registers */
host_base = ioremap(pci_resource_start(pdev, 0),
pci_resource_len(pdev, 0));
if (!host_base)
goto out_free;
port_base = ioremap(pci_resource_start(pdev, 2),
pci_resource_len(pdev, 2));
if (!port_base)
goto out_free;
/* allocate & init probe_ent and hpriv */
probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
if (!probe_ent)
goto out_free;
hpriv = kmalloc(sizeof(*hpriv), GFP_KERNEL);
if (!hpriv)
goto out_free;
memset(probe_ent, 0, sizeof(*probe_ent));
probe_ent->dev = pci_dev_to_dev(pdev);
INIT_LIST_HEAD(&probe_ent->node);
probe_ent->sht = pinfo->sht;
probe_ent->host_flags = pinfo->host_flags;
probe_ent->pio_mask = pinfo->pio_mask;
probe_ent->udma_mask = pinfo->udma_mask;
probe_ent->port_ops = pinfo->port_ops;
probe_ent->n_ports = SIL24_FLAG2NPORTS(pinfo->host_flags);
probe_ent->irq = pdev->irq;
probe_ent->irq_flags = SA_SHIRQ;
probe_ent->mmio_base = port_base;
probe_ent->private_data = hpriv;
memset(hpriv, 0, sizeof(*hpriv));
hpriv->host_base = host_base;
hpriv->port_base = port_base;
/*
* Configure the device
*/
/*
* FIXME: This device is certainly 64-bit capable. We just
* don't know how to use it. After fixing 32bit activation in
* this function, enable 64bit masks here.
*/
rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
if (rc) {
printk(KERN_ERR DRV_NAME "(%s): 32-bit DMA enable failed\n",
pci_name(pdev));
goto out_free;
}
rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
if (rc) {
printk(KERN_ERR DRV_NAME "(%s): 32-bit consistent DMA enable failed\n",
pci_name(pdev));
goto out_free;
}
/* GPIO off */
writel(0, host_base + HOST_FLASH_CMD);
/* Mask interrupts during initialization */
writel(0, host_base + HOST_CTRL);
for (i = 0; i < probe_ent->n_ports; i++) {
void *port = port_base + i * PORT_REGS_SIZE;
unsigned long portu = (unsigned long)port;
u32 tmp;
int cnt;
probe_ent->port[i].cmd_addr = portu + PORT_PRB;
probe_ent->port[i].scr_addr = portu + PORT_SCONTROL;
ata_std_ports(&probe_ent->port[i]);
/* Initial PHY setting */
writel(0x20c, port + PORT_PHY_CFG);
/* Clear port RST */
tmp = readl(port + PORT_CTRL_STAT);
if (tmp & PORT_CS_PORT_RST) {
writel(PORT_CS_PORT_RST, port + PORT_CTRL_CLR);
readl(port + PORT_CTRL_STAT); /* sync */
for (cnt = 0; cnt < 10; cnt++) {
msleep(10);
tmp = readl(port + PORT_CTRL_STAT);
if (!(tmp & PORT_CS_PORT_RST))
break;
}
if (tmp & PORT_CS_PORT_RST)
printk(KERN_ERR DRV_NAME
"(%s): failed to clear port RST\n",
pci_name(pdev));
}
/* Zero error counters. */
writel(0x8000, port + PORT_DECODE_ERR_THRESH);
writel(0x8000, port + PORT_CRC_ERR_THRESH);
writel(0x8000, port + PORT_HSHK_ERR_THRESH);
writel(0x0000, port + PORT_DECODE_ERR_CNT);
writel(0x0000, port + PORT_CRC_ERR_CNT);
writel(0x0000, port + PORT_HSHK_ERR_CNT);
/* FIXME: 32bit activation? */
writel(0, port + PORT_ACTIVATE_UPPER_ADDR);
writel(PORT_CS_32BIT_ACTV, port + PORT_CTRL_STAT);
/* Configure interrupts */
writel(0xffff, port + PORT_IRQ_ENABLE_CLR);
writel(PORT_IRQ_COMPLETE | PORT_IRQ_ERROR | PORT_IRQ_SDB_FIS,
port + PORT_IRQ_ENABLE_SET);
/* Clear interrupts */
writel(0x0fff0fff, port + PORT_IRQ_STAT);
writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_CLR);
/* Clear port multiplier enable and resume bits */
writel(PORT_CS_PM_EN | PORT_CS_RESUME, port + PORT_CTRL_CLR);
/* Reset itself */
if (__sil24_reset_controller(port))
printk(KERN_ERR DRV_NAME
"(%s): failed to reset controller\n",
pci_name(pdev));
}
/* Turn on interrupts */
writel(IRQ_STAT_4PORTS, host_base + HOST_CTRL);
pci_set_master(pdev);
/* FIXME: check ata_device_add return value */
ata_device_add(probe_ent);
kfree(probe_ent);
return 0;
out_free:
if (host_base)
iounmap(host_base);
if (port_base)
iounmap(port_base);
kfree(probe_ent);
kfree(hpriv);
pci_release_regions(pdev);
out_disable:
pci_disable_device(pdev);
return rc;
}
static int __init sil24_init(void)
{
return pci_module_init(&sil24_pci_driver);
}
static void __exit sil24_exit(void)
{
pci_unregister_driver(&sil24_pci_driver);
}
MODULE_AUTHOR("Tejun Heo");
MODULE_DESCRIPTION("Silicon Image 3124/3132 SATA low-level driver");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, sil24_pci_tbl);
module_init(sil24_init);
module_exit(sil24_exit);

View File

@ -263,7 +263,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_out_regions;
ppi = &sis_port_info;
probe_ent = ata_pci_init_native_mode(pdev, &ppi);
probe_ent = ata_pci_init_native_mode(pdev, &ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
if (!probe_ent) {
rc = -ENOMEM;
goto err_out_regions;

View File

@ -202,7 +202,7 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_out_regions;
ppi = &uli_port_info;
probe_ent = ata_pci_init_native_mode(pdev, &ppi);
probe_ent = ata_pci_init_native_mode(pdev, &ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
if (!probe_ent) {
rc = -ENOMEM;
goto err_out_regions;

View File

@ -212,7 +212,7 @@ static struct ata_probe_ent *vt6420_init_probe_ent(struct pci_dev *pdev)
struct ata_probe_ent *probe_ent;
struct ata_port_info *ppi = &svia_port_info;
probe_ent = ata_pci_init_native_mode(pdev, &ppi);
probe_ent = ata_pci_init_native_mode(pdev, &ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
if (!probe_ent)
return NULL;

View File

@ -518,11 +518,7 @@ static void sunsu_change_mouse_baud(struct uart_sunsu_port *up)
quot = up->port.uartclk / (16 * new_baud);
spin_unlock(&up->port.lock);
sunsu_change_speed(&up->port, up->cflag, 0, quot);
spin_lock(&up->port.lock);
}
static void receive_kbd_ms_chars(struct uart_sunsu_port *up, struct pt_regs *regs, int is_break)

View File

@ -108,7 +108,7 @@ static int bfs_create(struct inode * dir, struct dentry * dentry, int mode,
inode->i_mapping->a_ops = &bfs_aops;
inode->i_mode = mode;
inode->i_ino = ino;
BFS_I(inode)->i_dsk_ino = cpu_to_le16(ino);
BFS_I(inode)->i_dsk_ino = ino;
BFS_I(inode)->i_sblock = 0;
BFS_I(inode)->i_eblock = 0;
insert_inode_hash(inode);

View File

@ -357,28 +357,46 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
}
info->si_blocks = (le32_to_cpu(bfs_sb->s_end) + 1)>>BFS_BSIZE_BITS; /* for statfs(2) */
info->si_freeb = (le32_to_cpu(bfs_sb->s_end) + 1 - cpu_to_le32(bfs_sb->s_start))>>BFS_BSIZE_BITS;
info->si_freeb = (le32_to_cpu(bfs_sb->s_end) + 1 - le32_to_cpu(bfs_sb->s_start))>>BFS_BSIZE_BITS;
info->si_freei = 0;
info->si_lf_eblk = 0;
info->si_lf_sblk = 0;
info->si_lf_ioff = 0;
bh = NULL;
for (i=BFS_ROOT_INO; i<=info->si_lasti; i++) {
inode = iget(s,i);
if (BFS_I(inode)->i_dsk_ino == 0)
info->si_freei++;
else {
set_bit(i, info->si_imap);
info->si_freeb -= inode->i_blocks;
if (BFS_I(inode)->i_eblock > info->si_lf_eblk) {
info->si_lf_eblk = BFS_I(inode)->i_eblock;
info->si_lf_sblk = BFS_I(inode)->i_sblock;
info->si_lf_ioff = BFS_INO2OFF(i);
}
struct bfs_inode *di;
int block = (i - BFS_ROOT_INO)/BFS_INODES_PER_BLOCK + 1;
int off = (i - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK;
unsigned long sblock, eblock;
if (!off) {
brelse(bh);
bh = sb_bread(s, block);
}
if (!bh)
continue;
di = (struct bfs_inode *)bh->b_data + off;
if (!di->i_ino) {
info->si_freei++;
continue;
}
set_bit(i, info->si_imap);
info->si_freeb -= BFS_FILEBLOCKS(di);
sblock = le32_to_cpu(di->i_sblock);
eblock = le32_to_cpu(di->i_eblock);
if (eblock > info->si_lf_eblk) {
info->si_lf_eblk = eblock;
info->si_lf_sblk = sblock;
info->si_lf_ioff = BFS_INO2OFF(i);
}
iput(inode);
}
brelse(bh);
if (!(s->s_flags & MS_RDONLY)) {
mark_buffer_dirty(bh);
mark_buffer_dirty(info->si_sbh);
s->s_dirt = 1;
}
dump_imap("read_super", s);

View File

@ -1551,19 +1551,19 @@ do_link:
if (nd->last_type != LAST_NORM)
goto exit;
if (nd->last.name[nd->last.len]) {
putname(nd->last.name);
__putname(nd->last.name);
goto exit;
}
error = -ELOOP;
if (count++==32) {
putname(nd->last.name);
__putname(nd->last.name);
goto exit;
}
dir = nd->dentry;
down(&dir->d_inode->i_sem);
path.dentry = __lookup_hash(&nd->last, nd->dentry, nd);
path.mnt = nd->mnt;
putname(nd->last.name);
__putname(nd->last.name);
goto do_last;
}

View File

@ -102,6 +102,9 @@ ToDo/Notes:
inode instead of a vfs inode as parameter.
- Fix the definition of the CHKD ntfs record magic. It had an off by
two error causing it to be CHKB instead of CHKD.
- Fix a stupid bug in __ntfs_bitmap_set_bits_in_run() which caused the
count to become negative and hence we had a wild memset() scribbling
all over the system's ram.
2.1.23 - Implement extension of resident files and make writing safe as well as
many bug fixes, cleanups, and enhancements...

View File

@ -1,7 +1,7 @@
/*
* bitmap.c - NTFS kernel bitmap handling. Part of the Linux-NTFS project.
*
* Copyright (c) 2004 Anton Altaparmakov
* Copyright (c) 2004-2005 Anton Altaparmakov
*
* This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
@ -90,7 +90,8 @@ int __ntfs_bitmap_set_bits_in_run(struct inode *vi, const s64 start_bit,
/* If the first byte is partial, modify the appropriate bits in it. */
if (bit) {
u8 *byte = kaddr + pos;
while ((bit & 7) && cnt--) {
while ((bit & 7) && cnt) {
cnt--;
if (value)
*byte |= 1 << bit++;
else

View File

@ -309,7 +309,7 @@ typedef le16 MFT_RECORD_FLAGS;
* Note: The _LE versions will return a CPU endian formatted value!
*/
#define MFT_REF_MASK_CPU 0x0000ffffffffffffULL
#define MFT_REF_MASK_LE const_cpu_to_le64(0x0000ffffffffffffULL)
#define MFT_REF_MASK_LE const_cpu_to_le64(MFT_REF_MASK_CPU)
typedef u64 MFT_REF;
typedef le64 leMFT_REF;

View File

@ -58,7 +58,8 @@ static inline MFT_RECORD *map_mft_record_page(ntfs_inode *ni)
* overflowing the unsigned long, but I don't think we would ever get
* here if the volume was that big...
*/
index = ni->mft_no << vol->mft_record_size_bits >> PAGE_CACHE_SHIFT;
index = (u64)ni->mft_no << vol->mft_record_size_bits >>
PAGE_CACHE_SHIFT;
ofs = (ni->mft_no << vol->mft_record_size_bits) & ~PAGE_CACHE_MASK;
i_size = i_size_read(mft_vi);

View File

@ -1,7 +1,7 @@
/*
* unistr.c - NTFS Unicode string handling. Part of the Linux-NTFS project.
*
* Copyright (c) 2001-2004 Anton Altaparmakov
* Copyright (c) 2001-2005 Anton Altaparmakov
*
* This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published

View File

@ -17,9 +17,11 @@
static void arch_idle(void)
{
CPU_REG (PMU_BASE, PMU_MODE) = PMU_MODE_IDLE;
__asm__ __volatile__(
"mov r0, r0\n\t"
"mov r0, r0");
nop();
nop();
CPU_REG (PMU_BASE, PMU_MODE) = PMU_MODE_RUN;
nop();
nop();
}

View File

@ -76,6 +76,7 @@
#define GPIO_PIN_MASK 0x1f
#define GPIO_PORT_MASK (0x3 << 5)
#define GPIO_PORT_SHIFT 5
#define GPIO_PORTA (0<<5)
#define GPIO_PORTB (1<<5)
#define GPIO_PORTC (2<<5)
@ -88,24 +89,37 @@
#define GPIO_PF (0<<9)
#define GPIO_AF (1<<9)
#define GPIO_OCR_SHIFT 10
#define GPIO_OCR_MASK (3<<10)
#define GPIO_AIN (0<<10)
#define GPIO_BIN (1<<10)
#define GPIO_CIN (2<<10)
#define GPIO_GPIO (3<<10)
#define GPIO_DR (3<<10)
#define GPIO_AOUT (1<<12)
#define GPIO_BOUT (1<<13)
#define GPIO_AOUT_SHIFT 12
#define GPIO_AOUT_MASK (3<<12)
#define GPIO_AOUT (0<<12)
#define GPIO_AOUT_ISR (1<<12)
#define GPIO_AOUT_0 (2<<12)
#define GPIO_AOUT_1 (3<<12)
#define GPIO_BOUT_SHIFT 14
#define GPIO_BOUT_MASK (3<<14)
#define GPIO_BOUT (0<<14)
#define GPIO_BOUT_ISR (1<<14)
#define GPIO_BOUT_0 (2<<14)
#define GPIO_BOUT_1 (3<<14)
#define GPIO_GIUS (1<<16)
/* assignements for GPIO alternate/primary functions */
/* FIXME: This list is not completed. The correct directions are
* missing on some (many) pins
*/
#define PA0_PF_A24 ( GPIO_PORTA | GPIO_PF | 0 )
#define PA0_AIN_SPI2_CLK ( GPIO_PORTA | GPIO_OUT | GPIO_AIN | 0 )
#define PA0_AIN_SPI2_CLK ( GPIO_GIUS | GPIO_PORTA | GPIO_OUT | 0 )
#define PA0_AF_ETMTRACESYNC ( GPIO_PORTA | GPIO_AF | 0 )
#define PA1_AOUT_SPI2_RXD ( GPIO_PORTA | GPIO_IN | GPIO_AOUT | 1 )
#define PA1_AOUT_SPI2_RXD ( GPIO_GIUS | GPIO_PORTA | GPIO_IN | 1 )
#define PA1_PF_TIN ( GPIO_PORTA | GPIO_PF | 1 )
#define PA2_PF_PWM0 ( GPIO_PORTA | GPIO_OUT | GPIO_PF | 2 )
#define PA3_PF_CSI_MCLK ( GPIO_PORTA | GPIO_PF | 3 )
@ -123,7 +137,7 @@
#define PA15_PF_I2C_SDA ( GPIO_PORTA | GPIO_OUT | GPIO_PF | 15 )
#define PA16_PF_I2C_SCL ( GPIO_PORTA | GPIO_OUT | GPIO_PF | 16 )
#define PA17_AF_ETMTRACEPKT4 ( GPIO_PORTA | GPIO_AF | 17 )
#define PA17_AIN_SPI2_SS ( GPIO_PORTA | GPIO_AIN | 17 )
#define PA17_AIN_SPI2_SS ( GPIO_GIUS | GPIO_PORTA | GPIO_OUT | 17 )
#define PA18_AF_ETMTRACEPKT5 ( GPIO_PORTA | GPIO_AF | 18 )
#define PA19_AF_ETMTRACEPKT6 ( GPIO_PORTA | GPIO_AF | 19 )
#define PA20_AF_ETMTRACEPKT7 ( GPIO_PORTA | GPIO_AF | 20 )
@ -191,19 +205,27 @@
#define PC15_PF_SPI1_SS ( GPIO_PORTC | GPIO_PF | 15 )
#define PC16_PF_SPI1_MISO ( GPIO_PORTC | GPIO_PF | 16 )
#define PC17_PF_SPI1_MOSI ( GPIO_PORTC | GPIO_PF | 17 )
#define PC24_BIN_UART3_RI ( GPIO_GIUS | GPIO_PORTC | GPIO_OUT | GPIO_BIN | 24 )
#define PC25_BIN_UART3_DSR ( GPIO_GIUS | GPIO_PORTC | GPIO_OUT | GPIO_BIN | 25 )
#define PC26_AOUT_UART3_DTR ( GPIO_GIUS | GPIO_PORTC | GPIO_IN | 26 )
#define PC27_BIN_UART3_DCD ( GPIO_GIUS | GPIO_PORTC | GPIO_OUT | GPIO_BIN | 27 )
#define PC28_BIN_UART3_CTS ( GPIO_GIUS | GPIO_PORTC | GPIO_OUT | GPIO_BIN | 28 )
#define PC29_AOUT_UART3_RTS ( GPIO_GIUS | GPIO_PORTC | GPIO_IN | 29 )
#define PC30_BIN_UART3_TX ( GPIO_GIUS | GPIO_PORTC | GPIO_BIN | 30 )
#define PC31_AOUT_UART3_RX ( GPIO_GIUS | GPIO_PORTC | GPIO_IN | 31)
#define PD6_PF_LSCLK ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 6 )
#define PD7_PF_REV ( GPIO_PORTD | GPIO_PF | 7 )
#define PD7_AF_UART2_DTR ( GPIO_PORTD | GPIO_IN | GPIO_AF | 7 )
#define PD7_AIN_SPI2_SCLK ( GPIO_PORTD | GPIO_AIN | 7 )
#define PD7_AIN_SPI2_SCLK ( GPIO_GIUS | GPIO_PORTD | GPIO_AIN | 7 )
#define PD8_PF_CLS ( GPIO_PORTD | GPIO_PF | 8 )
#define PD8_AF_UART2_DCD ( GPIO_PORTD | GPIO_OUT | GPIO_AF | 8 )
#define PD8_AIN_SPI2_SS ( GPIO_PORTD | GPIO_AIN | 8 )
#define PD8_AIN_SPI2_SS ( GPIO_GIUS | GPIO_PORTD | GPIO_AIN | 8 )
#define PD9_PF_PS ( GPIO_PORTD | GPIO_PF | 9 )
#define PD9_AF_UART2_RI ( GPIO_PORTD | GPIO_OUT | GPIO_AF | 9 )
#define PD9_AOUT_SPI2_RXD ( GPIO_PORTD | GPIO_IN | GPIO_AOUT | 9 )
#define PD9_AOUT_SPI2_RXD ( GPIO_GIUS | GPIO_PORTD | GPIO_IN | 9 )
#define PD10_PF_SPL_SPR ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 10 )
#define PD10_AF_UART2_DSR ( GPIO_PORTD | GPIO_OUT | GPIO_AF | 10 )
#define PD10_AIN_SPI2_TXD ( GPIO_PORTD | GPIO_OUT | GPIO_AIN | 10 )
#define PD10_AIN_SPI2_TXD ( GPIO_GIUS | GPIO_PORTD | GPIO_OUT | 10 )
#define PD11_PF_CONTRAST ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 11 )
#define PD12_PF_ACD_OE ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 12 )
#define PD13_PF_LP_HSYNC ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 13 )
@ -225,7 +247,7 @@
#define PD29_PF_LD14 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 29 )
#define PD30_PF_LD15 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 30 )
#define PD31_PF_TMR2OUT ( GPIO_PORTD | GPIO_PF | 31 )
#define PD31_BIN_SPI2_TXD ( GPIO_PORTD | GPIO_BIN | 31 )
#define PD31_BIN_SPI2_TXD ( GPIO_GIUS | GPIO_PORTD | GPIO_BIN | 31 )
/*
* PWM controller

View File

@ -93,7 +93,7 @@ extern struct pci_bus *ixp4xx_scan_bus(int nr, struct pci_sys_data *sys);
static inline void gpio_line_config(u8 line, u32 direction)
{
if (direction == IXP4XX_GPIO_OUT)
if (direction == IXP4XX_GPIO_IN)
*IXP4XX_GPIO_GPOER |= (1 << line);
else
*IXP4XX_GPIO_GPOER &= ~(1 << line);

View File

@ -49,17 +49,17 @@ extern unsigned int ___illegal_use_of_BTFIXUP_INT_in_module(void);
/* Put bottom 13bits into some register variable */
#define BTFIXUPDEF_SIMM13(__name) \
extern unsigned int ___sf_##__name(void) __attribute_const__; \
static inline unsigned int ___sf_##__name(void) __attribute_const__; \
extern unsigned ___ss_##__name[2]; \
extern __inline__ unsigned int ___sf_##__name(void) { \
static inline unsigned int ___sf_##__name(void) { \
unsigned int ret; \
__asm__ ("or %%g0, ___s_" #__name ", %0" : "=r"(ret)); \
return ret; \
}
#define BTFIXUPDEF_SIMM13_INIT(__name,__val) \
extern unsigned int ___sf_##__name(void) __attribute_const__; \
static inline unsigned int ___sf_##__name(void) __attribute_const__; \
extern unsigned ___ss_##__name[2]; \
extern __inline__ unsigned int ___sf_##__name(void) { \
static inline unsigned int ___sf_##__name(void) { \
unsigned int ret; \
__asm__ ("or %%g0, ___s_" #__name "__btset_" #__val ", %0" : "=r"(ret));\
return ret; \
@ -71,17 +71,17 @@ extern unsigned int ___illegal_use_of_BTFIXUP_INT_in_module(void);
*/
#define BTFIXUPDEF_HALF(__name) \
extern unsigned int ___af_##__name(void) __attribute_const__; \
static inline unsigned int ___af_##__name(void) __attribute_const__; \
extern unsigned ___as_##__name[2]; \
extern __inline__ unsigned int ___af_##__name(void) { \
static inline unsigned int ___af_##__name(void) { \
unsigned int ret; \
__asm__ ("or %%g0, ___a_" #__name ", %0" : "=r"(ret)); \
return ret; \
}
#define BTFIXUPDEF_HALF_INIT(__name,__val) \
extern unsigned int ___af_##__name(void) __attribute_const__; \
static inline unsigned int ___af_##__name(void) __attribute_const__; \
extern unsigned ___as_##__name[2]; \
extern __inline__ unsigned int ___af_##__name(void) { \
static inline unsigned int ___af_##__name(void) { \
unsigned int ret; \
__asm__ ("or %%g0, ___a_" #__name "__btset_" #__val ", %0" : "=r"(ret));\
return ret; \
@ -90,17 +90,17 @@ extern unsigned int ___illegal_use_of_BTFIXUP_INT_in_module(void);
/* Put upper 22 bits into some register variable */
#define BTFIXUPDEF_SETHI(__name) \
extern unsigned int ___hf_##__name(void) __attribute_const__; \
static inline unsigned int ___hf_##__name(void) __attribute_const__; \
extern unsigned ___hs_##__name[2]; \
extern __inline__ unsigned int ___hf_##__name(void) { \
static inline unsigned int ___hf_##__name(void) { \
unsigned int ret; \
__asm__ ("sethi %%hi(___h_" #__name "), %0" : "=r"(ret)); \
return ret; \
}
#define BTFIXUPDEF_SETHI_INIT(__name,__val) \
extern unsigned int ___hf_##__name(void) __attribute_const__; \
static inline unsigned int ___hf_##__name(void) __attribute_const__; \
extern unsigned ___hs_##__name[2]; \
extern __inline__ unsigned int ___hf_##__name(void) { \
static inline unsigned int ___hf_##__name(void) { \
unsigned int ret; \
__asm__ ("sethi %%hi(___h_" #__name "__btset_" #__val "), %0" : \
"=r"(ret)); \

View File

@ -27,7 +27,7 @@
*/
/* First, cache-tag access. */
extern __inline__ unsigned int get_icache_tag(int setnum, int tagnum)
static inline unsigned int get_icache_tag(int setnum, int tagnum)
{
unsigned int vaddr, retval;
@ -38,7 +38,7 @@ extern __inline__ unsigned int get_icache_tag(int setnum, int tagnum)
return retval;
}
extern __inline__ void put_icache_tag(int setnum, int tagnum, unsigned int entry)
static inline void put_icache_tag(int setnum, int tagnum, unsigned int entry)
{
unsigned int vaddr;
@ -51,7 +51,7 @@ extern __inline__ void put_icache_tag(int setnum, int tagnum, unsigned int entry
/* Second cache-data access. The data is returned two-32bit quantities
* at a time.
*/
extern __inline__ void get_icache_data(int setnum, int tagnum, int subblock,
static inline void get_icache_data(int setnum, int tagnum, int subblock,
unsigned int *data)
{
unsigned int value1, value2, vaddr;
@ -67,7 +67,7 @@ extern __inline__ void get_icache_data(int setnum, int tagnum, int subblock,
data[0] = value1; data[1] = value2;
}
extern __inline__ void put_icache_data(int setnum, int tagnum, int subblock,
static inline void put_icache_data(int setnum, int tagnum, int subblock,
unsigned int *data)
{
unsigned int value1, value2, vaddr;
@ -92,35 +92,35 @@ extern __inline__ void put_icache_data(int setnum, int tagnum, int subblock,
*/
/* Flushes which clear out both the on-chip and external caches */
extern __inline__ void flush_ei_page(unsigned int addr)
static inline void flush_ei_page(unsigned int addr)
{
__asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
"r" (addr), "i" (ASI_M_FLUSH_PAGE) :
"memory");
}
extern __inline__ void flush_ei_seg(unsigned int addr)
static inline void flush_ei_seg(unsigned int addr)
{
__asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
"r" (addr), "i" (ASI_M_FLUSH_SEG) :
"memory");
}
extern __inline__ void flush_ei_region(unsigned int addr)
static inline void flush_ei_region(unsigned int addr)
{
__asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
"r" (addr), "i" (ASI_M_FLUSH_REGION) :
"memory");
}
extern __inline__ void flush_ei_ctx(unsigned int addr)
static inline void flush_ei_ctx(unsigned int addr)
{
__asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
"r" (addr), "i" (ASI_M_FLUSH_CTX) :
"memory");
}
extern __inline__ void flush_ei_user(unsigned int addr)
static inline void flush_ei_user(unsigned int addr)
{
__asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
"r" (addr), "i" (ASI_M_FLUSH_USER) :

View File

@ -48,25 +48,25 @@
#define CYPRESS_NFAULT 0x00000002
#define CYPRESS_MENABLE 0x00000001
extern __inline__ void cypress_flush_page(unsigned long page)
static inline void cypress_flush_page(unsigned long page)
{
__asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
"r" (page), "i" (ASI_M_FLUSH_PAGE));
}
extern __inline__ void cypress_flush_segment(unsigned long addr)
static inline void cypress_flush_segment(unsigned long addr)
{
__asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
"r" (addr), "i" (ASI_M_FLUSH_SEG));
}
extern __inline__ void cypress_flush_region(unsigned long addr)
static inline void cypress_flush_region(unsigned long addr)
{
__asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
"r" (addr), "i" (ASI_M_FLUSH_REGION));
}
extern __inline__ void cypress_flush_context(void)
static inline void cypress_flush_context(void)
{
__asm__ __volatile__("sta %%g0, [%%g0] %0\n\t" : :
"i" (ASI_M_FLUSH_CTX));

View File

@ -10,7 +10,7 @@
#include <linux/config.h>
#include <asm/cpudata.h>
extern __inline__ void __delay(unsigned long loops)
static inline void __delay(unsigned long loops)
{
__asm__ __volatile__("cmp %0, 0\n\t"
"1: bne 1b\n\t"

View File

@ -198,7 +198,7 @@ extern void dvma_init(struct sbus_bus *);
/* Pause until counter runs out or BIT isn't set in the DMA condition
* register.
*/
extern __inline__ void sparc_dma_pause(struct sparc_dma_registers *regs,
static inline void sparc_dma_pause(struct sparc_dma_registers *regs,
unsigned long bit)
{
int ctr = 50000; /* Let's find some bugs ;) */

View File

@ -108,12 +108,12 @@ struct iommu_struct {
struct bit_map usemap;
};
extern __inline__ void iommu_invalidate(struct iommu_regs *regs)
static inline void iommu_invalidate(struct iommu_regs *regs)
{
regs->tlbflush = 0;
}
extern __inline__ void iommu_invalidate_page(struct iommu_regs *regs, unsigned long ba)
static inline void iommu_invalidate_page(struct iommu_regs *regs, unsigned long ba)
{
regs->pageflush = (ba & PAGE_MASK);
}

View File

@ -46,7 +46,7 @@ struct kernel_debug {
extern struct kernel_debug *linux_dbvec;
/* Use this macro in C-code to enter the debugger. */
extern __inline__ void sp_enter_debugger(void)
static inline void sp_enter_debugger(void)
{
__asm__ __volatile__("jmpl %0, %%o7\n\t"
"nop\n\t" : :

View File

@ -83,7 +83,7 @@ extern unsigned int hwbug_bitmask;
*/
#define TBR_ID_SHIFT 20
extern __inline__ int get_cpuid(void)
static inline int get_cpuid(void)
{
register int retval;
__asm__ __volatile__("rd %%tbr, %0\n\t"
@ -93,7 +93,7 @@ extern __inline__ int get_cpuid(void)
return (retval & 3);
}
extern __inline__ int get_modid(void)
static inline int get_modid(void)
{
return (get_cpuid() | 0x8);
}

View File

@ -19,7 +19,7 @@
#define MSI_ASYNC_MODE 0x80000000 /* Operate the MSI asynchronously */
extern __inline__ void msi_set_sync(void)
static inline void msi_set_sync(void)
{
__asm__ __volatile__ ("lda [%0] %1, %%g3\n\t"
"andn %%g3, %2, %%g3\n\t"

View File

@ -85,7 +85,7 @@
#ifndef __ASSEMBLY__
extern __inline__ void mxcc_set_stream_src(unsigned long *paddr)
static inline void mxcc_set_stream_src(unsigned long *paddr)
{
unsigned long data0 = paddr[0];
unsigned long data1 = paddr[1];
@ -98,7 +98,7 @@ extern __inline__ void mxcc_set_stream_src(unsigned long *paddr)
"i" (ASI_M_MXCC) : "g2", "g3");
}
extern __inline__ void mxcc_set_stream_dst(unsigned long *paddr)
static inline void mxcc_set_stream_dst(unsigned long *paddr)
{
unsigned long data0 = paddr[0];
unsigned long data1 = paddr[1];
@ -111,7 +111,7 @@ extern __inline__ void mxcc_set_stream_dst(unsigned long *paddr)
"i" (ASI_M_MXCC) : "g2", "g3");
}
extern __inline__ unsigned long mxcc_get_creg(void)
static inline unsigned long mxcc_get_creg(void)
{
unsigned long mxcc_control;
@ -125,7 +125,7 @@ extern __inline__ unsigned long mxcc_get_creg(void)
return mxcc_control;
}
extern __inline__ void mxcc_set_creg(unsigned long mxcc_control)
static inline void mxcc_set_creg(unsigned long mxcc_control)
{
__asm__ __volatile__("sta %0, [%1] %2\n\t" : :
"r" (mxcc_control), "r" (MXCC_CREG),

View File

@ -98,7 +98,7 @@
#ifndef __ASSEMBLY__
extern __inline__ int bw_get_intr_mask(int sbus_level)
static inline int bw_get_intr_mask(int sbus_level)
{
int mask;
@ -109,7 +109,7 @@ extern __inline__ int bw_get_intr_mask(int sbus_level)
return mask;
}
extern __inline__ void bw_clear_intr_mask(int sbus_level, int mask)
static inline void bw_clear_intr_mask(int sbus_level, int mask)
{
__asm__ __volatile__ ("stha %0, [%1] %2" : :
"r" (mask),
@ -117,7 +117,7 @@ extern __inline__ void bw_clear_intr_mask(int sbus_level, int mask)
"i" (ASI_M_CTL));
}
extern __inline__ unsigned bw_get_prof_limit(int cpu)
static inline unsigned bw_get_prof_limit(int cpu)
{
unsigned limit;
@ -128,7 +128,7 @@ extern __inline__ unsigned bw_get_prof_limit(int cpu)
return limit;
}
extern __inline__ void bw_set_prof_limit(int cpu, unsigned limit)
static inline void bw_set_prof_limit(int cpu, unsigned limit)
{
__asm__ __volatile__ ("sta %0, [%1] %2" : :
"r" (limit),
@ -136,7 +136,7 @@ extern __inline__ void bw_set_prof_limit(int cpu, unsigned limit)
"i" (ASI_M_CTL));
}
extern __inline__ unsigned bw_get_ctrl(int cpu)
static inline unsigned bw_get_ctrl(int cpu)
{
unsigned ctrl;
@ -147,7 +147,7 @@ extern __inline__ unsigned bw_get_ctrl(int cpu)
return ctrl;
}
extern __inline__ void bw_set_ctrl(int cpu, unsigned ctrl)
static inline void bw_set_ctrl(int cpu, unsigned ctrl)
{
__asm__ __volatile__ ("sta %0, [%1] %2" : :
"r" (ctrl),
@ -157,7 +157,7 @@ extern __inline__ void bw_set_ctrl(int cpu, unsigned ctrl)
extern unsigned char cpu_leds[32];
extern __inline__ void show_leds(int cpuid)
static inline void show_leds(int cpuid)
{
cpuid &= 0x1e;
__asm__ __volatile__ ("stba %0, [%1] %2" : :
@ -166,7 +166,7 @@ extern __inline__ void show_leds(int cpuid)
"i" (ASI_M_CTL));
}
extern __inline__ unsigned cc_get_ipen(void)
static inline unsigned cc_get_ipen(void)
{
unsigned pending;
@ -177,7 +177,7 @@ extern __inline__ unsigned cc_get_ipen(void)
return pending;
}
extern __inline__ void cc_set_iclr(unsigned clear)
static inline void cc_set_iclr(unsigned clear)
{
__asm__ __volatile__ ("stha %0, [%1] %2" : :
"r" (clear),
@ -185,7 +185,7 @@ extern __inline__ void cc_set_iclr(unsigned clear)
"i" (ASI_M_MXCC));
}
extern __inline__ unsigned cc_get_imsk(void)
static inline unsigned cc_get_imsk(void)
{
unsigned mask;
@ -196,7 +196,7 @@ extern __inline__ unsigned cc_get_imsk(void)
return mask;
}
extern __inline__ void cc_set_imsk(unsigned mask)
static inline void cc_set_imsk(unsigned mask)
{
__asm__ __volatile__ ("stha %0, [%1] %2" : :
"r" (mask),
@ -204,7 +204,7 @@ extern __inline__ void cc_set_imsk(unsigned mask)
"i" (ASI_M_MXCC));
}
extern __inline__ unsigned cc_get_imsk_other(int cpuid)
static inline unsigned cc_get_imsk_other(int cpuid)
{
unsigned mask;
@ -215,7 +215,7 @@ extern __inline__ unsigned cc_get_imsk_other(int cpuid)
return mask;
}
extern __inline__ void cc_set_imsk_other(int cpuid, unsigned mask)
static inline void cc_set_imsk_other(int cpuid, unsigned mask)
{
__asm__ __volatile__ ("stha %0, [%1] %2" : :
"r" (mask),
@ -223,7 +223,7 @@ extern __inline__ void cc_set_imsk_other(int cpuid, unsigned mask)
"i" (ASI_M_CTL));
}
extern __inline__ void cc_set_igen(unsigned gen)
static inline void cc_set_igen(unsigned gen)
{
__asm__ __volatile__ ("sta %0, [%1] %2" : :
"r" (gen),
@ -239,7 +239,7 @@ extern __inline__ void cc_set_igen(unsigned gen)
#define IGEN_MESSAGE(bcast, devid, sid, levels) \
(((bcast) << 31) | ((devid) << 23) | ((sid) << 15) | (levels))
extern __inline__ void sun4d_send_ipi(int cpu, int level)
static inline void sun4d_send_ipi(int cpu, int level)
{
cc_set_igen(IGEN_MESSAGE(0, cpu << 3, 6 + ((level >> 1) & 7), 1 << (level - 1)));
}

View File

@ -15,12 +15,12 @@
#define PCI_IRQ_NONE 0xffffffff
extern inline void pcibios_set_master(struct pci_dev *dev)
static inline void pcibios_set_master(struct pci_dev *dev)
{
/* No special bus mastering setup handling */
}
extern inline void pcibios_penalize_isa_irq(int irq, int active)
static inline void pcibios_penalize_isa_irq(int irq, int active)
{
/* We don't do dynamic PCI IRQ allocation */
}
@ -137,7 +137,7 @@ extern void pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist
* only drive the low 24-bits during PCI bus mastering, then
* you would pass 0x00ffffff as the mask to this function.
*/
extern inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask)
static inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask)
{
return 1;
}

View File

@ -154,7 +154,7 @@ BTFIXUPDEF_CALL_CONST(int, pte_present, pte_t)
BTFIXUPDEF_CALL(void, pte_clear, pte_t *)
BTFIXUPDEF_CALL(int, pte_read, pte_t)
extern __inline__ int pte_none(pte_t pte)
static inline int pte_none(pte_t pte)
{
return !(pte_val(pte) & ~BTFIXUP_SETHI(none_mask));
}
@ -167,7 +167,7 @@ BTFIXUPDEF_CALL_CONST(int, pmd_bad, pmd_t)
BTFIXUPDEF_CALL_CONST(int, pmd_present, pmd_t)
BTFIXUPDEF_CALL(void, pmd_clear, pmd_t *)
extern __inline__ int pmd_none(pmd_t pmd)
static inline int pmd_none(pmd_t pmd)
{
return !(pmd_val(pmd) & ~BTFIXUP_SETHI(none_mask));
}
@ -194,20 +194,20 @@ BTFIXUPDEF_HALF(pte_writei)
BTFIXUPDEF_HALF(pte_dirtyi)
BTFIXUPDEF_HALF(pte_youngi)
extern int pte_write(pte_t pte) __attribute_const__;
extern __inline__ int pte_write(pte_t pte)
static int pte_write(pte_t pte) __attribute_const__;
static inline int pte_write(pte_t pte)
{
return pte_val(pte) & BTFIXUP_HALF(pte_writei);
}
extern int pte_dirty(pte_t pte) __attribute_const__;
extern __inline__ int pte_dirty(pte_t pte)
static int pte_dirty(pte_t pte) __attribute_const__;
static inline int pte_dirty(pte_t pte)
{
return pte_val(pte) & BTFIXUP_HALF(pte_dirtyi);
}
extern int pte_young(pte_t pte) __attribute_const__;
extern __inline__ int pte_young(pte_t pte)
static int pte_young(pte_t pte) __attribute_const__;
static inline int pte_young(pte_t pte)
{
return pte_val(pte) & BTFIXUP_HALF(pte_youngi);
}
@ -217,8 +217,8 @@ extern __inline__ int pte_young(pte_t pte)
*/
BTFIXUPDEF_HALF(pte_filei)
extern int pte_file(pte_t pte) __attribute_const__;
extern __inline__ int pte_file(pte_t pte)
static int pte_file(pte_t pte) __attribute_const__;
static inline int pte_file(pte_t pte)
{
return pte_val(pte) & BTFIXUP_HALF(pte_filei);
}
@ -229,20 +229,20 @@ BTFIXUPDEF_HALF(pte_wrprotecti)
BTFIXUPDEF_HALF(pte_mkcleani)
BTFIXUPDEF_HALF(pte_mkoldi)
extern pte_t pte_wrprotect(pte_t pte) __attribute_const__;
extern __inline__ pte_t pte_wrprotect(pte_t pte)
static pte_t pte_wrprotect(pte_t pte) __attribute_const__;
static inline pte_t pte_wrprotect(pte_t pte)
{
return __pte(pte_val(pte) & ~BTFIXUP_HALF(pte_wrprotecti));
}
extern pte_t pte_mkclean(pte_t pte) __attribute_const__;
extern __inline__ pte_t pte_mkclean(pte_t pte)
static pte_t pte_mkclean(pte_t pte) __attribute_const__;
static inline pte_t pte_mkclean(pte_t pte)
{
return __pte(pte_val(pte) & ~BTFIXUP_HALF(pte_mkcleani));
}
extern pte_t pte_mkold(pte_t pte) __attribute_const__;
extern __inline__ pte_t pte_mkold(pte_t pte)
static pte_t pte_mkold(pte_t pte) __attribute_const__;
static inline pte_t pte_mkold(pte_t pte)
{
return __pte(pte_val(pte) & ~BTFIXUP_HALF(pte_mkoldi));
}
@ -278,8 +278,8 @@ BTFIXUPDEF_CALL_CONST(pte_t, mk_pte_io, unsigned long, pgprot_t, int)
BTFIXUPDEF_INT(pte_modify_mask)
extern pte_t pte_modify(pte_t pte, pgprot_t newprot) __attribute_const__;
extern __inline__ pte_t pte_modify(pte_t pte, pgprot_t newprot)
static pte_t pte_modify(pte_t pte, pgprot_t newprot) __attribute_const__;
static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
{
return __pte((pte_val(pte) & BTFIXUP_INT(pte_modify_mask)) |
pgprot_val(newprot));
@ -386,13 +386,13 @@ extern struct ctx_list ctx_used; /* Head of used contexts list */
#define NO_CONTEXT -1
extern __inline__ void remove_from_ctx_list(struct ctx_list *entry)
static inline void remove_from_ctx_list(struct ctx_list *entry)
{
entry->next->prev = entry->prev;
entry->prev->next = entry->next;
}
extern __inline__ void add_to_ctx_list(struct ctx_list *head, struct ctx_list *entry)
static inline void add_to_ctx_list(struct ctx_list *head, struct ctx_list *entry)
{
entry->next = head;
(entry->prev = head->prev)->next = entry;
@ -401,7 +401,7 @@ extern __inline__ void add_to_ctx_list(struct ctx_list *head, struct ctx_list *e
#define add_to_free_ctxlist(entry) add_to_ctx_list(&ctx_free, entry)
#define add_to_used_ctxlist(entry) add_to_ctx_list(&ctx_used, entry)
extern __inline__ unsigned long
static inline unsigned long
__get_phys (unsigned long addr)
{
switch (sparc_cpu_model){
@ -416,7 +416,7 @@ __get_phys (unsigned long addr)
}
}
extern __inline__ int
static inline int
__get_iospace (unsigned long addr)
{
switch (sparc_cpu_model){

View File

@ -148,7 +148,7 @@ extern void *srmmu_nocache_pool;
#define __nocache_fix(VADDR) __va(__nocache_pa(VADDR))
/* Accessing the MMU control register. */
extern __inline__ unsigned int srmmu_get_mmureg(void)
static inline unsigned int srmmu_get_mmureg(void)
{
unsigned int retval;
__asm__ __volatile__("lda [%%g0] %1, %0\n\t" :
@ -157,14 +157,14 @@ extern __inline__ unsigned int srmmu_get_mmureg(void)
return retval;
}
extern __inline__ void srmmu_set_mmureg(unsigned long regval)
static inline void srmmu_set_mmureg(unsigned long regval)
{
__asm__ __volatile__("sta %0, [%%g0] %1\n\t" : :
"r" (regval), "i" (ASI_M_MMUREGS) : "memory");
}
extern __inline__ void srmmu_set_ctable_ptr(unsigned long paddr)
static inline void srmmu_set_ctable_ptr(unsigned long paddr)
{
paddr = ((paddr >> 4) & SRMMU_CTX_PMASK);
__asm__ __volatile__("sta %0, [%1] %2\n\t" : :
@ -173,7 +173,7 @@ extern __inline__ void srmmu_set_ctable_ptr(unsigned long paddr)
"memory");
}
extern __inline__ unsigned long srmmu_get_ctable_ptr(void)
static inline unsigned long srmmu_get_ctable_ptr(void)
{
unsigned int retval;
@ -184,14 +184,14 @@ extern __inline__ unsigned long srmmu_get_ctable_ptr(void)
return (retval & SRMMU_CTX_PMASK) << 4;
}
extern __inline__ void srmmu_set_context(int context)
static inline void srmmu_set_context(int context)
{
__asm__ __volatile__("sta %0, [%1] %2\n\t" : :
"r" (context), "r" (SRMMU_CTX_REG),
"i" (ASI_M_MMUREGS) : "memory");
}
extern __inline__ int srmmu_get_context(void)
static inline int srmmu_get_context(void)
{
register int retval;
__asm__ __volatile__("lda [%1] %2, %0\n\t" :
@ -201,7 +201,7 @@ extern __inline__ int srmmu_get_context(void)
return retval;
}
extern __inline__ unsigned int srmmu_get_fstatus(void)
static inline unsigned int srmmu_get_fstatus(void)
{
unsigned int retval;
@ -211,7 +211,7 @@ extern __inline__ unsigned int srmmu_get_fstatus(void)
return retval;
}
extern __inline__ unsigned int srmmu_get_faddr(void)
static inline unsigned int srmmu_get_faddr(void)
{
unsigned int retval;
@ -222,7 +222,7 @@ extern __inline__ unsigned int srmmu_get_faddr(void)
}
/* This is guaranteed on all SRMMU's. */
extern __inline__ void srmmu_flush_whole_tlb(void)
static inline void srmmu_flush_whole_tlb(void)
{
__asm__ __volatile__("sta %%g0, [%0] %1\n\t": :
"r" (0x400), /* Flush entire TLB!! */
@ -231,7 +231,7 @@ extern __inline__ void srmmu_flush_whole_tlb(void)
}
/* These flush types are not available on all chips... */
extern __inline__ void srmmu_flush_tlb_ctx(void)
static inline void srmmu_flush_tlb_ctx(void)
{
__asm__ __volatile__("sta %%g0, [%0] %1\n\t": :
"r" (0x300), /* Flush TLB ctx.. */
@ -239,7 +239,7 @@ extern __inline__ void srmmu_flush_tlb_ctx(void)
}
extern __inline__ void srmmu_flush_tlb_region(unsigned long addr)
static inline void srmmu_flush_tlb_region(unsigned long addr)
{
addr &= SRMMU_PGDIR_MASK;
__asm__ __volatile__("sta %%g0, [%0] %1\n\t": :
@ -249,7 +249,7 @@ extern __inline__ void srmmu_flush_tlb_region(unsigned long addr)
}
extern __inline__ void srmmu_flush_tlb_segment(unsigned long addr)
static inline void srmmu_flush_tlb_segment(unsigned long addr)
{
addr &= SRMMU_REAL_PMD_MASK;
__asm__ __volatile__("sta %%g0, [%0] %1\n\t": :
@ -258,7 +258,7 @@ extern __inline__ void srmmu_flush_tlb_segment(unsigned long addr)
}
extern __inline__ void srmmu_flush_tlb_page(unsigned long page)
static inline void srmmu_flush_tlb_page(unsigned long page)
{
page &= PAGE_MASK;
__asm__ __volatile__("sta %%g0, [%0] %1\n\t": :
@ -267,7 +267,7 @@ extern __inline__ void srmmu_flush_tlb_page(unsigned long page)
}
extern __inline__ unsigned long srmmu_hwprobe(unsigned long vaddr)
static inline unsigned long srmmu_hwprobe(unsigned long vaddr)
{
unsigned long retval;
@ -279,7 +279,7 @@ extern __inline__ unsigned long srmmu_hwprobe(unsigned long vaddr)
return retval;
}
extern __inline__ int
static inline int
srmmu_get_pte (unsigned long addr)
{
register unsigned long entry;

View File

@ -79,7 +79,7 @@ struct thread_struct {
extern unsigned long thread_saved_pc(struct task_struct *t);
/* Do necessary setup to start up a newly executed thread. */
extern __inline__ void start_thread(struct pt_regs * regs, unsigned long pc,
static inline void start_thread(struct pt_regs * regs, unsigned long pc,
unsigned long sp)
{
register unsigned long zero asm("g1");

View File

@ -38,7 +38,7 @@
#ifndef __ASSEMBLY__
/* Get the %psr register. */
extern __inline__ unsigned int get_psr(void)
static inline unsigned int get_psr(void)
{
unsigned int psr;
__asm__ __volatile__(
@ -53,7 +53,7 @@ extern __inline__ unsigned int get_psr(void)
return psr;
}
extern __inline__ void put_psr(unsigned int new_psr)
static inline void put_psr(unsigned int new_psr)
{
__asm__ __volatile__(
"wr %0, 0x0, %%psr\n\t"
@ -72,7 +72,7 @@ extern __inline__ void put_psr(unsigned int new_psr)
extern unsigned int fsr_storage;
extern __inline__ unsigned int get_fsr(void)
static inline unsigned int get_fsr(void)
{
unsigned int fsr = 0;

View File

@ -65,7 +65,7 @@ struct sbi_regs {
#ifndef __ASSEMBLY__
extern __inline__ int acquire_sbi(int devid, int mask)
static inline int acquire_sbi(int devid, int mask)
{
__asm__ __volatile__ ("swapa [%2] %3, %0" :
"=r" (mask) :
@ -75,7 +75,7 @@ extern __inline__ int acquire_sbi(int devid, int mask)
return mask;
}
extern __inline__ void release_sbi(int devid, int mask)
static inline void release_sbi(int devid, int mask)
{
__asm__ __volatile__ ("sta %0, [%1] %2" : :
"r" (mask),
@ -83,7 +83,7 @@ extern __inline__ void release_sbi(int devid, int mask)
"i" (ASI_M_CTL));
}
extern __inline__ void set_sbi_tid(int devid, int targetid)
static inline void set_sbi_tid(int devid, int targetid)
{
__asm__ __volatile__ ("sta %0, [%1] %2" : :
"r" (targetid),
@ -91,7 +91,7 @@ extern __inline__ void set_sbi_tid(int devid, int targetid)
"i" (ASI_M_CTL));
}
extern __inline__ int get_sbi_ctl(int devid, int cfgno)
static inline int get_sbi_ctl(int devid, int cfgno)
{
int cfg;
@ -102,7 +102,7 @@ extern __inline__ int get_sbi_ctl(int devid, int cfgno)
return cfg;
}
extern __inline__ void set_sbi_ctl(int devid, int cfgno, int cfg)
static inline void set_sbi_ctl(int devid, int cfgno, int cfg)
{
__asm__ __volatile__ ("sta %0, [%1] %2" : :
"r" (cfg),

View File

@ -28,12 +28,12 @@
* numbers + offsets, and vice versa.
*/
extern __inline__ unsigned long sbus_devaddr(int slotnum, unsigned long offset)
static inline unsigned long sbus_devaddr(int slotnum, unsigned long offset)
{
return (unsigned long) (SUN_SBUS_BVADDR+((slotnum)<<25)+(offset));
}
extern __inline__ int sbus_dev_slot(unsigned long dev_addr)
static inline int sbus_dev_slot(unsigned long dev_addr)
{
return (int) (((dev_addr)-SUN_SBUS_BVADDR)>>25);
}
@ -80,7 +80,7 @@ struct sbus_bus {
extern struct sbus_bus *sbus_root;
extern __inline__ int
static inline int
sbus_is_slave(struct sbus_dev *dev)
{
/* XXX Have to write this for sun4c's */

View File

@ -60,22 +60,22 @@ BTFIXUPDEF_BLACKBOX(load_current)
#define smp_cross_call(func,arg1,arg2,arg3,arg4,arg5) BTFIXUP_CALL(smp_cross_call)(func,arg1,arg2,arg3,arg4,arg5)
#define smp_message_pass(target,msg,data,wait) BTFIXUP_CALL(smp_message_pass)(target,msg,data,wait)
extern __inline__ void xc0(smpfunc_t func) { smp_cross_call(func, 0, 0, 0, 0, 0); }
extern __inline__ void xc1(smpfunc_t func, unsigned long arg1)
static inline void xc0(smpfunc_t func) { smp_cross_call(func, 0, 0, 0, 0, 0); }
static inline void xc1(smpfunc_t func, unsigned long arg1)
{ smp_cross_call(func, arg1, 0, 0, 0, 0); }
extern __inline__ void xc2(smpfunc_t func, unsigned long arg1, unsigned long arg2)
static inline void xc2(smpfunc_t func, unsigned long arg1, unsigned long arg2)
{ smp_cross_call(func, arg1, arg2, 0, 0, 0); }
extern __inline__ void xc3(smpfunc_t func, unsigned long arg1, unsigned long arg2,
static inline void xc3(smpfunc_t func, unsigned long arg1, unsigned long arg2,
unsigned long arg3)
{ smp_cross_call(func, arg1, arg2, arg3, 0, 0); }
extern __inline__ void xc4(smpfunc_t func, unsigned long arg1, unsigned long arg2,
static inline void xc4(smpfunc_t func, unsigned long arg1, unsigned long arg2,
unsigned long arg3, unsigned long arg4)
{ smp_cross_call(func, arg1, arg2, arg3, arg4, 0); }
extern __inline__ void xc5(smpfunc_t func, unsigned long arg1, unsigned long arg2,
static inline void xc5(smpfunc_t func, unsigned long arg1, unsigned long arg2,
unsigned long arg3, unsigned long arg4, unsigned long arg5)
{ smp_cross_call(func, arg1, arg2, arg3, arg4, arg5); }
extern __inline__ int smp_call_function(void (*func)(void *info), void *info, int nonatomic, int wait)
static inline int smp_call_function(void (*func)(void *info), void *info, int nonatomic, int wait)
{
xc1((smpfunc_t)func, (unsigned long)info);
return 0;
@ -84,16 +84,16 @@ extern __inline__ int smp_call_function(void (*func)(void *info), void *info, in
extern __volatile__ int __cpu_number_map[NR_CPUS];
extern __volatile__ int __cpu_logical_map[NR_CPUS];
extern __inline__ int cpu_logical_map(int cpu)
static inline int cpu_logical_map(int cpu)
{
return __cpu_logical_map[cpu];
}
extern __inline__ int cpu_number_map(int cpu)
static inline int cpu_number_map(int cpu)
{
return __cpu_number_map[cpu];
}
extern __inline__ int hard_smp4m_processor_id(void)
static inline int hard_smp4m_processor_id(void)
{
int cpuid;
@ -104,7 +104,7 @@ extern __inline__ int hard_smp4m_processor_id(void)
return cpuid;
}
extern __inline__ int hard_smp4d_processor_id(void)
static inline int hard_smp4d_processor_id(void)
{
int cpuid;
@ -114,7 +114,7 @@ extern __inline__ int hard_smp4d_processor_id(void)
}
#ifndef MODULE
extern __inline__ int hard_smp_processor_id(void)
static inline int hard_smp_processor_id(void)
{
int cpuid;
@ -136,7 +136,7 @@ extern __inline__ int hard_smp_processor_id(void)
return cpuid;
}
#else
extern __inline__ int hard_smp_processor_id(void)
static inline int hard_smp_processor_id(void)
{
int cpuid;

View File

@ -15,7 +15,7 @@
* atomic.
*/
extern __inline__ __volatile__ char test_and_set(void *addr)
static inline __volatile__ char test_and_set(void *addr)
{
char state = 0;
@ -27,7 +27,7 @@ extern __inline__ __volatile__ char test_and_set(void *addr)
}
/* Initialize a spin-lock. */
extern __inline__ __volatile__ smp_initlock(void *spinlock)
static inline __volatile__ smp_initlock(void *spinlock)
{
/* Unset the lock. */
*((unsigned char *) spinlock) = 0;
@ -36,7 +36,7 @@ extern __inline__ __volatile__ smp_initlock(void *spinlock)
}
/* This routine spins until it acquires the lock at ADDR. */
extern __inline__ __volatile__ smp_lock(void *addr)
static inline __volatile__ smp_lock(void *addr)
{
while(test_and_set(addr) == 0xff)
;
@ -46,7 +46,7 @@ extern __inline__ __volatile__ smp_lock(void *addr)
}
/* This routine releases the lock at ADDR. */
extern __inline__ __volatile__ smp_unlock(void *addr)
static inline __volatile__ smp_unlock(void *addr)
{
*((unsigned char *) addr) = 0;
}

View File

@ -17,7 +17,7 @@
#define __raw_spin_unlock_wait(lock) \
do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0)
extern __inline__ void __raw_spin_lock(raw_spinlock_t *lock)
static inline void __raw_spin_lock(raw_spinlock_t *lock)
{
__asm__ __volatile__(
"\n1:\n\t"
@ -37,7 +37,7 @@ extern __inline__ void __raw_spin_lock(raw_spinlock_t *lock)
: "g2", "memory", "cc");
}
extern __inline__ int __raw_spin_trylock(raw_spinlock_t *lock)
static inline int __raw_spin_trylock(raw_spinlock_t *lock)
{
unsigned int result;
__asm__ __volatile__("ldstub [%1], %0"
@ -47,7 +47,7 @@ extern __inline__ int __raw_spin_trylock(raw_spinlock_t *lock)
return (result == 0);
}
extern __inline__ void __raw_spin_unlock(raw_spinlock_t *lock)
static inline void __raw_spin_unlock(raw_spinlock_t *lock)
{
__asm__ __volatile__("stb %%g0, [%0]" : : "r" (lock) : "memory");
}
@ -78,7 +78,7 @@ extern __inline__ void __raw_spin_unlock(raw_spinlock_t *lock)
*
* Unfortunately this scheme limits us to ~16,000,000 cpus.
*/
extern __inline__ void __read_lock(raw_rwlock_t *rw)
static inline void __read_lock(raw_rwlock_t *rw)
{
register raw_rwlock_t *lp asm("g1");
lp = rw;
@ -98,7 +98,7 @@ do { unsigned long flags; \
local_irq_restore(flags); \
} while(0)
extern __inline__ void __read_unlock(raw_rwlock_t *rw)
static inline void __read_unlock(raw_rwlock_t *rw)
{
register raw_rwlock_t *lp asm("g1");
lp = rw;

View File

@ -204,7 +204,7 @@ static inline unsigned long getipl(void)
BTFIXUPDEF_CALL(void, ___xchg32, void)
#endif
extern __inline__ unsigned long xchg_u32(__volatile__ unsigned long *m, unsigned long val)
static inline unsigned long xchg_u32(__volatile__ unsigned long *m, unsigned long val)
{
#ifdef CONFIG_SMP
__asm__ __volatile__("swap [%2], %0"

View File

@ -22,7 +22,7 @@ struct tt_entry {
/* We set this to _start in system setup. */
extern struct tt_entry *sparc_ttable;
extern __inline__ unsigned long get_tbr(void)
static inline unsigned long get_tbr(void)
{
unsigned long tbr;

View File

@ -13,6 +13,7 @@ struct task_struct;
#include "linux/config.h"
#include "asm/ptrace.h"
#include "choose-mode.h"
#include "registers.h"
struct mm_struct;
@ -136,19 +137,15 @@ extern struct cpuinfo_um cpu_data[];
#define current_cpu_data boot_cpu_data
#endif
#define KSTK_EIP(tsk) (PT_REGS_IP(&tsk->thread.regs))
#define KSTK_ESP(tsk) (PT_REGS_SP(&tsk->thread.regs))
#ifdef CONFIG_MODE_SKAS
#define KSTK_REG(tsk, reg) \
({ union uml_pt_regs regs; \
get_thread_regs(&regs, tsk->thread.mode.skas.switch_buf); \
UPT_REG(&regs, reg); })
#else
#define KSTK_REG(tsk, reg) (0xbadbabe)
#endif
#define get_wchan(p) (0)
#endif
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-file-style: "linux"
* End:
*/

View File

@ -43,17 +43,10 @@ static inline void rep_nop(void)
#define ARCH_IS_STACKGROW(address) \
(address + 32 >= UPT_SP(&current->thread.regs.regs))
#define KSTK_EIP(tsk) KSTK_REG(tsk, EIP)
#define KSTK_ESP(tsk) KSTK_REG(tsk, UESP)
#define KSTK_EBP(tsk) KSTK_REG(tsk, EBP)
#include "asm/processor-generic.h"
#endif
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-file-style: "linux"
* End:
*/

View File

@ -36,17 +36,9 @@ extern inline void rep_nop(void)
#define ARCH_IS_STACKGROW(address) \
(address + 128 >= UPT_SP(&current->thread.regs.regs))
#define KSTK_EIP(tsk) KSTK_REG(tsk, RIP)
#define KSTK_ESP(tsk) KSTK_REG(tsk, RSP)
#include "asm/processor-generic.h"
#endif
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-file-style: "linux"
* End:
*/

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