diff options
| author | Anton Blanchard <anton@samba.org> | 2003-01-14 15:39:43 +1100 |
|---|---|---|
| committer | Anton Blanchard <anton@samba.org> | 2003-01-14 15:39:43 +1100 |
| commit | 1362870b954f86e86e05288b5df0e2341e45354c (patch) | |
| tree | 927215aa7e0e0bba229e4f76f3497187a4de69a0 | |
| parent | f3ae5c72087bd059e0a188e57a171709c4fd72fa (diff) | |
| parent | bcd998aad6496759d239eaba760a6ca6d1a73e2c (diff) | |
Merge samba.org:/scratch/anton/linux-2.5
into samba.org:/scratch/anton/for-alan
102 files changed, 1419 insertions, 2022 deletions
diff --git a/arch/alpha/vmlinux.lds.S b/arch/alpha/vmlinux.lds.S index ac8106a4ea20..20f7cadffedd 100644 --- a/arch/alpha/vmlinux.lds.S +++ b/arch/alpha/vmlinux.lds.S @@ -32,6 +32,13 @@ SECTIONS __stop___ksymtab = .; } + /* Kernel symbol table: GPL only */ + __gpl_ksymtab ALIGN(8) : { + __start___gpl_ksymtab = .; + *(__gpl_ksymtab) + __stop___gpl_ksymtab = .; + } + /* All kernel symbols */ __kallsyms ALIGN(8) : { __start___kallsyms = .; diff --git a/arch/arm/vmlinux-armo.lds.in b/arch/arm/vmlinux-armo.lds.in index 1c32108b9a13..ce2b98b67fdc 100644 --- a/arch/arm/vmlinux-armo.lds.in +++ b/arch/arm/vmlinux-armo.lds.in @@ -78,6 +78,12 @@ SECTIONS __stop___ksymtab = .; } + __gpl_ksymtab : { /* Kernel symbol table: GPL-only */ + __start___gpl_ksymtab = .; + *(__gpl_ksymtab) + __stop___gpl_ksymtab = .; + } + .data : { /* * The cacheline aligned data diff --git a/arch/cris/vmlinux.lds.S b/arch/cris/vmlinux.lds.S index 74ac779474eb..bc3231c2c3b0 100644 --- a/arch/cris/vmlinux.lds.S +++ b/arch/cris/vmlinux.lds.S @@ -43,6 +43,10 @@ SECTIONS __ksymtab : { *(__ksymtab) } __stop___ksymtab = .; + __start___gpl_ksymtab = .; /* Kernel symbol table: GPL-only */ + __gpl_ksymtab : { *(__gpl_ksymtab) } + __stop___gpl_ksymtab = .; + . = ALIGN (4); ___data_start = . ; __Sdata = . ; diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c index c471cfb27070..951717d62f17 100644 --- a/arch/i386/kernel/ptrace.c +++ b/arch/i386/kernel/ptrace.c @@ -21,6 +21,8 @@ #include <asm/processor.h> #include <asm/i387.h> #include <asm/debugreg.h> +#include <asm/ldt.h> +#include <asm/desc.h> /* * does not yet catch signals sent when the child dies. @@ -148,6 +150,85 @@ void ptrace_disable(struct task_struct *child) put_stack_long(child, EFL_OFFSET, tmp); } +/* + * Perform get_thread_area on behalf of the traced child. + */ +static int +ptrace_get_thread_area(struct task_struct *child, + int idx, struct user_desc *user_desc) +{ + struct user_desc info; + struct desc_struct *desc; + +/* + * Get the current Thread-Local Storage area: + */ + +#define GET_BASE(desc) ( \ + (((desc)->a >> 16) & 0x0000ffff) | \ + (((desc)->b << 16) & 0x00ff0000) | \ + ( (desc)->b & 0xff000000) ) + +#define GET_LIMIT(desc) ( \ + ((desc)->a & 0x0ffff) | \ + ((desc)->b & 0xf0000) ) + +#define GET_32BIT(desc) (((desc)->b >> 23) & 1) +#define GET_CONTENTS(desc) (((desc)->b >> 10) & 3) +#define GET_WRITABLE(desc) (((desc)->b >> 9) & 1) +#define GET_LIMIT_PAGES(desc) (((desc)->b >> 23) & 1) +#define GET_PRESENT(desc) (((desc)->b >> 15) & 1) +#define GET_USEABLE(desc) (((desc)->b >> 20) & 1) + + if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) + return -EINVAL; + + desc = child->thread.tls_array + idx - GDT_ENTRY_TLS_MIN; + + info.entry_number = idx; + info.base_addr = GET_BASE(desc); + info.limit = GET_LIMIT(desc); + info.seg_32bit = GET_32BIT(desc); + info.contents = GET_CONTENTS(desc); + info.read_exec_only = !GET_WRITABLE(desc); + info.limit_in_pages = GET_LIMIT_PAGES(desc); + info.seg_not_present = !GET_PRESENT(desc); + info.useable = GET_USEABLE(desc); + + if (copy_to_user(user_desc, &info, sizeof(info))) + return -EFAULT; + + return 0; +} + +/* + * Perform set_thread_area on behalf of the traced child. + */ +static int +ptrace_set_thread_area(struct task_struct *child, + int idx, struct user_desc *user_desc) +{ + struct user_desc info; + struct desc_struct *desc; + + if (copy_from_user(&info, user_desc, sizeof(info))) + return -EFAULT; + + if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) + return -EINVAL; + + desc = child->thread.tls_array + idx - GDT_ENTRY_TLS_MIN; + if (LDT_empty(&info)) { + desc->a = 0; + desc->b = 0; + } else { + desc->a = LDT_entry_a(&info); + desc->b = LDT_entry_b(&info); + } + + return 0; +} + asmlinkage int sys_ptrace(long request, long pid, long addr, long data) { struct task_struct *child; @@ -416,6 +497,16 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) break; } + case PTRACE_GET_THREAD_AREA: + ret = ptrace_get_thread_area(child, + addr, (struct user_desc *) data); + break; + + case PTRACE_SET_THREAD_AREA: + ret = ptrace_set_thread_area(child, + addr, (struct user_desc *) data); + break; + default: ret = ptrace_request(child, request, addr, data); break; diff --git a/arch/i386/vmlinux.lds.S b/arch/i386/vmlinux.lds.S index 71860a99a417..222deebc9e67 100644 --- a/arch/i386/vmlinux.lds.S +++ b/arch/i386/vmlinux.lds.S @@ -31,6 +31,10 @@ SECTIONS __ksymtab : { *(__ksymtab) } __stop___ksymtab = .; + __start___gpl_ksymtab = .; /* Kernel symbol table: GPL-only symbols */ + __gpl_ksymtab : { *(__gpl_ksymtab) } + __stop___gpl_ksymtab = .; + __start___kallsyms = .; /* All kernel symbols */ __kallsyms : { *(__kallsyms) } __stop___kallsyms = .; diff --git a/arch/ia64/vmlinux.lds.S b/arch/ia64/vmlinux.lds.S index 69ba842dd76d..04a2fdf300d3 100644 --- a/arch/ia64/vmlinux.lds.S +++ b/arch/ia64/vmlinux.lds.S @@ -65,6 +65,11 @@ SECTIONS { *(__ksymtab) } __stop___ksymtab = .; + __start___gpl_ksymtab = .; /* Kernel symbol table: GPL only */ + __gpl_ksymtab : AT(ADDR(__gpl_ksymtab) - PAGE_OFFSET) + { *(__gpl_ksymtab) } + __stop___gpl_ksymtab = .; + __kallsyms : AT(ADDR(__kallsyms) - PAGE_OFFSET) { __start___kallsyms = .; /* All kernel symbols */ diff --git a/arch/m68k/vmlinux-std.lds b/arch/m68k/vmlinux-std.lds index c31bc1da259b..d5ef5629f941 100644 --- a/arch/m68k/vmlinux-std.lds +++ b/arch/m68k/vmlinux-std.lds @@ -24,6 +24,10 @@ SECTIONS __ksymtab : { *(__ksymtab) } __stop___ksymtab = .; + __start___gpl_ksymtab = .; /* Kernel symbol table: GPL only */ + __gpl_ksymtab : { *(__gpl_ksymtab) } + __stop___gpl_ksymtab = .; + _etext = .; /* End of text section */ .data : { /* Data */ diff --git a/arch/m68k/vmlinux-sun3.lds b/arch/m68k/vmlinux-sun3.lds index 9ce55a8120c0..9c35357cb6f9 100644 --- a/arch/m68k/vmlinux-sun3.lds +++ b/arch/m68k/vmlinux-sun3.lds @@ -30,6 +30,9 @@ SECTIONS __start___ksymtab = .; /* Kernel symbol table */ *(__ksymtab) __stop___ksymtab = .; + __start___gpl_ksymtab = .; /* Kernel symbol table: GPL-only */ + __gpl_ksymtab : { *(__gpl_ksymtab) } + __stop___gpl_ksymtab = .; } /* End of data goes *here* so that freeing init code works properly. */ _edata = .; diff --git a/arch/m68knommu/platform/5206/ARNEWSH/ram.ld b/arch/m68knommu/platform/5206/ARNEWSH/ram.ld index 43a14a0c9e42..b495a0c77737 100644 --- a/arch/m68knommu/platform/5206/ARNEWSH/ram.ld +++ b/arch/m68knommu/platform/5206/ARNEWSH/ram.ld @@ -24,6 +24,11 @@ SECTIONS { __start___ksymtab = .; /* Kernel symbol table */ *(__ksymtab) __stop___ksymtab = .; + + __start___gpl_ksymtab = .; /* Kernel symbol table: GPL-only */ + *(__gpl_ksymtab) + __stop___gpl_ksymtab = .; + . = ALIGN(4) ; _etext = . ; } > ram diff --git a/arch/m68knommu/platform/5206e/MOTOROLA/ram.ld b/arch/m68knommu/platform/5206e/MOTOROLA/ram.ld index d1251467ed1f..60e2b4b47090 100644 --- a/arch/m68knommu/platform/5206e/MOTOROLA/ram.ld +++ b/arch/m68knommu/platform/5206e/MOTOROLA/ram.ld @@ -24,6 +24,11 @@ SECTIONS { __start___ksymtab = .; /* Kernel symbol table */ *(__ksymtab) __stop___ksymtab = .; + + __start___gpl_ksymtab = .; /* Kernel symbol table: GPL-only */ + *(__gpl_ksymtab) + __stop___gpl_ksymtab = .; + . = ALIGN(4) ; _etext = . ; } > ram diff --git a/arch/m68knommu/platform/5206e/eLITE/ram.ld b/arch/m68knommu/platform/5206e/eLITE/ram.ld index d5e7def1ee32..4671c9f42905 100644 --- a/arch/m68knommu/platform/5206e/eLITE/ram.ld +++ b/arch/m68knommu/platform/5206e/eLITE/ram.ld @@ -24,6 +24,11 @@ SECTIONS { __start___ksymtab = .; /* Kernel symbol table */ *(__ksymtab) __stop___ksymtab = .; + + __start___gpl_ksymtab = .; /* Kernel symbol table: GPL-only */ + *(__gpl_ksymtab) + __stop___gpl_ksymtab = .; + . = ALIGN(4) ; _etext = . ; } > ram diff --git a/arch/m68knommu/platform/5249/MOTOROLA/ram.ld b/arch/m68knommu/platform/5249/MOTOROLA/ram.ld index 03514c65d949..16027bd834ed 100644 --- a/arch/m68knommu/platform/5249/MOTOROLA/ram.ld +++ b/arch/m68knommu/platform/5249/MOTOROLA/ram.ld @@ -25,6 +25,11 @@ SECTIONS { __start___ksymtab = .; /* Kernel symbol table */ *(__ksymtab) __stop___ksymtab = .; + + __start___gpl_ksymtab = .; /* Kernel symbol table: GPL-only */ + *(__gpl_ksymtab) + __stop___gpl_ksymtab = .; + . = ALIGN(4) ; _etext = . ; } > ram diff --git a/arch/m68knommu/platform/5272/MOTOROLA/ram.ld b/arch/m68knommu/platform/5272/MOTOROLA/ram.ld index 03514c65d949..16027bd834ed 100644 --- a/arch/m68knommu/platform/5272/MOTOROLA/ram.ld +++ b/arch/m68knommu/platform/5272/MOTOROLA/ram.ld @@ -25,6 +25,11 @@ SECTIONS { __start___ksymtab = .; /* Kernel symbol table */ *(__ksymtab) __stop___ksymtab = .; + + __start___gpl_ksymtab = .; /* Kernel symbol table: GPL-only */ + *(__gpl_ksymtab) + __stop___gpl_ksymtab = .; + . = ALIGN(4) ; _etext = . ; } > ram diff --git a/arch/m68knommu/platform/5272/NETtel/ram.ld b/arch/m68knommu/platform/5272/NETtel/ram.ld index 96b255638b8b..a28ff1c8995d 100644 --- a/arch/m68knommu/platform/5272/NETtel/ram.ld +++ b/arch/m68knommu/platform/5272/NETtel/ram.ld @@ -25,6 +25,11 @@ SECTIONS { __start___ksymtab = .; /* Kernel symbol table */ *(__ksymtab) __stop___ksymtab = .; + + __start___gpl_ksymtab = .; /* Kernel symbol table: GPL-only */ + *(__gpl_ksymtab) + __stop___gpl_ksymtab = .; + . = ALIGN(4) ; _etext = . ; } > ram diff --git a/arch/m68knommu/platform/5307/ARNEWSH/ram.ld b/arch/m68knommu/platform/5307/ARNEWSH/ram.ld index 81e0b94b940d..3eed2271047f 100644 --- a/arch/m68knommu/platform/5307/ARNEWSH/ram.ld +++ b/arch/m68knommu/platform/5307/ARNEWSH/ram.ld @@ -24,6 +24,11 @@ SECTIONS { __start___ksymtab = .; /* Kernel symbol table */ *(__ksymtab) __stop___ksymtab = .; + + __start___gpl_ksymtab = .; /* Kernel symbol table: GPL-only */ + *(__gpl_ksymtab) + __stop___gpl_ksymtab = .; + . = ALIGN(4) ; _etext = . ; } > ram diff --git a/arch/m68knommu/platform/5307/CLEOPATRA/ram.ld b/arch/m68knommu/platform/5307/CLEOPATRA/ram.ld index 2b7fa0e99120..f407dadae130 100644 --- a/arch/m68knommu/platform/5307/CLEOPATRA/ram.ld +++ b/arch/m68knommu/platform/5307/CLEOPATRA/ram.ld @@ -24,6 +24,11 @@ SECTIONS { __start___ksymtab = .; /* Kernel symbol table */ *(__ksymtab) __stop___ksymtab = .; + + __start___gpl_ksymtab = .; /* Kernel symbol table: GPL-only */ + *(__gpl_ksymtab) + __stop___gpl_ksymtab = .; + . = ALIGN(4) ; _etext = . ; } > ram diff --git a/arch/m68knommu/platform/5307/MOTOROLA/ram.ld b/arch/m68knommu/platform/5307/MOTOROLA/ram.ld index 81e0b94b940d..3eed2271047f 100644 --- a/arch/m68knommu/platform/5307/MOTOROLA/ram.ld +++ b/arch/m68knommu/platform/5307/MOTOROLA/ram.ld @@ -24,6 +24,11 @@ SECTIONS { __start___ksymtab = .; /* Kernel symbol table */ *(__ksymtab) __stop___ksymtab = .; + + __start___gpl_ksymtab = .; /* Kernel symbol table: GPL-only */ + *(__gpl_ksymtab) + __stop___gpl_ksymtab = .; + . = ALIGN(4) ; _etext = . ; } > ram diff --git a/arch/m68knommu/platform/5307/MP3/ram.ld b/arch/m68knommu/platform/5307/MP3/ram.ld index 2b7fa0e99120..f407dadae130 100644 --- a/arch/m68knommu/platform/5307/MP3/ram.ld +++ b/arch/m68knommu/platform/5307/MP3/ram.ld @@ -24,6 +24,11 @@ SECTIONS { __start___ksymtab = .; /* Kernel symbol table */ *(__ksymtab) __stop___ksymtab = .; + + __start___gpl_ksymtab = .; /* Kernel symbol table: GPL-only */ + *(__gpl_ksymtab) + __stop___gpl_ksymtab = .; + . = ALIGN(4) ; _etext = . ; } > ram diff --git a/arch/m68knommu/platform/5307/NETtel/ram.ld b/arch/m68knommu/platform/5307/NETtel/ram.ld index 1bc8a19becb1..913619337af1 100644 --- a/arch/m68knommu/platform/5307/NETtel/ram.ld +++ b/arch/m68knommu/platform/5307/NETtel/ram.ld @@ -24,6 +24,11 @@ SECTIONS { __start___ksymtab = .; /* Kernel symbol table */ *(__ksymtab) __stop___ksymtab = .; + + __start___gpl_ksymtab = .; /* Kernel symbol table: GPL-only */ + *(__gpl_ksymtab) + __stop___gpl_ksymtab = .; + . = ALIGN(4) ; _etext = . ; } > ram diff --git a/arch/m68knommu/platform/5407/CLEOPATRA/ram.ld b/arch/m68knommu/platform/5407/CLEOPATRA/ram.ld index 7026f1d7b405..78ca244b1a6f 100644 --- a/arch/m68knommu/platform/5407/CLEOPATRA/ram.ld +++ b/arch/m68knommu/platform/5407/CLEOPATRA/ram.ld @@ -24,6 +24,11 @@ SECTIONS { __start___ksymtab = .; /* Kernel symbol table */ *(__ksymtab) __stop___ksymtab = .; + + __start___gpl_ksymtab = .; /* Kernel symbol table: GPL-only */ + *(__gpl_ksymtab) + __stop___gpl_ksymtab = .; + . = ALIGN(4) ; _etext = . ; } > ram diff --git a/arch/m68knommu/platform/5407/MOTOROLA/ram.ld b/arch/m68knommu/platform/5407/MOTOROLA/ram.ld index 81e0b94b940d..3eed2271047f 100644 --- a/arch/m68knommu/platform/5407/MOTOROLA/ram.ld +++ b/arch/m68knommu/platform/5407/MOTOROLA/ram.ld @@ -24,6 +24,11 @@ SECTIONS { __start___ksymtab = .; /* Kernel symbol table */ *(__ksymtab) __stop___ksymtab = .; + + __start___gpl_ksymtab = .; /* Kernel symbol table: GPL-only */ + *(__gpl_ksymtab) + __stop___gpl_ksymtab = .; + . = ALIGN(4) ; _etext = . ; } > ram diff --git a/arch/m68knommu/platform/68360/uCquicc/ram.ld b/arch/m68knommu/platform/68360/uCquicc/ram.ld index 8e5c46433784..055840b84cdd 100644 --- a/arch/m68knommu/platform/68360/uCquicc/ram.ld +++ b/arch/m68knommu/platform/68360/uCquicc/ram.ld @@ -38,6 +38,9 @@ SECTIONS __start___ksymtab = . ; *(__ksymtab) __stop___ksymtab = . ; + __start___gpl_ksymtab = . ; + *(__gpl_ksymtab) + __stop___gpl_ksymtab = . ; __start___ex_table = . ; *(___ex_table) __stop___ex_table = . ; diff --git a/arch/m68knommu/platform/68360/uCquicc/rom.ld b/arch/m68knommu/platform/68360/uCquicc/rom.ld index 411f1b71d56d..e40c48fafe5e 100644 --- a/arch/m68knommu/platform/68360/uCquicc/rom.ld +++ b/arch/m68knommu/platform/68360/uCquicc/rom.ld @@ -38,6 +38,9 @@ SECTIONS __start___ksymtab = . ; *(__ksymtab) __stop___ksymtab = . ; + __start___gpl_ksymtab = . ; + *(__gpl_ksymtab) + __stop___gpl_ksymtab = . ; __start___ex_table = . ; *(___ex_table) __stop___ex_table = . ; diff --git a/arch/m68knommu/platform/68EZ328/ucsimm/fixed.ld b/arch/m68knommu/platform/68EZ328/ucsimm/fixed.ld index 58a6e032c2db..2b0e7f79e041 100644 --- a/arch/m68knommu/platform/68EZ328/ucsimm/fixed.ld +++ b/arch/m68knommu/platform/68EZ328/ucsimm/fixed.ld @@ -30,6 +30,10 @@ SECTIONS *(__ksymtab) __stop___ksymtab = .; + __start___gpl_ksymtab = .; /* Kernel symbol table: GPL-only */ + *(__gpl_ksymtab) + __stop___gpl_ksymtab = .; + . = ALIGN(0x4) ; _etext = . ; __data_rom_start = . ; diff --git a/arch/m68knommu/platform/68EZ328/ucsimm/ram.ld b/arch/m68knommu/platform/68EZ328/ucsimm/ram.ld index 29f6b951e036..cf70aa4709be 100644 --- a/arch/m68knommu/platform/68EZ328/ucsimm/ram.ld +++ b/arch/m68knommu/platform/68EZ328/ucsimm/ram.ld @@ -51,6 +51,10 @@ SECTIONS *(__ksymtab) __stop___ksymtab = .; + __start___gpl_ksymtab = .; /* Kernel symbol table: GPL-only */ + *(__gpl_ksymtab) + __stop___gpl_ksymtab = .; + _etext = . ; __data_rom_start = ALIGN ( 4 ) ; } > ram diff --git a/arch/m68knommu/platform/68VZ328/de2/fixed.ld b/arch/m68knommu/platform/68VZ328/de2/fixed.ld index c27774e9913d..eb9337985eaf 100644 --- a/arch/m68knommu/platform/68VZ328/de2/fixed.ld +++ b/arch/m68knommu/platform/68VZ328/de2/fixed.ld @@ -29,6 +29,10 @@ SECTIONS *(__ksymtab) __stop___ksymtab = .; + __start___gpl_ksymtab = .; /* Kernel symbol table: GPL-only */ + *(__gpl_ksymtab) + __stop___gpl_ksymtab = .; + . = ALIGN(0x4) ; _etext = . ; __data_rom_start = . ; diff --git a/arch/m68knommu/platform/68VZ328/de2/ram.ld b/arch/m68knommu/platform/68VZ328/de2/ram.ld index cf1d75fa056e..a8cc62449910 100644 --- a/arch/m68knommu/platform/68VZ328/de2/ram.ld +++ b/arch/m68knommu/platform/68VZ328/de2/ram.ld @@ -50,6 +50,10 @@ SECTIONS *(__ksymtab) __stop___ksymtab = .; + __start___gpl_ksymtab = .; /* Kernel symbol table: GPL-only */ + *(__gpl_ksymtab) + __stop___gpl_ksymtab = .; + _etext = . ; __data_rom_start = ALIGN ( 4 ) ; } > ram diff --git a/arch/m68knommu/platform/68VZ328/ucdimm/fixed.ld b/arch/m68knommu/platform/68VZ328/ucdimm/fixed.ld index 73dd70b52e47..8620d7780853 100644 --- a/arch/m68knommu/platform/68VZ328/ucdimm/fixed.ld +++ b/arch/m68knommu/platform/68VZ328/ucdimm/fixed.ld @@ -29,6 +29,10 @@ SECTIONS *(__ksymtab) __stop___ksymtab = .; + __start___gpl_ksymtab = .; /* Kernel symbol table: GPL-only */ + *(__gpl_ksymtab) + __stop___gpl_ksymtab = .; + . = ALIGN(0x4) ; _etext = . ; __data_rom_start = . ; diff --git a/arch/m68knommu/platform/68VZ328/ucdimm/ram.ld b/arch/m68knommu/platform/68VZ328/ucdimm/ram.ld index 8d33e798fa99..84c85c7ce228 100644 --- a/arch/m68knommu/platform/68VZ328/ucdimm/ram.ld +++ b/arch/m68knommu/platform/68VZ328/ucdimm/ram.ld @@ -50,6 +50,10 @@ SECTIONS *(__ksymtab) __stop___ksymtab = .; + __start___gpl_ksymtab = .; /* Kernel symbol table: GPL-only */ + *(__gpl_ksymtab) + __stop___gpl_ksymtab = .; + _etext = . ; __data_rom_start = ALIGN ( 4 ) ; } > ram diff --git a/arch/mips/vmlinux.lds.S b/arch/mips/vmlinux.lds.S index 83563f969f6b..d97c30432939 100644 --- a/arch/mips/vmlinux.lds.S +++ b/arch/mips/vmlinux.lds.S @@ -29,6 +29,10 @@ SECTIONS __ksymtab : { *(__ksymtab) } __stop___ksymtab = .; + __start___gpl_ksymtab = .; /* Kernel symbol table: GPL-only symbols */ + __gpl_ksymtab : { *(__gpl_ksymtab) } + __stop___gpl_ksymtab = .; + _etext = .; . = ALIGN(8192); diff --git a/arch/parisc/vmlinux.lds.S b/arch/parisc/vmlinux.lds.S index 01e4aaa7550e..0857c90f9d3a 100644 --- a/arch/parisc/vmlinux.lds.S +++ b/arch/parisc/vmlinux.lds.S @@ -49,6 +49,10 @@ SECTIONS __ksymtab : { *(__ksymtab) } __stop___ksymtab = .; + __start___gpl_ksymtab = .; /* Kernel symbol table: GPL-only symbols */ + __gpl_ksymtab : { *(__gpl_ksymtab) } + __stop___gpl_ksymtab = .; + __start___kallsyms = .; /* All kernel symbols */ __kallsyms : { *(__kallsyms) } __stop___kallsyms = .; diff --git a/arch/ppc/vmlinux.lds.S b/arch/ppc/vmlinux.lds.S index 4522197a7556..2b0a30627986 100644 --- a/arch/ppc/vmlinux.lds.S +++ b/arch/ppc/vmlinux.lds.S @@ -61,6 +61,10 @@ SECTIONS __ksymtab : { *(__ksymtab) } __stop___ksymtab = .; + __start___gpl_ksymtab = .; /* Kernel symbol table: GPL-only symbols */ + __gpl_ksymtab : { *(__gpl_ksymtab) } + __stop___gpl_ksymtab = .; + __start___kallsyms = .; /* All kernel symbols */ __kallsyms : { *(__kallsyms) } __stop___kallsyms = .; diff --git a/arch/ppc64/vmlinux.lds.S b/arch/ppc64/vmlinux.lds.S index 00911a7ec795..dc1b16ca6807 100644 --- a/arch/ppc64/vmlinux.lds.S +++ b/arch/ppc64/vmlinux.lds.S @@ -69,6 +69,10 @@ SECTIONS __ksymtab : { *(__ksymtab) } __stop___ksymtab = .; + __start___gpl_ksymtab = .; /* Kernel symbol table: GPL-only symbols */ + __gpl_ksymtab : { *(__gpl_ksymtab) } + __stop___gpl_ksymtab = .; + __start___kallsyms = .; /* All kernel symbols */ __kallsyms : { *(__kallsyms) } __stop___kallsyms = .; diff --git a/arch/s390/vmlinux.lds.S b/arch/s390/vmlinux.lds.S index e7c792933af5..0310629bc544 100644 --- a/arch/s390/vmlinux.lds.S +++ b/arch/s390/vmlinux.lds.S @@ -30,6 +30,10 @@ SECTIONS __ksymtab : { *(__ksymtab) } __stop___ksymtab = .; + __start___gpl_ksymtab = .; /* Kernel symbol table: GPL-only symbols */ + __gpl_ksymtab : { *(__gpl_ksymtab) } + __stop___gpl_ksymtab = .; + #ifdef CONFIG_SHARED_KERNEL . = ALIGN(1048576); /* VM shared segments are 1MB aligned */ diff --git a/arch/s390x/kernel/entry.S b/arch/s390x/kernel/entry.S index 66794e864c0d..03c188833122 100644 --- a/arch/s390x/kernel/entry.S +++ b/arch/s390x/kernel/entry.S @@ -490,8 +490,8 @@ sys_call_table: .long SYSCALL(sys_getpriority,sys32_getpriority_wrapper) .long SYSCALL(sys_setpriority,sys32_setpriority_wrapper) .long SYSCALL(sys_ni_syscall,sys_ni_syscall) /* old profil syscall */ - .long SYSCALL(sys_statfs,sys32_statfs_wrapper) - .long SYSCALL(sys_fstatfs,sys32_fstatfs_wrapper) /* 100 */ + .long SYSCALL(sys_statfs,compat_sys_statfs_wrapper) + .long SYSCALL(sys_fstatfs,compat_sys_fstatfs_wrapper) /* 100 */ .long SYSCALL(sys_ni_syscall,sys_ni_syscall) .long SYSCALL(sys_socketcall,sys32_socketcall_wrapper) .long SYSCALL(sys_syslog,sys32_syslog_wrapper) diff --git a/arch/s390x/kernel/linux32.c b/arch/s390x/kernel/linux32.c index da4806a694bd..7a0c09af5d87 100644 --- a/arch/s390x/kernel/linux32.c +++ b/arch/s390x/kernel/linux32.c @@ -884,61 +884,6 @@ asmlinkage long sys32_fcntl64(unsigned int fd, unsigned int cmd, unsigned long a return sys32_fcntl(fd, cmd, arg); } -static inline int put_statfs (struct statfs32 *ubuf, struct statfs *kbuf) -{ - int err; - - err = put_user (kbuf->f_type, &ubuf->f_type); - err |= __put_user (kbuf->f_bsize, &ubuf->f_bsize); - err |= __put_user (kbuf->f_blocks, &ubuf->f_blocks); - err |= __put_user (kbuf->f_bfree, &ubuf->f_bfree); - err |= __put_user (kbuf->f_bavail, &ubuf->f_bavail); - err |= __put_user (kbuf->f_files, &ubuf->f_files); - err |= __put_user (kbuf->f_ffree, &ubuf->f_ffree); - err |= __put_user (kbuf->f_namelen, &ubuf->f_namelen); - err |= __put_user (kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]); - err |= __put_user (kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]); - return err; -} - -extern asmlinkage int sys_statfs(const char * path, struct statfs * buf); - -asmlinkage int sys32_statfs(const char * path, struct statfs32 *buf) -{ - int ret; - struct statfs s; - mm_segment_t old_fs = get_fs(); - char *pth; - - pth = getname (path); - ret = PTR_ERR(pth); - if (!IS_ERR(pth)) { - set_fs (KERNEL_DS); - ret = sys_statfs((const char *)pth, &s); - set_fs (old_fs); - putname (pth); - if (put_statfs(buf, &s)) - return -EFAULT; - } - return ret; -} - -extern asmlinkage int sys_fstatfs(unsigned int fd, struct statfs * buf); - -asmlinkage int sys32_fstatfs(unsigned int fd, struct statfs32 *buf) -{ - int ret; - struct statfs s; - mm_segment_t old_fs = get_fs(); - - set_fs (KERNEL_DS); - ret = sys_fstatfs(fd, &s); - set_fs (old_fs); - if (put_statfs(buf, &s)) - return -EFAULT; - return ret; -} - extern asmlinkage long sys_truncate(const char * path, unsigned long length); extern asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length); diff --git a/arch/s390x/kernel/linux32.h b/arch/s390x/kernel/linux32.h index 0c43c224c678..5d249c03cb75 100644 --- a/arch/s390x/kernel/linux32.h +++ b/arch/s390x/kernel/linux32.h @@ -25,19 +25,6 @@ struct ipc_kludge_32 { #define F_SETLK64 13 #define F_SETLKW64 14 -struct statfs32 { - __s32 f_type; - __s32 f_bsize; - __s32 f_blocks; - __s32 f_bfree; - __s32 f_bavail; - __s32 f_files; - __s32 f_ffree; - __kernel_fsid_t f_fsid; - __s32 f_namelen; - __s32 f_spare[6]; -}; - typedef __u32 old_sigset_t32; /* at least 32 bits */ struct old_sigaction32 { diff --git a/arch/s390x/kernel/wrapper32.S b/arch/s390x/kernel/wrapper32.S index 380d13fe4096..a50add0cf4f5 100644 --- a/arch/s390x/kernel/wrapper32.S +++ b/arch/s390x/kernel/wrapper32.S @@ -440,17 +440,17 @@ sys32_setpriority_wrapper: lgfr %r4,%r4 # int jg sys_setpriority # branch to system call - .globl sys32_statfs_wrapper -sys32_statfs_wrapper: + .globl compat_sys_statfs_wrapper +compat_sys_statfs_wrapper: llgtr %r2,%r2 # char * - llgtr %r3,%r3 # struct statfs_emu31 * - jg sys32_statfs # branch to system call + llgtr %r3,%r3 # struct compat_statfs * + jg compat_sys_statfs # branch to system call - .globl sys32_fstatfs_wrapper -sys32_fstatfs_wrapper: + .globl compat_sys_fstatfs_wrapper +compat_sys_fstatfs_wrapper: llgfr %r2,%r2 # unsigned int - llgtr %r3,%r3 # struct statfs_emu31 * - jg sys32_fstatfs # branch to system call + llgtr %r3,%r3 # struct compat_statfs * + jg compat_sys_fstatfs # branch to system call .globl sys32_socketcall_wrapper sys32_socketcall_wrapper: diff --git a/arch/s390x/vmlinux.lds.S b/arch/s390x/vmlinux.lds.S index 3aa2e0d1343f..c8766744dd25 100644 --- a/arch/s390x/vmlinux.lds.S +++ b/arch/s390x/vmlinux.lds.S @@ -30,6 +30,10 @@ SECTIONS __ksymtab : { *(__ksymtab) } __stop___ksymtab = .; + __start___gpl_ksymtab = .; /* Kernel symbol table: GPL-only symbols */ + __gpl_ksymtab : { *(__gpl_ksymtab) } + __stop___gpl_ksymtab = .; + #ifdef CONFIG_SHARED_KERNEL . = ALIGN(1048576); /* VM shared segments are 1MB aligned */ diff --git a/arch/sh/vmlinux.lds.S b/arch/sh/vmlinux.lds.S index eebc61c626ba..051d1c5db589 100644 --- a/arch/sh/vmlinux.lds.S +++ b/arch/sh/vmlinux.lds.S @@ -37,6 +37,10 @@ SECTIONS __ksymtab : { *(__ksymtab) } __stop___ksymtab = .; + __start___gpl_ksymtab = .; /* Kernel symbol table: GPL-only symbols */ + __gpl_ksymtab : { *(__gpl_ksymtab) } + __stop___gpl_ksymtab = .; + __start___kallsyms = .; /* All kernel symbols */ __kallsyms : { *(__kallsyms) } __stop___kallsyms = .; diff --git a/arch/sparc/vmlinux.lds.S b/arch/sparc/vmlinux.lds.S index a9343f993144..0c3ff57eccfe 100644 --- a/arch/sparc/vmlinux.lds.S +++ b/arch/sparc/vmlinux.lds.S @@ -35,6 +35,10 @@ SECTIONS __ksymtab : { *(__ksymtab) } __stop___ksymtab = .; + __start___gpl_ksymtab = .; + __gpl_ksymtab : { *(__gpl_ksymtab) } + __stop___gpl_ksymtab = .; + __start___kallsyms = .; /* All kernel symbols */ __kallsyms : { *(__kallsyms) } __stop___kallsyms = .; diff --git a/arch/sparc64/vmlinux.lds.S b/arch/sparc64/vmlinux.lds.S index 68b3827b6997..b20ac519366a 100644 --- a/arch/sparc64/vmlinux.lds.S +++ b/arch/sparc64/vmlinux.lds.S @@ -39,6 +39,9 @@ SECTIONS __start___ksymtab = .; __ksymtab : { *(__ksymtab) } __stop___ksymtab = .; + __start___gpl_ksymtab = .; + __gpl_ksymtab : { *(__gpl_ksymtab) } + __stop___gpl_ksymtab = .; __kstrtab : { *(.kstrtab) } __start___kallsyms = .; /* All kernel symbols */ __kallsyms : { *(__kallsyms) } diff --git a/arch/x86_64/vmlinux.lds.S b/arch/x86_64/vmlinux.lds.S index 08d1a8696e2d..a767b86aba8f 100644 --- a/arch/x86_64/vmlinux.lds.S +++ b/arch/x86_64/vmlinux.lds.S @@ -30,6 +30,9 @@ SECTIONS __start___ksymtab = .; /* Kernel symbol table */ __ksymtab : { *(__ksymtab) } __stop___ksymtab = .; + __start___gpl_ksymtab = .; /* Kernel symbol table: GPL-only symbols */ + __gpl_ksymtab : { *(__gpl_ksymtab) } + __stop___gpl_ksymtab = .; __start___kallsyms = .; /* All kernel symbols */ __kallsyms : { *(__kallsyms) } diff --git a/drivers/isdn/hisax/Kconfig b/drivers/isdn/hisax/Kconfig index 031b3bdca874..78cf51e98074 100644 --- a/drivers/isdn/hisax/Kconfig +++ b/drivers/isdn/hisax/Kconfig @@ -109,6 +109,7 @@ config HISAX_16_3 config HISAX_TELESPCI bool "Teles PCI" + depends on PCI help This enables HiSax support for the Teles PCI. See <file:Documentation/isdn/README.HiSax> on how to configure it. @@ -235,6 +236,7 @@ config HISAX_MIC config HISAX_NETJET bool "NETjet card" + depends on PCI help This enables HiSax support for the NetJet from Traverse Technologies. @@ -245,6 +247,7 @@ config HISAX_NETJET config HISAX_NETJET_U bool "NETspider U card" + depends on PCI help This enables HiSax support for the Netspider U interface ISDN card from Traverse Technologies. @@ -283,6 +286,7 @@ config HISAX_HSTSAPHIR config HISAX_BKM_A4T bool "Telekom A4T card" + depends on PCI help This enables HiSax support for the Telekom A4T card. @@ -292,6 +296,7 @@ config HISAX_BKM_A4T config HISAX_SCT_QUADRO bool "Scitel Quadro card" + depends on PCI help This enables HiSax support for the Scitel Quadro card. @@ -310,6 +315,7 @@ config HISAX_GAZEL config HISAX_HFC_PCI bool "HFC PCI-Bus cards" + depends on PCI help This enables HiSax support for the HFC-S PCI 2BDS0 based cards. @@ -318,6 +324,7 @@ config HISAX_HFC_PCI config HISAX_W6692 bool "Winbond W6692 based cards" + depends on PCI help This enables HiSax support for Winbond W6692 based PCI ISDN cards. @@ -335,7 +342,7 @@ config HISAX_HFC_SX config HISAX_ENTERNOW_PCI bool "Formula-n enter:now PCI card (EXPERIMENTAL)" - depends on EXPERIMENTAL + depends on PCI && EXPERIMENTAL help This enables HiSax support for the Formula-n enter:now PCI ISDN card. @@ -397,14 +404,14 @@ config HISAX_FRITZ_PCIPNP config HISAX_FRITZ_CLASSIC tristate "AVM Fritz!Card classic support (EXPERIMENTAL)" - depends on EXPERIMENTAL + depends on ISA && EXPERIMENTAL help This enables the driver for the AVM Fritz!Card classic, formerly known as AVM A1. config HISAX_HFCPCI tristate "HFC PCI support (EXPERIMENTAL)" - depends on EXPERIMENTAL + depends on PCI && EXPERIMENTAL help This enables the driver for CCD HFC PCI based cards. diff --git a/drivers/isdn/hisax/amd7930.c b/drivers/isdn/hisax/amd7930.c index 181ebf15e07a..e39d75fe1e35 100644 --- a/drivers/isdn/hisax/amd7930.c +++ b/drivers/isdn/hisax/amd7930.c @@ -686,31 +686,19 @@ static void init_amd7930(struct IsdnCardState *cs) Bchan_mode(cs->bcs + 1, 0, 0); } -void -release_amd7930(struct IsdnCardState *cs) -{ -} - static int -amd7930_card_msg(struct IsdnCardState *cs, int mt, void *arg) +amd7930_init(struct IsdnCardState *cs) { - switch (mt) { - case CARD_RESET: - return(0); - case CARD_RELEASE: - release_amd7930(cs); - return(0); - case CARD_INIT: - cs->l1cmd = amd7930_l1cmd; - amd7930_liu_init(0, &amd7930_liu_callback, (void *)cs); - init_amd7930(cs); - return(0); - case CARD_TEST: - return(0); - } - return(0); + cs->l1cmd = amd7930_l1cmd; + amd7930_liu_init(0, &amd7930_liu_callback, (void *)cs); + init_amd7930(cs); + return 0; } +static struct card_ops amd7930_ops = { + .init = amd7930_init, +}; + int __init setup_amd7930(struct IsdnCard *card) { @@ -719,14 +707,11 @@ setup_amd7930(struct IsdnCard *card) strcpy(tmp, amd7930_revision); printk(KERN_INFO "HiSax: AMD7930 driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_AMD7930) - return (0); cs->irq = amd7930_get_irqnum(0); if (cs->irq == 0) - return (0); - - cs->cardmsg = &amd7930_card_msg; + return 0; - return (1); + cs->card_ops = &amd7930_ops; + return 1; } diff --git a/drivers/isdn/hisax/amd7930_fn.c b/drivers/isdn/hisax/amd7930_fn.c index 02475d725b1f..40085c40e448 100644 --- a/drivers/isdn/hisax/amd7930_fn.c +++ b/drivers/isdn/hisax/amd7930_fn.c @@ -804,3 +804,12 @@ Amd7930_init(struct IsdnCardState *cs) } } } + +int +amd7930_setup(struct IsdnCardState *cs, struct dc_hw_ops *amd7930_ops, + void (*set_irq_mask)(struct IsdnCardState *, u8 val)) +{ + cs->dc_hw_ops = amd7930_ops; + cs->dc.amd7930.setIrqMask = set_irq_mask; + return 0; +} diff --git a/drivers/isdn/hisax/amd7930_fn.h b/drivers/isdn/hisax/amd7930_fn.h index 186186559f0b..7adb2a46aad6 100644 --- a/drivers/isdn/hisax/amd7930_fn.h +++ b/drivers/isdn/hisax/amd7930_fn.h @@ -18,5 +18,7 @@ #define DBUSY_TIMER_VALUE 80 -extern void Amd7930_interrupt(struct IsdnCardState *cs, unsigned char irflags); -extern void Amd7930_init(struct IsdnCardState *cs); +void Amd7930_interrupt(struct IsdnCardState *cs, unsigned char irflags); +void Amd7930_init(struct IsdnCardState *cs); +int amd7930_setup(struct IsdnCardState *cs, struct dc_hw_ops *amd7930_ops, + void (*set_irq_mask)(struct IsdnCardState *, u8 val)); diff --git a/drivers/isdn/hisax/asuscom.c b/drivers/isdn/hisax/asuscom.c index 83c0bbd5c930..da25348e3fa1 100644 --- a/drivers/isdn/hisax/asuscom.c +++ b/drivers/isdn/hisax/asuscom.c @@ -188,13 +188,6 @@ ipac_writefifo(struct IsdnCardState *cs, u8 off, u8 * data, int size) BUILD_IPAC_OPS(ipac); -static void -asuscom_release(struct IsdnCardState *cs) -{ - if (cs->hw.asus.cfg_reg) - release_region(cs->hw.asus.cfg_reg, 8); -} - static int asuscom_reset(struct IsdnCardState *cs) { @@ -224,23 +217,17 @@ asuscom_ipac_reset(struct IsdnCardState *cs) return 0; } -static int -Asus_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - return(0); -} - static struct card_ops asuscom_ops = { .init = inithscxisac, .reset = asuscom_reset, - .release = asuscom_release, + .release = hisax_release_resources, .irq_func = hscxisac_irq, }; static struct card_ops asuscom_ipac_ops = { .init = ipac_init, .reset = asuscom_ipac_reset, - .release = asuscom_release, + .release = hisax_release_resources, .irq_func = ipac_irq, }; @@ -275,8 +262,6 @@ setup_asuscom(struct IsdnCard *card) strcpy(tmp, Asuscom_revision); printk(KERN_INFO "HiSax: Asuscom ISDNLink driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_ASUSCOM) - return (0); #ifdef __ISAPNP__ if (!card->para[1] && isapnp_present()) { struct pnp_card *pb; @@ -328,28 +313,18 @@ setup_asuscom(struct IsdnCard *card) bytecnt = 8; cs->hw.asus.cfg_reg = card->para[1]; cs->irq = card->para[0]; - if (!request_region((cs->hw.asus.cfg_reg), bytecnt, - "asuscom isdn")) { - printk(KERN_WARNING - "HiSax: %s config port %x-%x already in use\n", - CardType[card->typ], - cs->hw.asus.cfg_reg, - cs->hw.asus.cfg_reg + bytecnt); - return (0); - } + if (!request_io(&cs->rs, cs->hw.asus.cfg_reg, bytecnt, "asuscom isdn")) + goto err; printk(KERN_INFO "ISDNLink: defined at 0x%x IRQ %d\n", cs->hw.asus.cfg_reg, cs->irq); - cs->cardmsg = &Asus_card_msg; cs->hw.asus.adr = cs->hw.asus.cfg_reg + ASUS_IPAC_ALE; val = readreg(cs, cs->hw.asus.cfg_reg + ASUS_IPAC_DATA, IPAC_ID); if ((val == 1) || (val == 2)) { cs->subtyp = ASUS_IPAC; cs->card_ops = &asuscom_ipac_ops; cs->hw.asus.isac = cs->hw.asus.cfg_reg + ASUS_IPAC_DATA; - cs->hw.asus.hscx = cs->hw.asus.cfg_reg + ASUS_IPAC_DATA; - cs->dc_hw_ops = &ipac_dc_ops; - cs->bc_hw_ops = &ipac_bc_ops; - printk(KERN_INFO "Asus: IPAC version %x\n", val); + if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops)) + goto err; } else { cs->subtyp = ASUS_ISACHSCX; cs->card_ops = &asuscom_ops; @@ -358,17 +333,13 @@ setup_asuscom(struct IsdnCard *card) cs->hw.asus.hscx = cs->hw.asus.cfg_reg + ASUS_HSCX; cs->hw.asus.u7 = cs->hw.asus.cfg_reg + ASUS_CTRL_U7; cs->hw.asus.pots = cs->hw.asus.cfg_reg + ASUS_CTRL_POTS; - cs->dc_hw_ops = &isac_ops; - cs->bc_hw_ops = &hscx_ops; - ISACVersion(cs, "ISDNLink:"); - if (HscxVersion(cs, "ISDNLink:")) { - printk(KERN_WARNING - "ISDNLink: wrong HSCX versions check IO address\n"); - asuscom_release(cs); - return (0); - } + if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) + goto err; } printk(KERN_INFO "ISDNLink: resetting card\n"); cs->card_ops->reset(cs); - return (1); + return 1; + err: + hisax_release_resources(cs); + return 0; } diff --git a/drivers/isdn/hisax/avm_a1.c b/drivers/isdn/hisax/avm_a1.c index 06b3c6c90e95..adea9b952125 100644 --- a/drivers/isdn/hisax/avm_a1.c +++ b/drivers/isdn/hisax/avm_a1.c @@ -146,30 +146,6 @@ avm_a1_interrupt(int intno, void *dev_id, struct pt_regs *regs) spin_unlock(&cs->lock); } -inline static void -release_ioregs(struct IsdnCardState *cs, int mask) -{ - release_region(cs->hw.avm.cfg_reg, 8); - if (mask & 1) - release_region(cs->hw.avm.isac + 32, 32); - if (mask & 2) - release_region(cs->hw.avm.isacfifo, 1); - if (mask & 4) - release_region(cs->hw.avm.hscx[0] + 32, 32); - if (mask & 8) - release_region(cs->hw.avm.hscxfifo[0], 1); - if (mask & 0x10) - release_region(cs->hw.avm.hscx[1] + 32, 32); - if (mask & 0x20) - release_region(cs->hw.avm.hscxfifo[1], 1); -} - -static int -AVM_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - return(0); -} - static void avm_a1_init(struct IsdnCardState *cs) { @@ -178,15 +154,9 @@ avm_a1_init(struct IsdnCardState *cs) inithscxisac(cs); } -static void -avm_a1_release(struct IsdnCardState *cs) -{ - release_ioregs(cs, 0x3f); -} - static struct card_ops avm_a1_ops = { .init = avm_a1_init, - .release = avm_a1_release, + .release = hisax_release_resources, .irq_func = avm_a1_interrupt, }; @@ -199,76 +169,26 @@ setup_avm_a1(struct IsdnCard *card) strcpy(tmp, avm_revision); printk(KERN_INFO "HiSax: AVM driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_A1) - return (0); - cs->hw.avm.cfg_reg = card->para[1] + 0x1800; - cs->hw.avm.isac = card->para[1] + 0x1400 - 0x20; - cs->hw.avm.hscx[0] = card->para[1] + 0x400 - 0x20; - cs->hw.avm.hscx[1] = card->para[1] + 0xc00 - 0x20; - cs->hw.avm.isacfifo = card->para[1] + 0x1000; - cs->hw.avm.hscxfifo[0] = card->para[1]; - cs->hw.avm.hscxfifo[1] = card->para[1] + 0x800; + cs->hw.avm.cfg_reg = request_io(&cs->rs, card->para[1] + 0x1800, 8, "avm cfg"); + if (!cs->hw.avm.cfg_reg) goto err; + cs->hw.avm.isac = request_io(&cs->rs, card->para[1] + 0x1400, 32, "HiSax isac"); + if (!cs->hw.avm.isac) goto err; + cs->hw.avm.isacfifo = request_io(&cs->rs, card->para[1] + 0x1000, 1, "HiSax isac fifo"); + if (!cs->hw.avm.isacfifo) goto err; + cs->hw.avm.hscx[0] = request_io(&cs->rs, card->para[1] + 0x400, 32, "HiSax hscx A"); + if (!cs->hw.avm.hscx[0]) goto err; + cs->hw.avm.hscxfifo[0] = request_io(&cs->rs, card->para[1], 1, "HiSax hscx A fifo"); + if (!cs->hw.avm.hscxfifo[0]) goto err; + cs->hw.avm.hscx[1] = request_io(&cs->rs, card->para[1] + 0xc00, 32, "HiSax hscx B"); + if (!cs->hw.avm.hscx[1]) goto err; + cs->hw.avm.hscxfifo[1] = request_io(&cs->rs, card->para[1] + 0x800, 1, "HiSax hscx B fifo"); + if (!cs->hw.avm.hscxfifo[1]) goto err; + cs->hw.avm.isac -= 0x20; + cs->hw.avm.hscx[0] -= 0x20; + cs->hw.avm.hscx[1] -= 0x20; cs->irq = card->para[0]; - if (!request_region(cs->hw.avm.cfg_reg, 8, "avm cfg")) { - printk(KERN_WARNING - "HiSax: %s config port %x-%x already in use\n", - CardType[card->typ], - cs->hw.avm.cfg_reg, - cs->hw.avm.cfg_reg + 8); - return (0); - } - if (!request_region(cs->hw.avm.isac + 32, 32, "HiSax isac")) { - printk(KERN_WARNING - "HiSax: %s isac ports %x-%x already in use\n", - CardType[cs->typ], - cs->hw.avm.isac + 32, - cs->hw.avm.isac + 64); - release_ioregs(cs, 0); - return (0); - } - if (!request_region(cs->hw.avm.isacfifo, 1, "HiSax isac fifo")) { - printk(KERN_WARNING - "HiSax: %s isac fifo port %x already in use\n", - CardType[cs->typ], - cs->hw.avm.isacfifo); - release_ioregs(cs, 1); - return (0); - } - if (!request_region(cs->hw.avm.hscx[0] + 32, 32, "HiSax hscx A")) { - printk(KERN_WARNING - "HiSax: %s hscx A ports %x-%x already in use\n", - CardType[cs->typ], - cs->hw.avm.hscx[0] + 32, - cs->hw.avm.hscx[0] + 64); - release_ioregs(cs, 3); - return (0); - } - if (!request_region(cs->hw.avm.hscxfifo[0], 1, "HiSax hscx A fifo")) { - printk(KERN_WARNING - "HiSax: %s hscx A fifo port %x already in use\n", - CardType[cs->typ], - cs->hw.avm.hscxfifo[0]); - release_ioregs(cs, 7); - return (0); - } - if (!request_region(cs->hw.avm.hscx[1] + 32, 32, "HiSax hscx B")) { - printk(KERN_WARNING - "HiSax: %s hscx B ports %x-%x already in use\n", - CardType[cs->typ], - cs->hw.avm.hscx[1] + 32, - cs->hw.avm.hscx[1] + 64); - release_ioregs(cs, 0xf); - return (0); - } - if (!request_region(cs->hw.avm.hscxfifo[1], 1, "HiSax hscx B fifo")) { - printk(KERN_WARNING - "HiSax: %s hscx B fifo port %x already in use\n", - CardType[cs->typ], - cs->hw.avm.hscxfifo[1]); - release_ioregs(cs, 0x1f); - return (0); - } + byteout(cs->hw.avm.cfg_reg, 0x0); HZDELAY(HZ / 5 + 1); byteout(cs->hw.avm.cfg_reg, 0x1); @@ -308,16 +228,11 @@ setup_avm_a1(struct IsdnCard *card) cs->hw.avm.hscx[0] + 32, cs->hw.avm.hscxfifo[0], cs->hw.avm.hscx[1] + 32, cs->hw.avm.hscxfifo[1]); - cs->dc_hw_ops = &isac_ops; - cs->bc_hw_ops = &hscx_ops; - cs->cardmsg = &AVM_card_msg; cs->card_ops = &avm_a1_ops; - ISACVersion(cs, "AVM A1:"); - if (HscxVersion(cs, "AVM A1:")) { - printk(KERN_WARNING - "AVM A1: wrong HSCX versions check IO address\n"); - release_ioregs(cs, 0x3f); - return (0); - } - return (1); + if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) + goto err; + return 1; + err: + hisax_release_resources(cs); + return 0; } diff --git a/drivers/isdn/hisax/avm_a1p.c b/drivers/isdn/hisax/avm_a1p.c index 3446b3cce953..3cac20543f0a 100644 --- a/drivers/isdn/hisax/avm_a1p.c +++ b/drivers/isdn/hisax/avm_a1p.c @@ -189,12 +189,6 @@ avm_a1p_interrupt(int intno, void *dev_id, struct pt_regs *regs) spin_unlock(&cs->lock); } -static int -AVM_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - return 0; -} - static void avm_a1p_init(struct IsdnCardState *cs) { @@ -231,10 +225,7 @@ setup_avm_a1_pcmcia(struct IsdnCard *card) strcpy(tmp, avm_revision); printk(KERN_INFO "HiSax: AVM A1 PCMCIA driver Rev. %s\n", - HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_A1_PCMCIA) - return (0); - + HiSax_getrev(tmp)); cs->hw.avm.cfg_reg = card->para[1]; cs->irq = card->para[0]; @@ -255,16 +246,9 @@ setup_avm_a1_pcmcia(struct IsdnCard *card) printk(KERN_INFO "AVM A1 PCMCIA: io 0x%x irq %d model %d version %d\n", cs->hw.avm.cfg_reg, cs->irq, model, vers); - cs->dc_hw_ops = &isac_ops; - cs->bc_hw_ops = &hscx_ops; - cs->cardmsg = &AVM_card_msg; cs->card_ops = &avm_a1p_ops; + if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) + return 0; - ISACVersion(cs, "AVM A1 PCMCIA:"); - if (HscxVersion(cs, "AVM A1 PCMCIA:")) { - printk(KERN_WARNING - "AVM A1 PCMCIA: wrong HSCX versions check IO address\n"); - return (0); - } - return (1); + return 1; } diff --git a/drivers/isdn/hisax/avm_pci.c b/drivers/isdn/hisax/avm_pci.c index 29e97538a842..2385f77a52f0 100644 --- a/drivers/isdn/hisax/avm_pci.c +++ b/drivers/isdn/hisax/avm_pci.c @@ -557,12 +557,6 @@ avm_pcipnp_interrupt(int intno, void *dev_id, struct pt_regs *regs) } static int -AVM_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - return(0); -} - -static int avm_pcipnp_reset(struct IsdnCardState *cs) { printk(KERN_INFO "AVM PCI/PnP: reset\n"); @@ -592,7 +586,7 @@ static void avm_pcipnp_release(struct IsdnCardState *cs) { outb(0, cs->hw.avm.cfg_reg + 2); - release_region(cs->hw.avm.cfg_reg, 32); + hisax_release_resources(cs); } static struct card_ops avm_pci_ops = { @@ -617,8 +611,6 @@ setup_avm_pcipnp(struct IsdnCard *card) strcpy(tmp, avm_pci_rev); printk(KERN_INFO "HiSax: AVM PCI driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_FRITZPCI) - return (0); if (card->para[1]) { /* old manual method */ cs->hw.avm.cfg_reg = card->para[1]; @@ -666,10 +658,6 @@ setup_avm_pcipnp(struct IsdnCard *card) } #endif #if CONFIG_PCI - if (!pci_present()) { - printk(KERN_ERR "FritzPCI: no PCI bus present\n"); - return(0); - } if ((dev_avm = pci_find_device(PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_A1, dev_avm))) { cs->irq = dev_avm->irq; @@ -690,22 +678,14 @@ setup_avm_pcipnp(struct IsdnCard *card) return(0); } cs->irq_flags |= SA_SHIRQ; -#else - printk(KERN_WARNING "FritzPCI: NO_PCI_BIOS\n"); - return (0); #endif /* CONFIG_PCI */ } ready: cs->hw.avm.isac = cs->hw.avm.cfg_reg + 0x10; - if (!request_region((cs->hw.avm.cfg_reg), 32, (cs->subtyp == AVM_FRITZ_PCI) - ? "avm PCI" : "avm PnP")) { - printk(KERN_WARNING - "HiSax: %s config port %x-%x already in use\n", - CardType[card->typ], - cs->hw.avm.cfg_reg, - cs->hw.avm.cfg_reg + 31); - return (0); - } + if (!request_io(&cs->rs, cs->hw.avm.cfg_reg, 32, + cs->subtyp == AVM_FRITZ_PCI ? "avm PCI" : "avm PnP")) + goto err; + switch (cs->subtyp) { case AVM_FRITZ_PCI: val = inl(cs->hw.avm.cfg_reg); @@ -724,11 +704,12 @@ ready: (cs->subtyp == AVM_FRITZ_PCI) ? "AVM Fritz!PCI" : "AVM Fritz!PnP", cs->irq, cs->hw.avm.cfg_reg); - cs->dc_hw_ops = &isac_ops; cs->bc_hw_ops = &hdlc_hw_ops; cs->bc_l1_ops = &hdlc_l1_ops; - cs->cardmsg = &AVM_card_msg; cs->card_ops = &avm_pci_ops; - ISACVersion(cs, (cs->subtyp == AVM_FRITZ_PCI) ? "AVM PCI:" : "AVM PnP:"); - return (1); + isac_setup(cs, &isac_ops); + return 1; + err: + hisax_release_resources(cs); + return 0; } diff --git a/drivers/isdn/hisax/bkm_a4t.c b/drivers/isdn/hisax/bkm_a4t.c index 67f59821b197..ce08c2b9442d 100644 --- a/drivers/isdn/hisax/bkm_a4t.c +++ b/drivers/isdn/hisax/bkm_a4t.c @@ -174,66 +174,47 @@ bkm_interrupt(int intno, void *dev_id, struct pt_regs *regs) spin_unlock(&cs->lock); } -void -release_io_bkm(struct IsdnCardState *cs) -{ - if (cs->hw.ax.base) { - iounmap((void *) cs->hw.ax.base); - cs->hw.ax.base = 0; - } -} - static void enable_bkm_int(struct IsdnCardState *cs, unsigned bEnable) { - if (cs->typ == ISDN_CTYPE_BKM_A4T) { - I20_REGISTER_FILE *pI20_Regs = (I20_REGISTER_FILE *) (cs->hw.ax.base); - if (bEnable) - pI20_Regs->i20IntCtrl |= (intISDN | intPCI); - else - /* CAUTION: This disables the video capture driver too */ - pI20_Regs->i20IntCtrl &= ~(intISDN | intPCI); - } + I20_REGISTER_FILE *pI20_Regs = (I20_REGISTER_FILE *) (cs->hw.ax.base); + if (bEnable) + pI20_Regs->i20IntCtrl |= (intISDN | intPCI); + else + /* CAUTION: This disables the video capture driver too */ + pI20_Regs->i20IntCtrl &= ~(intISDN | intPCI); } static void reset_bkm(struct IsdnCardState *cs) { - if (cs->typ == ISDN_CTYPE_BKM_A4T) { - I20_REGISTER_FILE *pI20_Regs = (I20_REGISTER_FILE *) (cs->hw.ax.base); - /* Issue the I20 soft reset */ - pI20_Regs->i20SysControl = 0xFF; /* all in */ - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout((10 * HZ) / 1000); - /* Remove the soft reset */ - pI20_Regs->i20SysControl = sysRESET | 0xFF; - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout((10 * HZ) / 1000); - /* Set our configuration */ - pI20_Regs->i20SysControl = sysRESET | sysCFG; - /* Issue ISDN reset */ - pI20_Regs->i20GuestControl = guestWAIT_CFG | - g_A4T_JADE_RES | - g_A4T_ISAR_RES | - g_A4T_ISAC_RES | - g_A4T_JADE_BOOTR | - g_A4T_ISAR_BOOTR; - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout((10 * HZ) / 1000); - - /* Remove RESET state from ISDN */ - pI20_Regs->i20GuestControl &= ~(g_A4T_ISAC_RES | - g_A4T_JADE_RES | - g_A4T_ISAR_RES); - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout((10 * HZ) / 1000); - } -} - -static int -BKM_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - return (0); + I20_REGISTER_FILE *pI20_Regs = (I20_REGISTER_FILE *) (cs->hw.ax.base); + /* Issue the I20 soft reset */ + pI20_Regs->i20SysControl = 0xFF; /* all in */ + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout((10 * HZ) / 1000); + /* Remove the soft reset */ + pI20_Regs->i20SysControl = sysRESET | 0xFF; + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout((10 * HZ) / 1000); + /* Set our configuration */ + pI20_Regs->i20SysControl = sysRESET | sysCFG; + /* Issue ISDN reset */ + pI20_Regs->i20GuestControl = guestWAIT_CFG | + g_A4T_JADE_RES | + g_A4T_ISAR_RES | + g_A4T_ISAC_RES | + g_A4T_JADE_BOOTR | + g_A4T_ISAR_BOOTR; + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout((10 * HZ) / 1000); + + /* Remove RESET state from ISDN */ + pI20_Regs->i20GuestControl &= ~(g_A4T_ISAC_RES | + g_A4T_JADE_RES | + g_A4T_ISAR_RES); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout((10 * HZ) / 1000); } static void @@ -257,9 +238,8 @@ bkm_a4t_reset(struct IsdnCardState *cs) static void bkm_a4t_release(struct IsdnCardState *cs) { - enable_bkm_int(cs, 0); reset_bkm(cs); - release_io_bkm(cs); + hisax_release_resources(cs); } static struct card_ops bkm_a4t_ops = { @@ -278,21 +258,9 @@ setup_bkm_a4t(struct IsdnCard *card) char tmp[64]; u_int pci_memaddr = 0, found = 0; I20_REGISTER_FILE *pI20_Regs; -#if CONFIG_PCI -#endif strcpy(tmp, bkm_a4t_revision); printk(KERN_INFO "HiSax: T-Berkom driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ == ISDN_CTYPE_BKM_A4T) { - cs->subtyp = BKM_A4T; - } else - return (0); - -#if CONFIG_PCI - if (!pci_present()) { - printk(KERN_ERR "bkm_a4t: no PCI bus present\n"); - return (0); - } while ((dev_a4t = pci_find_device(PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36120, dev_a4t))) { u16 sub_sys; @@ -317,40 +285,32 @@ setup_bkm_a4t(struct IsdnCard *card) printk(KERN_WARNING "HiSax: %s: No IRQ\n", CardType[card->typ]); return (0); } - if (!pci_memaddr) { + cs->hw.ax.base = (unsigned long)request_mmio(&cs->rs,pci_memaddr, 4096, "Telekom A4T"); + if (!cs->hw.ax.base) { printk(KERN_WARNING "HiSax: %s: No Memory base address\n", CardType[card->typ]); return (0); } - cs->hw.ax.base = (long) ioremap(pci_memaddr, 4096); + /* Check suspecious address */ pI20_Regs = (I20_REGISTER_FILE *) (cs->hw.ax.base); if ((pI20_Regs->i20IntStatus & 0x8EFFFFFF) != 0) { printk(KERN_WARNING "HiSax: %s address %lx-%lx suspecious\n", CardType[card->typ], cs->hw.ax.base, cs->hw.ax.base + 4096); - iounmap((void *) cs->hw.ax.base); - cs->hw.ax.base = 0; + hisax_release_resources(cs); return (0); } cs->hw.ax.isac_adr = cs->hw.ax.base + PO_OFFSET; cs->hw.ax.jade_adr = cs->hw.ax.base + PO_OFFSET; cs->hw.ax.isac_ale = GCS_1; cs->hw.ax.jade_ale = GCS_3; -#else - printk(KERN_WARNING "HiSax: %s: NO_PCI_BIOS\n", CardType[card->typ]); - printk(KERN_WARNING "HiSax: %s: unable to configure\n", CardType[card->typ]); - return (0); -#endif /* CONFIG_PCI */ + printk(KERN_INFO "HiSax: %s: Card configured at 0x%lX IRQ %d\n", CardType[card->typ], cs->hw.ax.base, cs->irq); reset_bkm(cs); - cs->dc_hw_ops = &isac_ops; - cs->bc_hw_ops = &jade_ops; - cs->cardmsg = &BKM_card_msg; cs->irq_flags |= SA_SHIRQ; cs->card_ops = &bkm_a4t_ops; - ISACVersion(cs, "Telekom A4T:"); - /* Jade version */ - JadeVersion(cs, "Telekom A4T:"); - return (1); + isac_setup(cs, &isac_ops); + jade_setup(cs, &jade_ops); + return 1; } diff --git a/drivers/isdn/hisax/bkm_a8.c b/drivers/isdn/hisax/bkm_a8.c index 64233fcba1ee..1d8b2c0beac5 100644 --- a/drivers/isdn/hisax/bkm_a8.c +++ b/drivers/isdn/hisax/bkm_a8.c @@ -20,8 +20,6 @@ #include <linux/pci.h> #include "bkm_ax.h" -#if CONFIG_PCI - #define ATTEMPT_PCI_REMAPPING /* Required for PLX rev 1 */ extern const char *CardType[]; @@ -98,23 +96,13 @@ set_ipac_active(struct IsdnCardState *cs, u_int active) ipac_write(cs, IPAC_MASK, active ? 0xc0 : 0xff); } -void -release_io_sct_quadro(struct IsdnCardState *cs) -{ - release_region(cs->hw.ax.base & 0xffffffc0, 128); - if (cs->subtyp == SCT_1) - release_region(cs->hw.ax.plx_adr, 64); -} - static void enable_bkm_int(struct IsdnCardState *cs, unsigned bEnable) { - if (cs->typ == ISDN_CTYPE_SCT_QUADRO) { - if (bEnable) - wordout(cs->hw.ax.plx_adr + 0x4C, (wordin(cs->hw.ax.plx_adr + 0x4C) | 0x41)); - else - wordout(cs->hw.ax.plx_adr + 0x4C, (wordin(cs->hw.ax.plx_adr + 0x4C) & ~0x41)); - } + if (bEnable) + wordout(cs->hw.ax.plx_adr + 0x4C, (wordin(cs->hw.ax.plx_adr + 0x4C) | 0x41)); + else + wordout(cs->hw.ax.plx_adr + 0x4C, (wordin(cs->hw.ax.plx_adr + 0x4C) & ~0x41)); } static void @@ -131,12 +119,6 @@ reset_bkm(struct IsdnCardState *cs) } } -static int -BKM_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - return (0); -} - static void bkm_a8_init(struct IsdnCardState *cs) { @@ -162,7 +144,7 @@ bkm_a8_release(struct IsdnCardState *cs) { set_ipac_active(cs, 0); enable_bkm_int(cs, 0); - release_io_sct_quadro(cs); + hisax_release_resources(cs); } static struct card_ops bkm_a8_ops = { @@ -172,29 +154,14 @@ static struct card_ops bkm_a8_ops = { .irq_func = ipac_irq, }; -int __init -sct_alloc_io(u_int adr, u_int len) -{ - if (!request_region(adr, len, "scitel")) { - printk(KERN_WARNING - "HiSax: Scitel port %#x-%#x already in use\n", - adr, adr + len); - return (1); - } - return(0); -} - static struct pci_dev *dev_a8 __initdata = NULL; static u16 sub_vendor_id __initdata = 0; static u16 sub_sys_id __initdata = 0; static u8 pci_irq __initdata = 0; -#endif /* CONFIG_PCI */ - int __init setup_sct_quadro(struct IsdnCard *card) { -#if CONFIG_PCI struct IsdnCardState *cs = card->cs; char tmp[64]; u8 pci_rev_id; @@ -203,11 +170,6 @@ setup_sct_quadro(struct IsdnCard *card) strcpy(tmp, sct_quadro_revision); printk(KERN_INFO "HiSax: T-Berkom driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ == ISDN_CTYPE_SCT_QUADRO) { - cs->subtyp = SCT_1; /* Preset */ - } else - return (0); - /* Identify subtype by para[0] */ if (card->para[0] >= SCT_1 && card->para[0] <= SCT_4) cs->subtyp = card->para[0]; @@ -220,10 +182,6 @@ setup_sct_quadro(struct IsdnCard *card) (sub_vendor_id != PCI_VENDOR_ID_BERKOM))) return (0); if (cs->subtyp == SCT_1) { - if (!pci_present()) { - printk(KERN_ERR "bkm_a4t: no PCI bus present\n"); - return (0); - } while ((dev_a8 = pci_find_device(PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, dev_a8))) { @@ -295,28 +253,28 @@ setup_sct_quadro(struct IsdnCard *card) cs->hw.ax.plx_adr = pci_ioaddr1; /* Enter all ipac_base addresses */ switch(cs->subtyp) { - case 1: - cs->hw.ax.base = pci_ioaddr5 + 0x00; - if (sct_alloc_io(pci_ioaddr1, 128)) - return(0); - if (sct_alloc_io(pci_ioaddr5, 64)) - return(0); - break; - case 2: - cs->hw.ax.base = pci_ioaddr4 + 0x08; - if (sct_alloc_io(pci_ioaddr4, 64)) - return(0); - break; - case 3: - cs->hw.ax.base = pci_ioaddr3 + 0x10; - if (sct_alloc_io(pci_ioaddr3, 64)) - return(0); - break; - case 4: - cs->hw.ax.base = pci_ioaddr2 + 0x20; - if (sct_alloc_io(pci_ioaddr2, 64)) - return(0); - break; + case 1: + cs->hw.ax.base = pci_ioaddr5 + 0x00; + if (!request_io(&cs->rs, pci_ioaddr1, 128, "scitel")) + goto err; + if (!request_io(&cs->rs, pci_ioaddr5, 64, "scitel")) + goto err; + break; + case 2: + cs->hw.ax.base = pci_ioaddr4 + 0x08; + if (!request_io(&cs->rs, pci_ioaddr4, 64, "scitel")) + goto err; + break; + case 3: + cs->hw.ax.base = pci_ioaddr3 + 0x10; + if (!request_io(&cs->rs, pci_ioaddr3, 64, "scitel")) + goto err; + break; + case 4: + cs->hw.ax.base = pci_ioaddr2 + 0x20; + if (!request_io(&cs->rs, pci_ioaddr2, 64, "scitel")) + goto err; + break; } cs->hw.ax.data_adr = cs->hw.ax.base + 4; ipac_write(cs, IPAC_MASK, 0xFF); @@ -329,17 +287,12 @@ setup_sct_quadro(struct IsdnCard *card) cs->hw.ax.data_adr, cs->irq); - cs->dc_hw_ops = &ipac_dc_ops; - cs->bc_hw_ops = &ipac_bc_ops; - cs->cardmsg = &BKM_card_msg; cs->card_ops = &bkm_a8_ops; + if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops)) + goto err; - printk(KERN_INFO "HiSax: %s (%s): IPAC Version %d\n", - CardType[card->typ], - sct_quadro_subtypes[cs->subtyp], - ipac_read(cs, IPAC_ID)); - return (1); -#else - printk(KERN_ERR "HiSax: bkm_a8 only supported on PCI Systems\n"); -#endif /* CONFIG_PCI */ + return 1; + err: + hisax_release_resources(cs); + return 0; } diff --git a/drivers/isdn/hisax/callc.c b/drivers/isdn/hisax/callc.c index 266a817889eb..bb7244198a9e 100644 --- a/drivers/isdn/hisax/callc.c +++ b/drivers/isdn/hisax/callc.c @@ -205,13 +205,49 @@ lli_deliver_cause(struct Channel *chanp) } static inline void +mdl_info_setup(struct Channel *chanp) +{ + if (chanp->chan) + chanp->cs->status |= 0x0200; + else + chanp->cs->status |= 0x0100; + + if (chanp->cs->card_ops->led_handler) + chanp->cs->card_ops->led_handler(chanp->cs); +} + +static inline void +mdl_info_connect(struct Channel *chanp) +{ + if (chanp->chan) + chanp->cs->status |= 0x2000; + else + chanp->cs->status |= 0x1000; + + if (chanp->cs->card_ops->led_handler) + chanp->cs->card_ops->led_handler(chanp->cs); +} + +static inline void +mdl_info_release(struct Channel *chanp) +{ + if (chanp->chan) + chanp->cs->status &= ~0x2200; + else + chanp->cs->status &= ~0x1100; + + if (chanp->cs->card_ops->led_handler) + chanp->cs->card_ops->led_handler(chanp->cs); +} + +static void lli_close(struct FsmInst *fi) { struct Channel *chanp = fi->userdata; FsmChangeState(fi, ST_NULL); chanp->Flags = 0; - chanp->cs->cardmsg(chanp->cs, MDL_INFO_REL, (void *) (long)chanp->chan); + mdl_info_release(chanp); } static void @@ -223,7 +259,8 @@ lli_leased_in(struct FsmInst *fi, int event, void *arg) if (!chanp->leased) return; - chanp->cs->cardmsg(chanp->cs, MDL_INFO_SETUP, (void *) (long)chanp->chan); + + mdl_info_setup(chanp); FsmChangeState(fi, ST_IN_WAIT_LL); if (chanp->debug & 1) link_debug(chanp, 0, "STAT_ICALL_LEASED"); @@ -240,7 +277,7 @@ lli_leased_in(struct FsmInst *fi, int event, void *arg) if (chanp->debug & 1) link_debug(chanp, 1, "statcallb ret=%d", ret); if (!ret) { - chanp->cs->cardmsg(chanp->cs, MDL_INFO_REL, (void *) (long)chanp->chan); + mdl_info_release(chanp); FsmChangeState(fi, ST_NULL); } } @@ -270,7 +307,7 @@ lli_prep_dialout(struct FsmInst *fi, int event, void *arg) FsmDelTimer(&chanp->dial_timer, 73); chanp->l2_active_protocol = chanp->l2_protocol; chanp->incoming = 0; - chanp->cs->cardmsg(chanp->cs, MDL_INFO_SETUP, (void *) (long)chanp->chan); + mdl_info_setup(chanp); if (chanp->leased) { lli_init_bchan_out(fi, event, arg); } else { @@ -288,7 +325,7 @@ lli_resume(struct FsmInst *fi, int event, void *arg) FsmDelTimer(&chanp->dial_timer, 73); chanp->l2_active_protocol = chanp->l2_protocol; chanp->incoming = 0; - chanp->cs->cardmsg(chanp->cs, MDL_INFO_SETUP, (void *) (long)chanp->chan); + mdl_info_setup(chanp); if (chanp->leased) { lli_init_bchan_out(fi, event, arg); } else { @@ -316,7 +353,7 @@ lli_go_active(struct FsmInst *fi, int event, void *arg) ic.command = ISDN_STAT_BCONN; ic.arg = chanp->chan; chanp->cs->iif.statcallb(&ic); - chanp->cs->cardmsg(chanp->cs, MDL_INFO_CONN, (void *) (long)chanp->chan); + mdl_info_connect(chanp); } @@ -333,7 +370,7 @@ lli_deliver_call(struct FsmInst *fi, int event, void *arg) isdn_ctrl ic; int ret; - chanp->cs->cardmsg(chanp->cs, MDL_INFO_SETUP, (void *) (long)chanp->chan); + mdl_info_setup(chanp); /* * Report incoming calls only once to linklevel, use CallFlags * which is set to 3 with each broadcast message in isdnl1.c @@ -381,13 +418,13 @@ lli_deliver_call(struct FsmInst *fi, int event, void *arg) case 0: /* OK, nobody likes this call */ default: /* statcallb problems */ L4L3(chanp->d_st, CC_IGNORE | REQUEST, chanp->proc); - chanp->cs->cardmsg(chanp->cs, MDL_INFO_REL, (void *) (long)chanp->chan); + mdl_info_release(chanp); FsmChangeState(fi, ST_NULL); break; } } else { L4L3(chanp->d_st, CC_IGNORE | REQUEST, chanp->proc); - chanp->cs->cardmsg(chanp->cs, MDL_INFO_REL, (void *) (long)chanp->chan); + mdl_info_release(chanp); } } @@ -730,7 +767,7 @@ lli_failure_l(struct FsmInst *fi, int event, void *arg) chanp->cs->iif.statcallb(&ic); HL_LL(chanp, ISDN_STAT_DHUP); chanp->Flags = 0; - chanp->cs->cardmsg(chanp->cs, MDL_INFO_REL, (void *) (long)chanp->chan); + mdl_info_release(chanp); } static void diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c index 6d853cb44780..1acb9a693f84 100644 --- a/drivers/isdn/hisax/config.c +++ b/drivers/isdn/hisax/config.c @@ -945,6 +945,7 @@ static int __devinit checkcard(int cardnr, char *id, int *busy_flag) cs->status_end = cs->status_buf + HISAX_STATUS_BUFSIZE - 1; cs->typ = card->typ; spin_lock_init(&cs->lock); + resources_init(&cs->rs); SET_MODULE_OWNER(&cs->iif); strcpy(cs->iif.id, id); cs->iif.channels = 2; @@ -1743,7 +1744,6 @@ static void hisax_d_l1l2(struct hisax_if *ifc, int pr, void *arg); static void hisax_b_l1l2(struct hisax_if *ifc, int pr, void *arg); static void hisax_d_l2l1(struct PStack *st, int pr, void *arg); static void hisax_b_l2l1(struct PStack *st, int pr, void *arg); -static int hisax_cardmsg(struct IsdnCardState *cs, int mt, void *arg); static int hisax_bc_setstack(struct PStack *st, struct BCState *bcs); static void hisax_bc_close(struct BCState *bcs); static void hisax_bh(void *data); @@ -1781,7 +1781,6 @@ int hisax_register(struct hisax_d_if *hisax_d_if, struct hisax_b_if *b_if[], cs = cards[i].cs; hisax_d_if->cs = cs; cs->hw.hisax_d_if = hisax_d_if; - cs->cardmsg = hisax_cardmsg; cs->iif.owner = hisax_d_if->owner; // FIXME should be done before registering dc_l1_init(cs, &hisax_l1_ops); cs->channel[0].d_st->l1.l2l1 = hisax_d_l2l1; @@ -1960,11 +1959,6 @@ static void hisax_d_l2l1(struct PStack *st, int pr, void *arg) } } -static int hisax_cardmsg(struct IsdnCardState *cs, int mt, void *arg) -{ - return 0; -} - static void hisax_b_l2l1(struct PStack *st, int pr, void *arg) { struct BCState *bcs = st->l1.bcs; @@ -2055,6 +2049,100 @@ static void EChannel_proc_rcv(struct hisax_d_if *d_if) } } +void +resources_init(struct resources *rs) +{ + INIT_LIST_HEAD(&rs->res_head); +} + +void +resources_release(struct resources *rs) +{ + struct res *r; + + list_for_each_entry(r, &rs->res_head, node) { + if (r->flags & IORESOURCE_IO) { + release_region(r->start, r->end - r->start + 1); + } + if (r->flags & IORESOURCE_MEM) { + iounmap(r->r_u.ioremap_addr); + release_mem_region(r->start, r->end - r->start + 1); + } + } +} + +unsigned long +request_io(struct resources *rs, unsigned long start, int len, + const char *name) +{ + struct res *r; + + r = kmalloc(sizeof(*r), GFP_KERNEL); + if (!r) { + printk(KERN_WARNING "%s: out of memory\n", __FUNCTION__); + goto err; + } + if (!request_region(start, len, name)) { + printk(KERN_WARNING "%s: IO %#lx-%#lx already in use\n", + __FUNCTION__, start, start + len - 1); + goto err_free; + } + r->flags = IORESOURCE_IO; + r->start = start; + r->end = start + len - 1; + r->name = name; + list_add_tail(&r->node, &rs->res_head); + + return r->start; + + err_free: + kfree(r); + err: + return 0; +} + +void * +request_mmio(struct resources *rs, unsigned long start, int len, + const char *name) +{ + struct res *r; + + r = kmalloc(sizeof(*r), GFP_KERNEL); + if (!r) { + printk(KERN_WARNING "%s: out of memory\n", __FUNCTION__); + goto err; + } + if (!request_mem_region(start, len, name)) { + printk(KERN_WARNING "%s: MMIO %#lx-%#lx already in use\n", + __FUNCTION__, start, start + len - 1); + goto err_free; + } + r->flags = IORESOURCE_MEM; + r->start = start; + r->end = start + len - 1; + r->name = name; + r->r_u.ioremap_addr = ioremap(start, len); + if (!r->r_u.ioremap_addr) + goto err_release; + + list_add_tail(&r->node, &rs->res_head); + + return r->r_u.ioremap_addr; + + err_release: + release_mem_region(r->start, r->end - r->start + 1); + err_free: + kfree(r); + err: + return 0; +} + +void +hisax_resources_release(struct IsdnCardState *cs) +{ + resources_release(&cs->rs); +} + #include <linux/pci.h> static struct pci_device_id hisax_pci_tbl[] __initdata = { diff --git a/drivers/isdn/hisax/diva.c b/drivers/isdn/hisax/diva.c index b5e7cf7bf5f3..09e5fe393311 100644 --- a/drivers/isdn/hisax/diva.c +++ b/drivers/isdn/hisax/diva.c @@ -362,25 +362,11 @@ diva_ipacx_pci_irq(int intno, void *dev_id, struct pt_regs *regs) static void diva_release(struct IsdnCardState *cs) { - int bytecnt; - del_timer(&cs->hw.diva.tl); if (cs->hw.diva.cfg_reg) byteout(cs->hw.diva.ctrl, 0); /* LED off, Reset */ - if (cs->subtyp == DIVA_ISA) - bytecnt = 8; - else - bytecnt = 32; - if (cs->hw.diva.cfg_reg) - release_region(cs->hw.diva.cfg_reg, bytecnt); -} - -static void -diva_ipac_isa_release(struct IsdnCardState *cs) -{ - if (cs->hw.diva.cfg_reg) - release_region(cs->hw.diva.cfg_reg, 8); + hisax_release_resources(cs); } static void @@ -388,8 +374,7 @@ diva_ipac_pci_release(struct IsdnCardState *cs) { writel(0, cs->hw.diva.pci_cfg); /* disable INT0/1 */ writel(2, cs->hw.diva.pci_cfg); /* reset pending INT0 */ - iounmap((void *)cs->hw.diva.cfg_reg); - iounmap((void *)cs->hw.diva.pci_cfg); + hisax_release_resources(cs); } static int @@ -458,20 +443,12 @@ diva_reset(struct IsdnCardState *cs) return 0; } -#define DIVA_ASSIGN 1 - static void diva_led_handler(struct IsdnCardState *cs) { int blink = 0; -// if ((cs->subtyp == DIVA_IPAC_ISA) || (cs->subtyp == DIVA_IPAC_PCI)) - if ((cs->subtyp == DIVA_IPAC_ISA) || - (cs->subtyp == DIVA_IPAC_PCI) || - (cs->subtyp == DIVA_IPACX_PCI) ) - return; - del_timer(&cs->hw.diva.tl); - if (cs->hw.diva.status & DIVA_ASSIGN) + if (cs->status & 0x0001) cs->hw.diva.ctrl_reg |= (DIVA_ISA == cs->subtyp) ? DIVA_ISA_LED_A : DIVA_PCI_LED_A; else { @@ -479,10 +456,10 @@ diva_led_handler(struct IsdnCardState *cs) DIVA_ISA_LED_A : DIVA_PCI_LED_A; blink = 250; } - if (cs->hw.diva.status & 0xf000) + if (cs->status & 0xf000) cs->hw.diva.ctrl_reg |= (DIVA_ISA == cs->subtyp) ? DIVA_ISA_LED_B : DIVA_PCI_LED_B; - else if (cs->hw.diva.status & 0x0f00) { + else if (cs->status & 0x0f00) { cs->hw.diva.ctrl_reg ^= (DIVA_ISA == cs->subtyp) ? DIVA_ISA_LED_B : DIVA_PCI_LED_B; blink = 500; @@ -491,50 +468,8 @@ diva_led_handler(struct IsdnCardState *cs) DIVA_ISA_LED_B : DIVA_PCI_LED_B); byteout(cs->hw.diva.ctrl, cs->hw.diva.ctrl_reg); - if (blink) { - init_timer(&cs->hw.diva.tl); - cs->hw.diva.tl.expires = jiffies + ((blink * HZ) / 1000); - add_timer(&cs->hw.diva.tl); - } -} - -static int -Diva_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - switch (mt) { - case (MDL_REMOVE | REQUEST): - cs->hw.diva.status = 0; - break; - case (MDL_ASSIGN | REQUEST): - cs->hw.diva.status |= DIVA_ASSIGN; - break; - case MDL_INFO_SETUP: - if ((long)arg) - cs->hw.diva.status |= 0x0200; - else - cs->hw.diva.status |= 0x0100; - break; - case MDL_INFO_CONN: - if ((long)arg) - cs->hw.diva.status |= 0x2000; - else - cs->hw.diva.status |= 0x1000; - break; - case MDL_INFO_REL: - if ((long)arg) { - cs->hw.diva.status &= ~0x2000; - cs->hw.diva.status &= ~0x0200; - } else { - cs->hw.diva.status &= ~0x1000; - cs->hw.diva.status &= ~0x0100; - } - break; - } - if ((cs->subtyp != DIVA_IPAC_ISA) && - (cs->subtyp != DIVA_IPAC_PCI) && - (cs->subtyp != DIVA_IPACX_PCI) ) - diva_led_handler(cs); - return(0); + if (blink) + mod_timer(&cs->hw.diva.tl, jiffies + (blink * HZ) / 1000); } static void @@ -552,31 +487,32 @@ diva_ipac_pci_init(struct IsdnCardState *cs) } static struct card_ops diva_ops = { - .init = inithscxisac, - .reset = diva_reset, - .release = diva_release, - .irq_func = diva_interrupt, + .init = inithscxisac, + .reset = diva_reset, + .release = diva_release, + .led_handler = diva_led_handler, + .irq_func = diva_interrupt, }; static struct card_ops diva_ipac_isa_ops = { - .init = ipac_init, - .reset = diva_ipac_isa_reset, - .release = diva_ipac_isa_release, - .irq_func = ipac_irq, + .init = ipac_init, + .reset = diva_ipac_isa_reset, + .release = hisax_release_resources, + .irq_func = ipac_irq, }; static struct card_ops diva_ipac_pci_ops = { - .init = diva_ipac_pci_init, - .reset = diva_ipac_pci_reset, - .release = diva_ipac_pci_release, - .irq_func = diva_ipac_pci_irq, + .init = diva_ipac_pci_init, + .reset = diva_ipac_pci_reset, + .release = diva_ipac_pci_release, + .irq_func = diva_ipac_pci_irq, }; static struct card_ops diva_ipacx_pci_ops = { - .init = diva_ipacx_pci_init, - .reset = diva_ipacx_pci_reset, - .release = diva_ipac_pci_release, - .irq_func = diva_ipacx_pci_irq, + .init = diva_ipacx_pci_init, + .reset = diva_ipacx_pci_reset, + .release = diva_ipac_pci_release, + .irq_func = diva_ipacx_pci_irq, }; static struct pci_dev *dev_diva __initdata = NULL; @@ -620,9 +556,6 @@ setup_diva(struct IsdnCard *card) strcpy(tmp, Diva_revision); printk(KERN_INFO "HiSax: Eicon.Diehl Diva driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_DIEHLDIVA) - return(0); - cs->hw.diva.status = 0; if (card->para[1]) { cs->hw.diva.ctrl_reg = 0; cs->hw.diva.cfg_reg = card->para[1]; @@ -721,11 +654,6 @@ setup_diva(struct IsdnCard *card) } #endif #if CONFIG_PCI - if (!pci_present()) { - printk(KERN_ERR "Diva: no PCI bus present\n"); - return(0); - } - cs->subtyp = 0; if ((dev_diva = pci_find_device(PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_DIVA20, dev_diva))) { @@ -747,10 +675,8 @@ setup_diva(struct IsdnCard *card) return(0); cs->subtyp = DIVA_IPAC_PCI; cs->irq = dev_diva201->irq; - cs->hw.diva.pci_cfg = - (ulong) ioremap(pci_resource_start(dev_diva201, 0), 4096); - cs->hw.diva.cfg_reg = - (ulong) ioremap(pci_resource_start(dev_diva201, 1), 4096); + cs->hw.diva.pci_cfg = (unsigned long)request_mmio(&cs->rs, pci_resource_start(dev_diva201, 0), 4096, "diva"); + cs->hw.diva.cfg_reg = (unsigned long)request_mmio(&cs->rs, pci_resource_start(dev_diva201, 1), 4096, "diva"); } else { printk(KERN_WARNING "Diva: No PCI card found\n"); return(0); @@ -758,18 +684,14 @@ setup_diva(struct IsdnCard *card) if (!cs->irq) { printk(KERN_WARNING "Diva: No IRQ for PCI card found\n"); - return(0); + goto err; } if (!cs->hw.diva.cfg_reg) { printk(KERN_WARNING "Diva: No IO-Adr for PCI card found\n"); - return(0); + goto err; } cs->irq_flags |= SA_SHIRQ; -#else - printk(KERN_WARNING "Diva: cfgreg 0 and NO_PCI_BIOS\n"); - printk(KERN_WARNING "Diva: unable to config DIVA PCI\n"); - return (0); #endif /* CONFIG_PCI */ if ((cs->subtyp == DIVA_IPAC_PCI) || (cs->subtyp == DIVA_IPACX_PCI) ) { @@ -805,54 +727,36 @@ ready: cs->hw.diva.pci_cfg); if ((cs->subtyp != DIVA_IPAC_PCI) && (cs->subtyp != DIVA_IPACX_PCI) ) { - if (check_region(cs->hw.diva.cfg_reg, bytecnt)) { - printk(KERN_WARNING - "HiSax: %s config port %lx-%lx already in use\n", - CardType[card->typ], - cs->hw.diva.cfg_reg, - cs->hw.diva.cfg_reg + bytecnt); - return (0); - } else { - request_region(cs->hw.diva.cfg_reg, bytecnt, "diva isdn"); - } + if (!request_io(&cs->rs, cs->hw.diva.cfg_reg, bytecnt, "diva isdn")) + return 0; } - cs->cardmsg = &Diva_card_msg; if (cs->subtyp == DIVA_IPAC_ISA) { diva_ipac_isa_reset(cs); - cs->dc_hw_ops = &ipac_dc_ops; - cs->bc_hw_ops = &ipac_bc_ops; cs->card_ops = &diva_ipac_isa_ops; - val = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_ID); - printk(KERN_INFO "Diva: IPAC version %x\n", val); + if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops)) + goto err; } else if (cs->subtyp == DIVA_IPAC_PCI) { diva_ipac_pci_reset(cs); - cs->dc_hw_ops = &mem_ipac_dc_ops; - cs->bc_hw_ops = &mem_ipac_bc_ops; cs->card_ops = &diva_ipac_pci_ops; - val = memreadreg(cs->hw.diva.cfg_reg, IPAC_ID); - printk(KERN_INFO "Diva: IPAC version %x\n", val); + if (ipac_setup(cs, &mem_ipac_dc_ops, &mem_ipac_bc_ops)) + goto err; } else if (cs->subtyp == DIVA_IPACX_PCI) { diva_ipacx_pci_reset(cs); - cs->dc_hw_ops = &ipacx_dc_ops; - cs->bc_hw_ops = &ipacx_bc_ops; cs->card_ops = &diva_ipacx_pci_ops; - printk(KERN_INFO "Diva: IPACX Design Id: %x\n", - ipacx_dc_read(cs, IPACX_ID) &0x3F); + if (ipacx_setup(cs, &ipacx_dc_ops, &ipacx_bc_ops)) + goto err; } else { /* DIVA 2.0 */ diva_reset(cs); cs->hw.diva.tl.function = (void *) diva_led_handler; cs->hw.diva.tl.data = (long) cs; init_timer(&cs->hw.diva.tl); - cs->dc_hw_ops = &isac_ops; - cs->bc_hw_ops = &hscx_ops; cs->card_ops = &diva_ops; - ISACVersion(cs, "Diva:"); - if (HscxVersion(cs, "Diva:")) { - printk(KERN_WARNING - "Diva: wrong HSCX versions check IO address\n"); - diva_release(cs); - return (0); - } + if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) + goto err; } - return (1); + return 1; + err: + diva_release(cs); + return 0; + } diff --git a/drivers/isdn/hisax/elsa.c b/drivers/isdn/hisax/elsa.c index b2917064c3cb..645257c744bb 100644 --- a/drivers/isdn/hisax/elsa.c +++ b/drivers/isdn/hisax/elsa.c @@ -106,7 +106,6 @@ const char *ITACVer[] = /* Status Flags */ #define ELSA_TIMER_AKTIV 1 #define ELSA_BAD_PWR 2 -#define ELSA_ASSIGN 4 #define RS_ISR_PASS_LIMIT 256 #define _INLINE_ inline @@ -387,8 +386,6 @@ elsa_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs) static void elsa_release(struct IsdnCardState *cs) { - int bytecnt = 8; - del_timer(&cs->hw.elsa.tl); #if ARCOFI_USE clear_arcofi(cs); @@ -398,28 +395,23 @@ elsa_release(struct IsdnCardState *cs) if (cs->subtyp == ELSA_QS1000PCI) { byteout(cs->hw.elsa.cfg + 0x4c, 0x01); /* disable IRQ */ writereg(cs, cs->hw.elsa.isac, IPAC_ATX, 0xff); - bytecnt = 2; - release_region(cs->hw.elsa.cfg, 0x80); } if (cs->subtyp == ELSA_QS3000PCI) { byteout(cs->hw.elsa.cfg + 0x4c, 0x03); /* disable ELSA PCI IRQ */ writereg(cs, cs->hw.elsa.isac, IPAC_ATX, 0xff); - release_region(cs->hw.elsa.cfg, 0x80); } if (cs->subtyp == ELSA_PCMCIA_IPAC) { writereg(cs, cs->hw.elsa.isac, IPAC_ATX, 0xff); } +#if ARCOFI_USE if ((cs->subtyp == ELSA_PCFPRO) || (cs->subtyp == ELSA_QS3000) || (cs->subtyp == ELSA_PCF) || (cs->subtyp == ELSA_QS3000PCI)) { - bytecnt = 16; -#if ARCOFI_USE release_modem(cs); -#endif } - if (cs->hw.elsa.base) - release_region(cs->hw.elsa.base, bytecnt); +#endif + hisax_release_resources(cs); } static int @@ -532,28 +524,14 @@ check_arcofi(struct IsdnCardState *cs) "Elsa: %s detected modem at 0x%lx\n", Elsa_Types[cs->subtyp], cs->hw.elsa.base+8); - release_region(cs->hw.elsa.base, 8); - if (!request_region(cs->hw.elsa.base, 16,"elsa isdn modem")) { - printk(KERN_WARNING - "HiSax: %s config port %lx-%lx already in use\n", - Elsa_Types[cs->subtyp], - cs->hw.elsa.base + 8, - cs->hw.elsa.base + 16); - } + request_io(&cs->rs, cs->hw.elsa.base+8, 8, "elsa isdn modem"); } else if (cs->subtyp==ELSA_PCC16) { cs->subtyp = ELSA_PCF; printk(KERN_INFO "Elsa: %s detected modem at 0x%lx\n", Elsa_Types[cs->subtyp], cs->hw.elsa.base+8); - release_region(cs->hw.elsa.base, 8); - if (!request_region(cs->hw.elsa.base, 16,"elsa isdn modem")) { - printk(KERN_WARNING - "HiSax: %s config port %lx-%lx already in use\n", - Elsa_Types[cs->subtyp], - cs->hw.elsa.base + 8, - cs->hw.elsa.base + 16); - } + request_io(&cs->rs, cs->hw.elsa.base+8, 8, "elsa isdn modem"); } else printk(KERN_INFO "Elsa: %s detected modem at 0x%lx\n", @@ -574,8 +552,15 @@ elsa_led_handler(struct IsdnCardState *cs) if (cs->subtyp == ELSA_PCMCIA || cs->subtyp == ELSA_PCMCIA_IPAC) return; - del_timer(&cs->hw.elsa.tl); - if (cs->hw.elsa.status & ELSA_ASSIGN) + + if (cs->typ == ISDN_CTYPE_ELSA) { + int pwr = bytein(cs->hw.elsa.ale); + if (pwr & 0x08) + cs->hw.elsa.status |= ELSA_BAD_PWR; + else + cs->hw.elsa.status &= ~ELSA_BAD_PWR; + } + if (cs->status & 0x0001) cs->hw.elsa.ctrl_reg |= ELSA_STAT_LED; else if (cs->hw.elsa.status & ELSA_BAD_PWR) cs->hw.elsa.ctrl_reg &= ~ELSA_STAT_LED; @@ -583,9 +568,9 @@ elsa_led_handler(struct IsdnCardState *cs) cs->hw.elsa.ctrl_reg ^= ELSA_STAT_LED; blink = 250; } - if (cs->hw.elsa.status & 0xf000) + if (cs->status & 0xf000) cs->hw.elsa.ctrl_reg |= ELSA_LINE_LED; - else if (cs->hw.elsa.status & 0x0f00) { + else if (cs->status & 0x0f00) { cs->hw.elsa.ctrl_reg ^= ELSA_LINE_LED; blink = 500; } else @@ -601,56 +586,9 @@ elsa_led_handler(struct IsdnCardState *cs) writereg(cs, cs->hw.elsa.isac, IPAC_ATX, led); } else byteout(cs->hw.elsa.ctrl, cs->hw.elsa.ctrl_reg); - if (blink) { - init_timer(&cs->hw.elsa.tl); - cs->hw.elsa.tl.expires = jiffies + ((blink * HZ) / 1000); - add_timer(&cs->hw.elsa.tl); - } -} -static int -Elsa_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - int ret = 0; - - switch (mt) { - case (MDL_REMOVE | REQUEST): - cs->hw.elsa.status &= 0; - break; - case (MDL_ASSIGN | REQUEST): - cs->hw.elsa.status |= ELSA_ASSIGN; - break; - case MDL_INFO_SETUP: - if ((long) arg) - cs->hw.elsa.status |= 0x0200; - else - cs->hw.elsa.status |= 0x0100; - break; - case MDL_INFO_CONN: - if ((long) arg) - cs->hw.elsa.status |= 0x2000; - else - cs->hw.elsa.status |= 0x1000; - break; - case MDL_INFO_REL: - if ((long) arg) { - cs->hw.elsa.status &= ~0x2000; - cs->hw.elsa.status &= ~0x0200; - } else { - cs->hw.elsa.status &= ~0x1000; - cs->hw.elsa.status &= ~0x0100; - } - break; - } - if (cs->typ == ISDN_CTYPE_ELSA) { - int pwr = bytein(cs->hw.elsa.ale); - if (pwr & 0x08) - cs->hw.elsa.status |= ELSA_BAD_PWR; - else - cs->hw.elsa.status &= ~ELSA_BAD_PWR; - } - elsa_led_handler(cs); - return(ret); + if (blink) + mod_timer(&cs->hw.elsa.tl, jiffies + (blink * HZ) / 1000); } #if ARCOFI_USE @@ -733,21 +671,23 @@ elsa_test(struct IsdnCardState *cs) } static struct card_ops elsa_ops = { - .init = elsa_init, - .test = elsa_test, - .reset = elsa_reset, - .release = elsa_release, - .aux_ind = elsa_aux_ind, - .irq_func = elsa_interrupt, + .init = elsa_init, + .test = elsa_test, + .reset = elsa_reset, + .release = elsa_release, + .aux_ind = elsa_aux_ind, + .led_handler = elsa_led_handler, + .irq_func = elsa_interrupt, }; static struct card_ops elsa_ipac_ops = { - .init = elsa_ipac_init, - .test = elsa_test, - .reset = elsa_reset, - .release = elsa_release, - .aux_ind = elsa_aux_ind, - .irq_func = elsa_interrupt_ipac, + .init = elsa_ipac_init, + .test = elsa_test, + .reset = elsa_reset, + .release = elsa_release, + .aux_ind = elsa_aux_ind, + .led_handler = elsa_led_handler, + .irq_func = elsa_interrupt_ipac, }; static unsigned char @@ -1002,10 +942,6 @@ setup_elsa(struct IsdnCard *card) cs->irq); } else if (cs->typ == ISDN_CTYPE_ELSA_PCI) { #if CONFIG_PCI - if (!pci_present()) { - printk(KERN_ERR "Elsa: no PCI bus present\n"); - return(0); - } cs->subtyp = 0; if ((dev_qs1000 = pci_find_device(PCI_VENDOR_ID_ELSA, PCI_DEVICE_ID_ELSA_MICROLINK, dev_qs1000))) { @@ -1054,10 +990,6 @@ setup_elsa(struct IsdnCard *card) cs->hw.elsa.base, cs->hw.elsa.cfg, cs->irq); -#else - printk(KERN_WARNING "Elsa: Elsa PCI and NO_PCI_BIOS\n"); - printk(KERN_WARNING "Elsa: unable to config Elsa PCI\n"); - return (0); #endif /* CONFIG_PCI */ } else return (0); @@ -1089,29 +1021,17 @@ setup_elsa(struct IsdnCard *card) reserved for us by the card manager. So we do not check it here, it would fail. */ if (cs->typ != ISDN_CTYPE_ELSA_PCMCIA) - if (!request_region(cs->hw.elsa.base, bytecnt, "elsa isdn")) { - printk(KERN_WARNING - "HiSax: %s config port %#lx-%#lx already in use\n", - CardType[card->typ], - cs->hw.elsa.base, - cs->hw.elsa.base + bytecnt); - return (0); - } + if (!request_io(&cs->rs, cs->hw.elsa.base, bytecnt, "elsa isdn")) + goto err; - if ((cs->subtyp == ELSA_QS1000PCI) || (cs->subtyp == ELSA_QS3000PCI)) { - if (!request_region(cs->hw.elsa.cfg, 0x80, "elsa isdn pci")) { - printk(KERN_WARNING - "HiSax: %s pci port %x-%x already in use\n", - CardType[card->typ], - cs->hw.elsa.cfg, - cs->hw.elsa.cfg + 0x80); - release_region(cs->hw.elsa.base, bytecnt); - return (0); - } - } + if ((cs->subtyp == ELSA_QS1000PCI) || (cs->subtyp == ELSA_QS3000PCI)) + if (!request_io(&cs->rs, cs->hw.elsa.cfg, 0x80, "elsa isdn pci")) + goto err; + #if ARCOFI_USE init_arcofi(cs); #endif + cs->hw.elsa.tl.function = (void *) elsa_led_handler; cs->hw.elsa.tl.data = (long) cs; init_timer(&cs->hw.elsa.tl); @@ -1124,37 +1044,25 @@ setup_elsa(struct IsdnCard *card) if (!TimerRun(cs)) { printk(KERN_WARNING "Elsa: timer do not start\n"); - elsa_release(cs); - return (0); + goto err; } } HZDELAY(1); /* wait >=10 ms */ if (TimerRun(cs)) { printk(KERN_WARNING "Elsa: timer do not run down\n"); - elsa_release(cs); - return (0); + goto err; } printk(KERN_INFO "Elsa: timer OK; resetting card\n"); } - cs->cardmsg = &Elsa_card_msg; elsa_reset(cs); if ((cs->subtyp == ELSA_QS1000PCI) || (cs->subtyp == ELSA_QS3000PCI) || (cs->subtyp == ELSA_PCMCIA_IPAC)) { - cs->dc_hw_ops = &ipac_dc_ops; - cs->bc_hw_ops = &ipac_bc_ops; cs->card_ops = &elsa_ipac_ops; - val = readreg(cs, cs->hw.elsa.isac, IPAC_ID); - printk(KERN_INFO "Elsa: IPAC version %x\n", val); + if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops)) + goto err; } else { - cs->dc_hw_ops = &isac_ops; - cs->bc_hw_ops = &hscx_ops; cs->card_ops = &elsa_ops; - ISACVersion(cs, "Elsa:"); - if (HscxVersion(cs, "Elsa:")) { - printk(KERN_WARNING - "Elsa: wrong HSCX versions check IO address\n"); - elsa_release(cs); - return (0); - } + if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) + goto err; } if (cs->subtyp == ELSA_PC) { val = readitac(cs, ITAC_SYS); @@ -1165,5 +1073,8 @@ setup_elsa(struct IsdnCard *card) writeitac(cs, ITAC_SCIE, 0); writeitac(cs, ITAC_STIE, 0); } - return (1); + return 1; + err: + elsa_release(cs); + return 0; } diff --git a/drivers/isdn/hisax/enternow_pci.c b/drivers/isdn/hisax/enternow_pci.c index 8813c016fd18..913ff14167c8 100644 --- a/drivers/isdn/hisax/enternow_pci.c +++ b/drivers/isdn/hisax/enternow_pci.c @@ -110,13 +110,14 @@ WriteByteAmd7930(struct IsdnCardState *cs, BYTE offset, BYTE value) } -static struct dc_hw_ops enternow_ops = { +static struct dc_hw_ops amd7930_ops = { .read_reg = ReadByteAmd7930, .write_reg = WriteByteAmd7930, }; -void -enpci_setIrqMask(struct IsdnCardState *cs, BYTE val) { +static void +enpci_setIrqMask(struct IsdnCardState *cs, BYTE val) +{ if (!val) OutByte(cs->hw.njet.base+NETJET_IRQMASK1, 0x00); else @@ -152,57 +153,44 @@ reset_enpci(struct IsdnCardState *cs) OutByte(cs->hw.njet.auxa, cs->hw.njet.auxd); // LED off } - -static int -enpci_card_msg(struct IsdnCardState *cs, int mt, void *arg) +static void +enpci_bc_activate(struct IsdnCardState *cs, int chan) { - BYTE *chan; + if (cs->debug & L1_DEB_ISAC) + debugl1(cs, "enter:now PCI: assign phys. BC %d in AMD LMR1", chan); + + cs->dc.amd7930.ph_command(cs, (cs->dc.amd7930.lmr1 | (chan + 1)), "MDL_BC_ASSIGN"); + /* at least one b-channel in use, LED 2 on */ + cs->hw.njet.auxd |= TJ_AMD_IRQ << 2; + OutByte(cs->hw.njet.base + NETJET_AUXDATA, cs->hw.njet.auxd); +} +static void +enpci_bc_deactivate(struct IsdnCardState *cs, int chan) +{ if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "enter:now PCI: card_msg: 0x%04X", mt); - - switch (mt) { - case MDL_ASSIGN: - /* TEI assigned, LED1 on */ - cs->hw.njet.auxd = TJ_AMD_IRQ << 1; - OutByte(cs->hw.njet.base + NETJET_AUXDATA, cs->hw.njet.auxd); - break; - case MDL_REMOVE: - /* TEI removed, LEDs off */ - cs->hw.njet.auxd = 0; - OutByte(cs->hw.njet.base + NETJET_AUXDATA, 0x00); - break; - case MDL_BC_ASSIGN: - /* activate B-channel */ - chan = (BYTE *)arg; - - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "enter:now PCI: assign phys. BC %d in AMD LMR1", *chan); - - cs->dc.amd7930.ph_command(cs, (cs->dc.amd7930.lmr1 | (*chan + 1)), "MDL_BC_ASSIGN"); - /* at least one b-channel in use, LED 2 on */ - cs->hw.njet.auxd |= TJ_AMD_IRQ << 2; - OutByte(cs->hw.njet.base + NETJET_AUXDATA, cs->hw.njet.auxd); - break; - case MDL_BC_RELEASE: - /* deactivate B-channel */ - chan = (BYTE *)arg; - - if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "enter:now PCI: release phys. BC %d in Amd LMR1", *chan); - - cs->dc.amd7930.ph_command(cs, (cs->dc.amd7930.lmr1 & ~(*chan + 1)), "MDL_BC_RELEASE"); - /* no b-channel active -> LED2 off */ - if (!(cs->dc.amd7930.lmr1 & 3)) { - cs->hw.njet.auxd &= ~(TJ_AMD_IRQ << 2); - OutByte(cs->hw.njet.base + NETJET_AUXDATA, cs->hw.njet.auxd); - } - break; - default: - break; + debugl1(cs, "enter:now PCI: release phys. BC %d in Amd LMR1", chan); + + cs->dc.amd7930.ph_command(cs, (cs->dc.amd7930.lmr1 & ~(chan + 1)), "MDL_BC_RELEASE"); + /* no b-channel active -> LED2 off */ + if (!(cs->dc.amd7930.lmr1 & 3)) { + cs->hw.njet.auxd &= ~(TJ_AMD_IRQ << 2); + OutByte(cs->hw.njet.base + NETJET_AUXDATA, cs->hw.njet.auxd); + } +} +static void +enpci_led_handler(struct IsdnCardState *cs) +{ + if (cs->status & 0x0001) { + /* TEI assigned, LED1 on */ + cs->hw.njet.auxd = TJ_AMD_IRQ << 1; + OutByte(cs->hw.njet.base + NETJET_AUXDATA, cs->hw.njet.auxd); + } else { + /* TEI removed, LEDs off */ + cs->hw.njet.auxd = 0; + OutByte(cs->hw.njet.base + NETJET_AUXDATA, 0x00); } - return(0); } static void @@ -268,10 +256,11 @@ enpci_interrupt(int intno, void *dev_id, struct pt_regs *regs) } static struct card_ops enpci_ops = { - .init = enpci_init, - .reset = enpci_reset, - .release = netjet_release, - .irq_func = enpci_interrupt, + .init = enpci_init, + .reset = enpci_reset, + .release = netjet_release, + .led_handler = enpci_led_handler, + .irq_func = enpci_interrupt, }; static struct pci_dev *dev_netjet __initdata = NULL; @@ -280,25 +269,16 @@ static struct pci_dev *dev_netjet __initdata = NULL; int __init setup_enternow_pci(struct IsdnCard *card) { - int bytecnt; struct IsdnCardState *cs = card->cs; char tmp[64]; -#if CONFIG_PCI #ifdef __BIG_ENDIAN #error "not running on big endian machines now" #endif strcpy(tmp, enternow_pci_rev); printk(KERN_INFO "HiSax: Formula-n Europe AG enter:now ISDN PCI driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_ENTERNOW) - return(0); - for ( ;; ) - { - if (!pci_present()) { - printk(KERN_ERR "enter:now PCI: no PCI bus present\n"); - return(0); - } + for ( ;; ) { if ((dev_netjet = pci_find_device(PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_300, dev_netjet))) { if (pci_enable_device(dev_netjet)) @@ -351,61 +331,19 @@ setup_enternow_pci(struct IsdnCard *card) break; } -#else - - printk(KERN_WARNING "enter:now PCI: NO_PCI_BIOS\n"); - printk(KERN_WARNING "enter:now PCI: unable to config Formula-n enter:now ISDN PCI ab\n"); - return (0); - -#endif /* CONFIG_PCI */ - - bytecnt = 256; - printk(KERN_INFO "enter:now PCI: PCI card configured at 0x%lx IRQ %d\n", cs->hw.njet.base, cs->irq); - if (!request_region(cs->hw.njet.base, bytecnt, "Fn_ISDN")) { - printk(KERN_WARNING - "HiSax: %s config port %lx-%lx already in use\n", - CardType[card->typ], - cs->hw.njet.base, - cs->hw.njet.base + bytecnt); - return (0); - } + if (!request_io(&cs->rs, cs->hw.njet.base, 0x100, "Fn_ISDN")) + return 0; reset_enpci(cs); cs->hw.njet.last_is0 = 0; - cs->dc_hw_ops = &enternow_ops; - cs->dc.amd7930.setIrqMask = &enpci_setIrqMask; + cs->hw.njet.bc_activate = enpci_bc_activate; + cs->hw.njet.bc_deactivate = enpci_bc_deactivate; + amd7930_setup(cs, &amd7930_ops, &enpci_setIrqMask); - cs->cardmsg = &enpci_card_msg; cs->irq_flags |= SA_SHIRQ; cs->card_ops = &enpci_ops; - return (1); + return 1; } - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/drivers/isdn/hisax/gazel.c b/drivers/isdn/hisax/gazel.c index 543715c39f5d..d07e0c5fbc5b 100644 --- a/drivers/isdn/hisax/gazel.c +++ b/drivers/isdn/hisax/gazel.c @@ -282,12 +282,6 @@ r742_reset(struct IsdnCardState *cs) return 0; } -static int -Gazel_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - return (0); -} - static void gazel_init(struct IsdnCardState *cs) { @@ -300,127 +294,85 @@ gazel_init(struct IsdnCardState *cs) inithscxisac(cs); } -static struct resource * -gazel_request_region(unsigned long start, unsigned long n, const char *name) -{ - struct resource *rc = request_region(start, n, name); - - if (!rc) - printk(KERN_WARNING "Gazel: io %#lx-%#lx already in use\n", - start, start + n); - return rc; -} - static int r647_reserve_regions(struct IsdnCardState *cs) { - int i, base; + int i, base = cs->hw.gazel.hscx[0]; - base = cs->hw.gazel.hscx[0]; - for (i = 0x0000; i < 0xC000; i += 0x1000) { - if (!gazel_request_region(i + base, 16, "gazel")) { - for (i -= 0x1000; i >= 0; i -= 0x1000) - release_region (i + base, 16); - return -EBUSY; - } - } - if (!gazel_request_region(0xC000 + base, 1, "gazel")) { - for (i = 0x0000; i < 0xC000; i += 0x1000) - release_region (i + base, 16); - return -EBUSY; + for (i = 0; i < 0xc000; i += 0x1000) { + if (!request_io(&cs->rs, i + base, 16, "gazel")) + goto err; } + if (!request_io(&cs->rs, 0xc000 + base, 1, "gazel")) + goto err; return 0; -} - -static void -r647_release(struct IsdnCardState *cs) -{ - int i; - - for (i = 0x0000; i < 0xC000; i += 0x1000) - release_region(i + cs->hw.gazel.hscx[0], 16); - release_region(0xC000 + cs->hw.gazel.hscx[0], 1); + err: + hisax_release_resources(cs); + return -EBUSY; } static int r685_reserve_regions(struct IsdnCardState *cs) { - if (!gazel_request_region(cs->hw.gazel.hscx[0], 0x100, "gazel")) { - return -EBUSY; - } - if (!gazel_request_region(cs->hw.gazel.cfg_reg, 0x80, "gazel")) { - release_region (cs->hw.gazel.hscx[0], 0x100); - return -EBUSY; - } + if (!request_io(&cs->rs, cs->hw.gazel.hscx[0], 0x100, "gazel")) + goto err; + if (!request_io(&cs->rs, cs->hw.gazel.cfg_reg, 0x80, "gazel")) + goto err; return 0; -} - -static void -r685_release(struct IsdnCardState *cs) -{ - release_region(cs->hw.gazel.hscx[0], 0x100); - release_region(cs->hw.gazel.cfg_reg, 0x80); + err: + hisax_release_resources(cs); + return -EBUSY; } static int r742_reserve_regions(struct IsdnCardState *cs) { - if (!gazel_request_region(cs->hw.gazel.ipac, 0x8, "gazel")) - return -EBUSY; + if (!request_io(&cs->rs, cs->hw.gazel.ipac, 0x8, "gazel")) + goto err; return 0; -} - -static void -r742_release(struct IsdnCardState *cs) -{ - release_region(cs->hw.gazel.ipac, 8); + err: + hisax_release_resources(cs); + return -EBUSY; } static int r753_reserve_regions(struct IsdnCardState *cs) { - if (!gazel_request_region(cs->hw.gazel.ipac, 0x8, "gazel")) { - return -EBUSY; - } - if (!gazel_request_region(cs->hw.gazel.cfg_reg, 0x80, "gazel")) { - release_region (cs->hw.gazel.ipac, 0x8); - return -EBUSY; - } + if (!request_io(&cs->rs, cs->hw.gazel.ipac, 0x8, "gazel")) + goto err; + if (!request_io(&cs->rs, cs->hw.gazel.cfg_reg, 0x80, "gazel")) + goto err; return 0; -} - -static void -r753_release(struct IsdnCardState *cs) -{ - release_region(cs->hw.gazel.ipac, 0x8); - release_region(cs->hw.gazel.cfg_reg, 0x80); + err: + hisax_release_resources(cs); + return -EBUSY; } static struct card_ops r647_ops = { .init = gazel_init, .reset = r647_reset, - .release = r647_release, + .release = hisax_release_resources, .irq_func = hscxisac_irq, }; static struct card_ops r685_ops = { .init = gazel_init, .reset = r685_reset, - .release = r685_release, + .release = hisax_release_resources, .irq_func = hscxisac_irq, }; static struct card_ops r742_ops = { .init = ipac_init, .reset = r742_reset, - .release = r742_release, + .release = hisax_release_resources, .irq_func = ipac_irq, }; static struct card_ops r753_ops = { .init = ipac_init, .reset = r753_reset, - .release = r753_release, + .release = hisax_release_resources, .irq_func = ipac_irq, }; @@ -573,14 +525,10 @@ setup_gazel(struct IsdnCard *card) { struct IsdnCardState *cs = card->cs; char tmp[64]; - u8 val; strcpy(tmp, gazel_revision); printk(KERN_INFO "Gazel: Driver Revision %s\n", HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_GAZEL) - return (0); - if (card->para[0]) { if (setup_gazelisa(card, cs)) return (0); @@ -589,28 +537,19 @@ setup_gazel(struct IsdnCard *card) return (0); } - cs->cardmsg = &Gazel_card_msg; - switch (cs->subtyp) { case R647: case R685: if (cs->subtyp == R647) { - cs->dc_hw_ops = &r647_isac_ops; - cs->bc_hw_ops = &r647_hscx_ops; cs->card_ops = &r647_ops; + if (hscxisac_setup(cs, &r647_isac_ops, &r647_hscx_ops)) + goto err; } else { - cs->dc_hw_ops = &r685_isac_ops; - cs->bc_hw_ops = &r685_hscx_ops; cs->card_ops = &r685_ops; + if (hscxisac_setup(cs, &r685_isac_ops, &r685_hscx_ops)) + goto err; } cs->card_ops->reset(cs); - ISACVersion(cs, "Gazel:"); - if (HscxVersion(cs, "Gazel:")) { - printk(KERN_WARNING - "Gazel: wrong HSCX versions check IO address\n"); - cs->card_ops->release(cs); - return (0); - } break; case R742: case R753: @@ -619,13 +558,13 @@ setup_gazel(struct IsdnCard *card) } else { cs->card_ops = &r753_ops; } - cs->dc_hw_ops = &ipac_dc_ops; - cs->bc_hw_ops = &ipac_bc_ops; + if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops)) + goto err; cs->card_ops->reset(cs); - val = ipac_read(cs, IPAC_ID); - printk(KERN_INFO "Gazel: IPAC version %x\n", val); break; } - return 1; + err: + hisax_release_resources(cs); + return 0; } diff --git a/drivers/isdn/hisax/hfc_2bs0.c b/drivers/isdn/hisax/hfc_2bs0.c index 29bc06033cd7..c1c106f59a2a 100644 --- a/drivers/isdn/hisax/hfc_2bs0.c +++ b/drivers/isdn/hisax/hfc_2bs0.c @@ -572,3 +572,10 @@ releasehfc(struct IsdnCardState *cs) cs->bcs[1].hw.hfc.send = NULL; } } + +int +hfc_setup(struct IsdnCardState *cs, struct bc_hw_ops *hfc_ops) +{ + cs->bc_hw_ops = hfc_ops; + return 0; +} diff --git a/drivers/isdn/hisax/hfc_2bs0.h b/drivers/isdn/hisax/hfc_2bs0.h index 34513adcacd4..62f3b08d0880 100644 --- a/drivers/isdn/hisax/hfc_2bs0.h +++ b/drivers/isdn/hisax/hfc_2bs0.h @@ -58,3 +58,4 @@ extern void main_irq_hfc(struct BCState *bcs); extern void inithfc(struct IsdnCardState *cs); extern void releasehfc(struct IsdnCardState *cs); +extern int hfc_setup(struct IsdnCardState *cs, struct bc_hw_ops *hfc_ops); diff --git a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c index 4623f05470ca..e674abdbbff6 100644 --- a/drivers/isdn/hisax/hfc_pci.c +++ b/drivers/isdn/hisax/hfc_pci.c @@ -65,8 +65,6 @@ static const PCI_ENTRY id_list[] = }; -#if CONFIG_PCI - /******************************************/ /* free hardware resources used by driver */ /******************************************/ @@ -83,8 +81,8 @@ hfcpci_release(struct IsdnCardState *cs) Write_hfc(cs, HFCPCI_CIRM, 0); /* Reset Off */ pci_disable_device(cs->hw.hfcpci.pdev); del_timer(&cs->hw.hfcpci.timer); - iounmap(cs->hw.hfcpci.pci_io); pci_free_consistent(cs->hw.hfcpci.pdev, 32768, cs->hw.hfcpci.fifos, cs->hw.hfcpci.fifos_dma); + hisax_release_resources(cs); } /********************************************************************************/ @@ -1363,17 +1361,6 @@ inithfcpci(struct IsdnCardState *cs) mode_hfcpci(cs->bcs + 1, 0, 1); } - - -/*******************************************/ -/* handle card messages from control layer */ -/*******************************************/ -static int -hfcpci_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - return (0); -} - static void hfcpci_init(struct IsdnCardState *cs) { @@ -1398,8 +1385,6 @@ static struct card_ops hfcpci_ops = { /* this variable is used as card index when more than one cards are present */ static struct pci_dev *dev_hfcpci __initdata = NULL; -#endif /* CONFIG_PCI */ - int __init setup_hfcpci(struct IsdnCard *card) { @@ -1410,72 +1395,66 @@ setup_hfcpci(struct IsdnCard *card) strcpy(tmp, hfcpci_revision); printk(KERN_INFO "HiSax: HFC-PCI driver Rev. %s\n", HiSax_getrev(tmp)); -#if CONFIG_PCI cs->hw.hfcpci.int_s1 = 0; cs->dc.hfcpci.ph_state = 0; cs->hw.hfcpci.fifo = 255; - if (cs->typ == ISDN_CTYPE_HFC_PCI) { - i = 0; - while (id_list[i].vendor_id) { - tmp_hfcpci = pci_find_device(id_list[i].vendor_id, - id_list[i].device_id, - dev_hfcpci); - i++; - if (tmp_hfcpci) { - if (pci_enable_device(tmp_hfcpci)) - continue; - pci_set_master(tmp_hfcpci); - if ((card->para[0]) && (card->para[0] != (tmp_hfcpci->resource[ 0].start & PCI_BASE_ADDRESS_IO_MASK))) - continue; - else - break; - } - } + i = 0; + while (id_list[i].vendor_id) { + tmp_hfcpci = pci_find_device(id_list[i].vendor_id, + id_list[i].device_id, + dev_hfcpci); + i++; if (tmp_hfcpci) { - i--; - dev_hfcpci = tmp_hfcpci; /* old device */ - cs->irq = dev_hfcpci->irq; - cs->hw.hfcpci.pdev = tmp_hfcpci; - if (!cs->irq) { - printk(KERN_WARNING "HFC-PCI: No IRQ for PCI card found\n"); - return (0); - } - cs->hw.hfcpci.pci_io = (char *) dev_hfcpci->resource[ 1].start; - printk(KERN_INFO "HiSax: HFC-PCI card manufacturer: %s card name: %s\n", id_list[i].vendor_name, id_list[i].card_name); - } else { - printk(KERN_WARNING "HFC-PCI: No PCI card found\n"); - return (0); + if (pci_enable_device(tmp_hfcpci)) + continue; + pci_set_master(tmp_hfcpci); + if ((card->para[0]) && (card->para[0] != (tmp_hfcpci->resource[ 0].start & PCI_BASE_ADDRESS_IO_MASK))) + continue; + else + break; } - if (!cs->hw.hfcpci.pci_io) { - printk(KERN_WARNING "HFC-PCI: No IO-Mem for PCI card found\n"); + } + + if (tmp_hfcpci) { + i--; + dev_hfcpci = tmp_hfcpci; /* old device */ + cs->irq = dev_hfcpci->irq; + cs->hw.hfcpci.pdev = tmp_hfcpci; + if (!cs->irq) { + printk(KERN_WARNING "HFC-PCI: No IRQ for PCI card found\n"); return (0); } - /* Allocate memory for FIFOS */ - cs->hw.hfcpci.fifos = pci_alloc_consistent(tmp_hfcpci, 32768, &cs->hw.hfcpci.fifos_dma); - if (!cs->hw.hfcpci.fifos) { - printk(KERN_WARNING "HFC-PCI: Error allocating memory for FIFO!\n"); - return 0; - } - pci_write_config_dword(cs->hw.hfcpci.pdev, 0x80, - (u_int)cs->hw.hfcpci.fifos_dma); - cs->hw.hfcpci.pci_io = ioremap((ulong) cs->hw.hfcpci.pci_io, 256); - printk(KERN_INFO - "HFC-PCI: defined at mem %#x fifo %#x(%#x) IRQ %d HZ %d\n", - (u_int) cs->hw.hfcpci.pci_io, - (u_int) cs->hw.hfcpci.fifos, - (u_int) cs->hw.hfcpci.fifos_dma, - cs->irq, HZ); - printk("ChipID: %x\n", Read_hfc(cs, HFCPCI_CHIP_ID)); - cs->hw.hfcpci.int_m2 = 0; /* disable alle interrupts */ - cs->hw.hfcpci.int_m1 = 0; - Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1); - Write_hfc(cs, HFCPCI_INT_M2, cs->hw.hfcpci.int_m2); - /* At this point the needed PCI config is done */ - /* fifos are still not enabled */ - } else - return (0); /* no valid card type */ - + printk(KERN_INFO "HiSax: HFC-PCI card manufacturer: %s card name: %s\n", id_list[i].vendor_name, id_list[i].card_name); + } else { + printk(KERN_WARNING "HFC-PCI: No PCI card found\n"); + return (0); + } + /* Allocate memory for FIFOS */ + cs->hw.hfcpci.fifos = pci_alloc_consistent(tmp_hfcpci, 32768, &cs->hw.hfcpci.fifos_dma); + if (!cs->hw.hfcpci.fifos) { + printk(KERN_WARNING "HFC-PCI: Error allocating memory for FIFO!\n"); + return 0; + } + pci_write_config_dword(cs->hw.hfcpci.pdev, 0x80, + (u_int)cs->hw.hfcpci.fifos_dma); + cs->hw.hfcpci.pci_io = request_mmio(&cs->rs, dev_hfcpci->resource[ 1].start, 256, "hfc_pci"); + if (!cs->hw.hfcpci.pci_io) + goto err; + + printk(KERN_INFO + "HFC-PCI: defined at mem %#x fifo %#x(%#x) IRQ %d HZ %d\n", + (u_int) cs->hw.hfcpci.pci_io, + (u_int) cs->hw.hfcpci.fifos, + (u_int) cs->hw.hfcpci.fifos_dma, + cs->irq, HZ); + printk("ChipID: %x\n", Read_hfc(cs, HFCPCI_CHIP_ID)); + cs->hw.hfcpci.int_m2 = 0; /* disable alle interrupts */ + cs->hw.hfcpci.int_m1 = 0; + Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1); + Write_hfc(cs, HFCPCI_INT_M2, cs->hw.hfcpci.int_m2); + /* At this point the needed PCI config is done */ + /* fifos are still not enabled */ cs->irq_flags |= SA_SHIRQ; @@ -1484,12 +1463,10 @@ setup_hfcpci(struct IsdnCard *card) init_timer(&cs->hw.hfcpci.timer); hfcpci_reset(cs); - cs->cardmsg = &hfcpci_card_msg; cs->auxcmd = &hfcpci_auxcmd; cs->card_ops = &hfcpci_ops; - return (1); -#else - printk(KERN_WARNING "HFC-PCI: NO_PCI_BIOS\n"); - return (0); -#endif /* CONFIG_PCI */ + return 1; + err: + hisax_release_resources(cs); + return 0; } diff --git a/drivers/isdn/hisax/hfc_sx.c b/drivers/isdn/hisax/hfc_sx.c index 611bedb5f3bd..566cf36ae6cd 100644 --- a/drivers/isdn/hisax/hfc_sx.c +++ b/drivers/isdn/hisax/hfc_sx.c @@ -318,7 +318,7 @@ hfcsx_release(struct IsdnCardState *cs) schedule_timeout((30 * HZ) / 1000); /* Timeout 30ms */ Write_hfc(cs, HFCSX_CIRM, 0); /* Reset Off */ del_timer(&cs->hw.hfcsx.timer); - release_region(cs->hw.hfcsx.base, 2); /* release IO-Block */ + hisax_release_resources(cs); kfree(cs->hw.hfcsx.extra); cs->hw.hfcsx.extra = NULL; } @@ -1139,17 +1139,6 @@ inithfcsx(struct IsdnCardState *cs) mode_hfcsx(cs->bcs + 1, 0, 1); } - - -/*******************************************/ -/* handle card messages from control layer */ -/*******************************************/ -static int -hfcsx_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - return (0); -} - static void hfcsx_init(struct IsdnCardState *cs) { @@ -1243,59 +1232,48 @@ setup_hfcsx(struct IsdnCard *card) cs->hw.hfcsx.int_s1 = 0; cs->dc.hfcsx.ph_state = 0; cs->hw.hfcsx.fifo = 255; - if ((cs->typ == ISDN_CTYPE_HFC_SX) || - (cs->typ == ISDN_CTYPE_HFC_SP_PCMCIA)) { - if ((!cs->hw.hfcsx.base) || - check_region((cs->hw.hfcsx.base), 2)) { - printk(KERN_WARNING - "HiSax: HFC-SX io-base %#lx already in use\n", - cs->hw.hfcsx.base); - return(0); - } else { - request_region(cs->hw.hfcsx.base, 2, "HFCSX isdn"); - } - byteout(cs->hw.hfcsx.base, cs->hw.hfcsx.base & 0xFF); - byteout(cs->hw.hfcsx.base + 1, - ((cs->hw.hfcsx.base >> 8) & 3) | 0x54); - udelay(10); - cs->hw.hfcsx.chip = Read_hfc(cs,HFCSX_CHIP_ID); - switch (cs->hw.hfcsx.chip >> 4) { - case 1: - tmp[0] ='+'; - break; - case 9: - tmp[0] ='P'; - break; - default: - printk(KERN_WARNING - "HFC-SX: invalid chip id 0x%x\n", - cs->hw.hfcsx.chip >> 4); - release_region(cs->hw.hfcsx.base, 2); - return(0); - } - if (!ccd_sp_irqtab[cs->irq & 0xF]) { - printk(KERN_WARNING - "HFC_SX: invalid irq %d specified\n",cs->irq & 0xF); - release_region(cs->hw.hfcsx.base, 2); - return(0); - } - if (!(cs->hw.hfcsx.extra = (void *) - kmalloc(sizeof(struct hfcsx_extra), GFP_ATOMIC))) { - release_region(cs->hw.hfcsx.base, 2); - printk(KERN_WARNING "HFC-SX: unable to allocate memory\n"); - return(0); - } - printk(KERN_INFO - "HFC-S%c chip detected at base 0x%x IRQ %d HZ %d\n", - tmp[0], (u_int) cs->hw.hfcsx.base, - cs->irq, HZ); - cs->hw.hfcsx.int_m2 = 0; /* disable alle interrupts */ - cs->hw.hfcsx.int_m1 = 0; - Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1); - Write_hfc(cs, HFCSX_INT_M2, cs->hw.hfcsx.int_m2); - } else - return (0); /* no valid card type */ + if (!request_io(&cs->rs, cs->hw.hfcsx.base, 2, "HFCSX isdn")) + return 0; + byteout(cs->hw.hfcsx.base, cs->hw.hfcsx.base & 0xFF); + byteout(cs->hw.hfcsx.base + 1, + ((cs->hw.hfcsx.base >> 8) & 3) | 0x54); + udelay(10); + cs->hw.hfcsx.chip = Read_hfc(cs,HFCSX_CHIP_ID); + switch (cs->hw.hfcsx.chip >> 4) { + case 1: + tmp[0] ='+'; + break; + case 9: + tmp[0] ='P'; + break; + default: + printk(KERN_WARNING "HFC-SX: invalid chip id 0x%x\n", + cs->hw.hfcsx.chip >> 4); + hisax_release_resources(cs); + return 0; + } + if (!ccd_sp_irqtab[cs->irq & 0xF]) { + printk(KERN_WARNING "HFC_SX: invalid irq %d specified\n", + cs->irq & 0xF); + hisax_release_resources(cs); + return 0; + } + cs->hw.hfcsx.extra = kmalloc(sizeof(struct hfcsx_extra), + GFP_ATOMIC); + if (!cs->hw.hfcsx.extra) { + hisax_release_resources(cs); + printk(KERN_WARNING "HFC-SX: unable to allocate memory\n"); + return 0; + } + + printk(KERN_INFO "HFC-S%c chip detected at base 0x%x IRQ %d HZ %d\n", + tmp[0], (u_int) cs->hw.hfcsx.base, + cs->irq, HZ); + cs->hw.hfcsx.int_m2 = 0; /* disable alle interrupts */ + cs->hw.hfcsx.int_m1 = 0; + Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1); + Write_hfc(cs, HFCSX_INT_M2, cs->hw.hfcsx.int_m2); cs->hw.hfcsx.timer.function = (void *) hfcsx_Timer; cs->hw.hfcsx.timer.data = (long) cs; @@ -1304,8 +1282,7 @@ setup_hfcsx(struct IsdnCard *card) init_timer(&cs->hw.hfcsx.timer); hfcsx_reset(cs); - cs->cardmsg = &hfcsx_card_msg; cs->auxcmd = &hfcsx_auxcmd; cs->card_ops = &hfcsx_ops; - return (1); + return 1; } diff --git a/drivers/isdn/hisax/hfcscard.c b/drivers/isdn/hisax/hfcscard.c index e309c578df11..93b5a5df0958 100644 --- a/drivers/isdn/hisax/hfcscard.c +++ b/drivers/isdn/hisax/hfcscard.c @@ -69,8 +69,7 @@ hfcs_release(struct IsdnCardState *cs) { release2bds0(cs); del_timer(&cs->hw.hfcD.timer); - if (cs->hw.hfcD.addr) - release_region(cs->hw.hfcD.addr, 2); + hisax_release_resources(cs); } static int @@ -114,12 +113,6 @@ hfcs_reset(struct IsdnCardState *cs) return 0; } -static int -hfcs_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - return(0); -} - static void hfcs_init(struct IsdnCardState *cs) { @@ -243,16 +236,8 @@ setup_hfcs(struct IsdnCard *card) cs->hw.hfcD.bfifosize = 7*1024 + 512; } else return (0); - if (check_region((cs->hw.hfcD.addr), 2)) { - printk(KERN_WARNING - "HiSax: %s config port %x-%x already in use\n", - CardType[card->typ], - cs->hw.hfcD.addr, - cs->hw.hfcD.addr + 2); - return (0); - } else { - request_region(cs->hw.hfcD.addr, 2, "HFCS isdn"); - } + if (!request_io(&cs->rs, cs->hw.hfcD.addr, 2, "HFCS isdn")) + return 0; printk(KERN_INFO "HFCS: defined at 0x%x IRQ %d HZ %d\n", cs->hw.hfcD.addr, @@ -271,7 +256,6 @@ setup_hfcs(struct IsdnCard *card) cs->hw.hfcD.timer.data = (long) cs; init_timer(&cs->hw.hfcD.timer); hfcs_reset(cs); - cs->cardmsg = &hfcs_card_msg; cs->card_ops = &hfcs_ops; return (1); } diff --git a/drivers/isdn/hisax/hisax.h b/drivers/isdn/hisax/hisax.h index 29c838357bb2..943d6a644dca 100644 --- a/drivers/isdn/hisax/hisax.h +++ b/drivers/isdn/hisax/hisax.h @@ -67,14 +67,9 @@ #define DL_FLUSH 0x0224 #define DL_UNIT_DATA 0x0230 -#define MDL_BC_RELEASE 0x0278 // Formula-n enter:now -#define MDL_BC_ASSIGN 0x027C // Formula-n enter:now #define MDL_ASSIGN 0x0280 #define MDL_REMOVE 0x0284 #define MDL_ERROR 0x0288 -#define MDL_INFO_SETUP 0x02E0 -#define MDL_INFO_CONN 0x02E4 -#define MDL_INFO_REL 0x02E8 #define CC_SETUP 0x0300 #define CC_RESUME 0x0304 @@ -149,6 +144,35 @@ /* #define I4L_IRQ_FLAG SA_INTERRUPT */ #define I4L_IRQ_FLAG 0 +struct res { + struct list_head node; + const char *name; + unsigned long start, end; + unsigned long flags; + union { + void *ioremap_addr; + } r_u; +}; + +struct resources { + struct list_head res_head; +}; + +void +resources_init(struct resources *rs); + +void +resources_release(struct resources *rs); + +unsigned long +request_io(struct resources *rs, unsigned long start, int len, + const char *name); + +void * +request_mmio(struct resources *rs, unsigned long start, int len, + const char *name); + + /* * Statemachine */ @@ -563,8 +587,8 @@ struct teles3_hw { struct teles0_hw { unsigned int cfg_reg; - unsigned long membase; unsigned long phymem; + void *membase; }; struct avm_hw { @@ -592,7 +616,6 @@ struct diva_hw { unsigned int isac; unsigned long hscx_adr; unsigned int hscx; - unsigned int status; struct timer_list tl; u8 ctrl_reg; }; @@ -654,6 +677,8 @@ struct njet_hw { unsigned char irqstat0; unsigned char last_is0; struct pci_dev *pdev; + void (*bc_activate)(struct IsdnCardState *cs, int bc); + void (*bc_deactivate)(struct IsdnCardState *cs, int bc); }; struct hfcPCI_hw { @@ -730,9 +755,8 @@ struct hfcD_hw { struct isurf_hw { unsigned int reset; - unsigned long phymem; - unsigned long isac; - unsigned long isar; + void *isac; + void *isar; struct isar_reg isar_r; }; @@ -857,12 +881,13 @@ struct IsdnCardState; /* Methods provided by driver for a specific card */ struct card_ops { - void (*init) (struct IsdnCardState *); - void (*test) (struct IsdnCardState *); - int (*reset) (struct IsdnCardState *); - void (*release) (struct IsdnCardState *); - void (*aux_ind) (struct IsdnCardState *, void *); - void (*irq_func) (int, void *, struct pt_regs *); + void (*init) (struct IsdnCardState *); + void (*test) (struct IsdnCardState *); + int (*reset) (struct IsdnCardState *); + void (*release) (struct IsdnCardState *); + void (*aux_ind) (struct IsdnCardState *, void *); + void (*led_handler)(struct IsdnCardState *); + void (*irq_func) (int, void *, struct pt_regs *); }; /* Card specific drivers provide methods to access the @@ -919,8 +944,10 @@ struct IsdnCardState { spinlock_t lock; struct card_ops *card_ops; int protocol; + struct resources rs; unsigned int irq; unsigned long irq_flags; + int status; long HW_Flags; int *busy_flag; int chanlimit; /* limited number of B-chans to use */ @@ -994,6 +1021,9 @@ struct IsdnCardState { #endif }; +void +hisax_release_resources(struct IsdnCardState *cs); + #define MON0_RX 1 #define MON1_RX 2 #define MON0_TX 4 @@ -1437,4 +1467,5 @@ L4L3(struct PStack *st, int pr, void *arg) st->l3.l4l3(st, pr, arg); } + #endif diff --git a/drivers/isdn/hisax/hisax_fcpcipnp.c b/drivers/isdn/hisax/hisax_fcpcipnp.c index b50b715351ed..75900470d57f 100644 --- a/drivers/isdn/hisax/hisax_fcpcipnp.c +++ b/drivers/isdn/hisax/hisax_fcpcipnp.c @@ -46,6 +46,9 @@ MODULE_PARM(debug, "i"); MODULE_AUTHOR("Kai Germaschewski <kai.germaschewski@gmx.de>/Karsten Keil <kkeil@suse.de>"); MODULE_DESCRIPTION("AVM Fritz!PCI/PnP ISDN driver"); +// FIXME temporary hack until I sort out the new PnP stuff +#define __ISAPNP__ + static struct pci_device_id fcpci_ids[] __devinitdata = { { PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_A1 , PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long) "Fritz!Card PCI" }, @@ -55,11 +58,12 @@ static struct pci_device_id fcpci_ids[] __devinitdata = { }; MODULE_DEVICE_TABLE(pci, fcpci_ids); -static const struct pnp_card_id fcpnp_ids[] __devinitdata = { - { .id = "AVM0900", .driver_data = (unsigned long) "Fritz!Card PnP", +static struct pnp_card_id fcpnp_ids[] __devinitdata = { + { .id = "AVM0900", + .driver_data = (unsigned long) "Fritz!Card PnP", .devs = { { "AVM0900" } } } }; -MODULE_DEVICE_TABLE(pnpc, fcpnp_ids); +//MODULE_DEVICE_TABLE(pnpc, fcpnp_ids); FIXME static int protocol = 2; /* EURO-ISDN Default */ MODULE_PARM(protocol, "i"); @@ -911,36 +915,43 @@ static int __devinit fcpnp_probe(struct pnp_card *card, { struct fritz_adapter *adapter; struct pnp_dev *pnp_dev; + int retval; - pnp_dev = pnp_request_card_device(card, card_id->devs[0], NULL); - if (pnp_dev == NULL) - return; + retval = -ENODEV; + pnp_dev = pnp_request_card_device(card, card_id->devs[0].id, NULL); + if (!pnp_dev) + goto err; - adapter = new_adapter(pdev); - if (!adapter) - return -ENOMEM; + if (!pnp_port_valid(pnp_dev, 0) || !pnp_irq_valid(pnp_dev, 0)) + goto err; + retval = -ENOMEM; + adapter = new_adapter((struct pci_dev *)pnp_dev); // FIXME + if (!adapter) + goto err; + adapter->type = AVM_FRITZ_PNP; - - if (!pnp_port_valid(pnp_dev, 0) || !pnp_irq_valid(pnp_dev, 0)) { - delete_adapter(adapter); adapter->io = pnp_port_start(pnp_dev, 0); adapter->irq = pnp_irq(pnp_dev, 0); - + printk(KERN_INFO "hisax_fcpcipnp: found adapter %s at IO %#x irq %d\n", - (char *) card_id->driver_data, adapter->io, adapter->irq); - + (char *) card_id->driver_data, adapter->io, adapter->irq); + retval = fcpcipnp_setup(adapter); - if (retval) { - delete_adapter(adapter); - return retval; - } + if (retval) + goto err_delete; + return 0; + + err_delete: + delete_adapter(adapter); + err: + return retval; } static void __devexit fcpnp_remove(struct pnp_card *pcard) { - struct fritz_adapter *adapter = pci_get_drvdata(pcard); + struct fritz_adapter *adapter = pnpc_get_drvdata(pcard); fcpcipnp_release(adapter); delete_adapter(adapter); @@ -997,7 +1008,7 @@ static int __init hisax_fcpcipnp_init(void) static void __exit hisax_fcpcipnp_exit(void) { #ifdef __ISAPNP__ - isapnp_unregister_driver(&fcpnp_driver); + pnpc_unregister_driver(&fcpnp_driver); #endif pci_unregister_driver(&fcpci_driver); } diff --git a/drivers/isdn/hisax/hscx.c b/drivers/isdn/hisax/hscx.c index 4304b0e65dcc..35dc68c1466e 100644 --- a/drivers/isdn/hisax/hscx.c +++ b/drivers/isdn/hisax/hscx.c @@ -45,7 +45,7 @@ hscx_write_fifo(struct BCState *bcs, u8 *p, int len) cs->bc_hw_ops->write_fifo(cs, bcs->unit, p, len); } -int __init +static int HscxVersion(struct IsdnCardState *cs, char *s) { int verA, verB; @@ -230,11 +230,24 @@ inithscx(struct IsdnCardState *cs) hscx_write(&cs->bcs[1], HSCX_MASK, 0x0); } -void __init +void inithscxisac(struct IsdnCardState *cs) { initisac(cs); inithscx(cs); } +int +hscxisac_setup(struct IsdnCardState *cs, struct dc_hw_ops *isac_ops, + struct bc_hw_ops *hscx_ops) +{ + isac_setup(cs, isac_ops); + cs->bc_hw_ops = hscx_ops; + if (HscxVersion(cs, "HiSax:")) { + printk(KERN_WARNING "HiSax: invalid HSCX version\n"); + return -ENODEV; + } + return 0; +} + #include "hscx_irq.c" diff --git a/drivers/isdn/hisax/hscx.h b/drivers/isdn/hisax/hscx.h index 3fc0c658caaf..cb4ade3cef32 100644 --- a/drivers/isdn/hisax/hscx.h +++ b/drivers/isdn/hisax/hscx.h @@ -34,8 +34,10 @@ #define HSCX_RLCR 0x2e #define HSCX_MASK 0x20 -extern int HscxVersion(struct IsdnCardState *cs, char *s); extern void modehscx(struct BCState *bcs, int mode, int bc); extern void inithscxisac(struct IsdnCardState *cs); extern void hscx_int_main(struct IsdnCardState *cs, u8 val); extern void hscxisac_irq(int intno, void *dev_id, struct pt_regs *regs); +extern int hscxisac_setup(struct IsdnCardState *cs, + struct dc_hw_ops *isac_ops, + struct bc_hw_ops *hscx_ops); diff --git a/drivers/isdn/hisax/icc.c b/drivers/isdn/hisax/icc.c index 51d392f902df..31dad9c22e20 100644 --- a/drivers/isdn/hisax/icc.c +++ b/drivers/isdn/hisax/icc.c @@ -51,7 +51,7 @@ icc_write_fifo(struct IsdnCardState *cs, u8 *p, int len) static char *ICCVer[] __initdata = {"2070 A1/A3", "2070 B1", "2070 B2/B3", "2070 V2.4"}; -void +static void ICCVersion(struct IsdnCardState *cs, char *s) { int val; @@ -558,3 +558,11 @@ initicc(struct IsdnCardState *cs) icc_write_reg(cs, ICC_MASK, 0x0); ph_command(cs, ICC_CMD_DI); } + +int +icc_setup(struct IsdnCardState *cs, struct dc_hw_ops *icc_ops) +{ + cs->dc_hw_ops = icc_ops; + ICCVersion(cs, "HiSax:"); + return 0; +} diff --git a/drivers/isdn/hisax/icc.h b/drivers/isdn/hisax/icc.h index a400616966da..8fc0aebd6755 100644 --- a/drivers/isdn/hisax/icc.h +++ b/drivers/isdn/hisax/icc.h @@ -65,6 +65,6 @@ #define ICC_IND_AIL 0xE #define ICC_IND_DC 0xF -extern void ICCVersion(struct IsdnCardState *cs, char *s); +extern int icc_setup(struct IsdnCardState *cs, struct dc_hw_ops *icc_ops); extern void initicc(struct IsdnCardState *cs); extern void icc_interrupt(struct IsdnCardState *cs, u8 val); diff --git a/drivers/isdn/hisax/ipac.c b/drivers/isdn/hisax/ipac.c index 06ddc035c374..803a1e70c140 100644 --- a/drivers/isdn/hisax/ipac.c +++ b/drivers/isdn/hisax/ipac.c @@ -91,3 +91,15 @@ Start_IPAC: ipac_write(cs, IPAC_MASK, 0xC0); spin_unlock(&cs->lock); } + +int +ipac_setup(struct IsdnCardState *cs, struct dc_hw_ops *ipac_dc_ops, + struct bc_hw_ops *ipac_bc_ops) +{ + u8 val; + + cs->dc_hw_ops = ipac_dc_ops; + cs->bc_hw_ops = ipac_bc_ops; + val = ipac_read(cs, IPAC_ID); + printk(KERN_INFO "HiSax: IPAC version %#x\n", val); +} diff --git a/drivers/isdn/hisax/ipac.h b/drivers/isdn/hisax/ipac.h index ac4823ef948a..dcda1fcdfd88 100644 --- a/drivers/isdn/hisax/ipac.h +++ b/drivers/isdn/hisax/ipac.h @@ -30,6 +30,8 @@ void ipac_init(struct IsdnCardState *cs); void ipac_irq(int intno, void *dev_id, struct pt_regs *regs); +int ipac_setup(struct IsdnCardState *cs, struct dc_hw_ops *ipac_dc_ops, + struct bc_hw_ops *ipac_bc_ops); /* Macro to build the needed D- and B-Channel access routines given * access functions for the IPAC */ diff --git a/drivers/isdn/hisax/ipacx.c b/drivers/isdn/hisax/ipacx.c index ca7fd962f8d7..ce64f0b1c02e 100644 --- a/drivers/isdn/hisax/ipacx.c +++ b/drivers/isdn/hisax/ipacx.c @@ -726,5 +726,15 @@ init_ipacx(struct IsdnCardState *cs, int part) } } -//----------------- end of file ----------------------- +int +ipacx_setup(struct IsdnCardState *cs, struct dc_hw_ops *ipacx_dc_ops, + struct bc_hw_ops *ipacx_bc_ops) +{ + u8 val; + + cs->dc_hw_ops = ipacx_dc_ops; + cs->bc_hw_ops = ipacx_bc_ops; + val = ipacx_read_reg(cs, IPACX_ID) & 0x3f; + printk(KERN_INFO "HiSax: IPACX Design Id: %#x\n", val); +} diff --git a/drivers/isdn/hisax/ipacx.h b/drivers/isdn/hisax/ipacx.h index fef4021f3eb1..818258281dc6 100644 --- a/drivers/isdn/hisax/ipacx.h +++ b/drivers/isdn/hisax/ipacx.h @@ -157,5 +157,8 @@ extern void init_ipacx(struct IsdnCardState *cs, int part); extern void interrupt_ipacx(struct IsdnCardState *cs); +extern int ipacx_setup(struct IsdnCardState *cs, + struct dc_hw_ops *ipacx_dc_ops, + struct bc_hw_ops *ipacx_bc_ops); #endif diff --git a/drivers/isdn/hisax/isac.c b/drivers/isdn/hisax/isac.c index 564ba14ba11d..10154acd8fc3 100644 --- a/drivers/isdn/hisax/isac.c +++ b/drivers/isdn/hisax/isac.c @@ -45,7 +45,7 @@ isac_write_fifo(struct IsdnCardState *cs, u8 *p, int len) return cs->dc_hw_ops->write_fifo(cs, p, len); } -void +static void ISACVersion(struct IsdnCardState *cs, char *s) { int val; @@ -559,3 +559,11 @@ initisac(struct IsdnCardState *cs) /* RESET Receiver and Transmitter */ isac_write(cs, ISAC_CMDR, 0x41); } + +int +isac_setup(struct IsdnCardState *cs, struct dc_hw_ops *isac_ops) +{ + cs->dc_hw_ops = isac_ops; + ISACVersion(cs, "HiSax:"); + return 0; +} diff --git a/drivers/isdn/hisax/isac.h b/drivers/isdn/hisax/isac.h index 756275a9844f..5e85c6296a0b 100644 --- a/drivers/isdn/hisax/isac.h +++ b/drivers/isdn/hisax/isac.h @@ -63,6 +63,6 @@ #define ISAC_IND_AI10 0xD #define ISAC_IND_DID 0xF -extern void ISACVersion(struct IsdnCardState *cs, char *s); extern void initisac(struct IsdnCardState *cs); extern void isac_interrupt(struct IsdnCardState *cs, u8 val); +extern int isac_setup(struct IsdnCardState *cs, struct dc_hw_ops *isac_ops); diff --git a/drivers/isdn/hisax/isar.c b/drivers/isdn/hisax/isar.c index de653b0e8ff7..c4c15b3efbc2 100644 --- a/drivers/isdn/hisax/isar.c +++ b/drivers/isdn/hisax/isar.c @@ -25,7 +25,7 @@ const u8 faxmodulation_s[] = "3,24,48,72,73,74,96,97,98,121,122,145,146"; const u8 faxmodulation[] = {3,24,48,72,73,74,96,97,98,121,122,145,146}; #define FAXMODCNT 13 -void isar_setup(struct IsdnCardState *cs); +static void __isar_setup(struct IsdnCardState *cs); static void isar_pump_cmd(struct BCState *bcs, u8 cmd, u8 para); static inline void ll_deliver_faxstat(struct BCState *bcs, u8 status); static spinlock_t isar_lock = SPIN_LOCK_UNLOCKED; @@ -165,7 +165,7 @@ waitrecmsg(struct IsdnCardState *cs, u8 *len, return(1); } -int +static int ISARVersion(struct IsdnCardState *cs, char *s) { int ver; @@ -420,7 +420,7 @@ isar_load_firmware(struct IsdnCardState *cs, u8 *buf) } } cs->debug = debug; - isar_setup(cs); + __isar_setup(cs); ret = 0; reterror: cs->debug = debug; @@ -1531,7 +1531,7 @@ isar_pump_cmd(struct BCState *bcs, u8 cmd, u8 para) } void -isar_setup(struct IsdnCardState *cs) +__isar_setup(struct IsdnCardState *cs) { u8 msg; int i; @@ -1754,3 +1754,10 @@ initisar(struct IsdnCardState *cs) { cs->bc_l1_ops = &isar_l1_ops; } + +int +isar_setup(struct IsdnCardState *cs, struct bc_hw_ops *isar_ops) +{ + cs->bc_hw_ops = isar_ops; + return ISARVersion(cs, "HiSax:"); +} diff --git a/drivers/isdn/hisax/isar.h b/drivers/isdn/hisax/isar.h index fb929c218ec1..9ab71bb7aa6f 100644 --- a/drivers/isdn/hisax/isar.h +++ b/drivers/isdn/hisax/isar.h @@ -207,8 +207,8 @@ #define STFAX_ESCAPE 5 #define STFAX_SILDET 6 -extern int ISARVersion(struct IsdnCardState *cs, char *s); extern void isar_int_main(struct IsdnCardState *cs); extern void initisar(struct IsdnCardState *cs); extern void isar_fill_fifo(struct BCState *bcs); extern int isar_auxcmd(struct IsdnCardState *cs, isdn_ctrl *ic); +extern int isar_setup(struct IsdnCardState *cs, struct bc_hw_ops *isar_ops); diff --git a/drivers/isdn/hisax/isurf.c b/drivers/isdn/hisax/isurf.c index 0166fc8a8110..feb20780ec6b 100644 --- a/drivers/isdn/hisax/isurf.c +++ b/drivers/isdn/hisax/isurf.c @@ -133,14 +133,6 @@ isurf_interrupt(int intno, void *dev_id, struct pt_regs *regs) } static void -isurf_release(struct IsdnCardState *cs) -{ - release_region(cs->hw.isurf.reset, 1); - iounmap((unsigned char *)cs->hw.isurf.isar); - release_mem_region(cs->hw.isurf.phymem, ISURF_IOMEM_SIZE); -} - -static void reset_isurf(struct IsdnCardState *cs, u8 chips) { printk(KERN_INFO "ISurf: resetting card\n"); @@ -154,12 +146,6 @@ reset_isurf(struct IsdnCardState *cs, u8 chips) } static int -ISurf_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - return(0); -} - -static int isurf_auxcmd(struct IsdnCardState *cs, isdn_ctrl *ic) { int ret; @@ -193,7 +179,7 @@ isurf_reset(struct IsdnCardState *cs) static struct card_ops isurf_ops = { .init = isurf_init, .reset = isurf_reset, - .release = isurf_release, + .release = hisax_release_resources, .irq_func = isurf_interrupt, }; @@ -204,18 +190,16 @@ static struct pnp_card *pnp_surf __devinitdata = NULL; int __init setup_isurf(struct IsdnCard *card) { - int ver; struct IsdnCardState *cs = card->cs; + unsigned long phymem; char tmp[64]; strcpy(tmp, ISurf_revision); printk(KERN_INFO "HiSax: ISurf driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_ISURF) - return(0); if (card->para[1] && card->para[2]) { cs->hw.isurf.reset = card->para[1]; - cs->hw.isurf.phymem = card->para[2]; + phymem = card->para[2]; cs->irq = card->para[0]; } else { #ifdef __ISAPNP__ @@ -251,7 +235,7 @@ setup_isurf(struct IsdnCard *card) return(0); } cs->hw.isurf.reset = pnp_port_start(pd, 0); - cs->hw.isurf.phymem = pnp_port_start(pd, 1); + phymem = pnp_port_start(pd, 1); cs->irq = pnp_irq(pd, 0); } else { printk(KERN_INFO "ISurfPnP: no ISAPnP card found\n"); @@ -267,50 +251,31 @@ setup_isurf(struct IsdnCard *card) return (0); #endif } - if (!request_region(cs->hw.isurf.reset, 1, "isurf isdn")) { - printk(KERN_WARNING - "HiSax: %s config port %x already in use\n", - CardType[card->typ], - cs->hw.isurf.reset); - return (0); - } - if (check_mem_region(cs->hw.isurf.phymem, ISURF_IOMEM_SIZE)) { - printk(KERN_WARNING - "HiSax: %s memory region %lx-%lx already in use\n", - CardType[card->typ], - cs->hw.isurf.phymem, - cs->hw.isurf.phymem + ISURF_IOMEM_SIZE); - release_region(cs->hw.isurf.reset, 1); - return (0); - } else { - request_mem_region(cs->hw.isurf.phymem, ISURF_IOMEM_SIZE, - "isurf iomem"); - } - cs->hw.isurf.isar = - (unsigned long) ioremap(cs->hw.isurf.phymem, ISURF_IOMEM_SIZE); + if (!request_io(&cs->rs, cs->hw.isurf.reset, 1, "isurf isdn")) + goto err; + cs->hw.isurf.isar = request_mmio(&cs->rs, phymem, ISURF_IOMEM_SIZE, "isurf iomem"); + if (!cs->hw.isurf.isar) + goto err; + cs->hw.isurf.isac = cs->hw.isurf.isar + ISURF_ISAC_OFFSET; printk(KERN_INFO "ISurf: defined at 0x%x 0x%lx IRQ %d\n", cs->hw.isurf.reset, - cs->hw.isurf.phymem, + card->para[2], cs->irq); - cs->cardmsg = &ISurf_card_msg; cs->auxcmd = &isurf_auxcmd; cs->card_ops = &isurf_ops; - cs->dc_hw_ops = &isac_ops; cs->bcs[0].hw.isar.reg = &cs->hw.isurf.isar_r; cs->bcs[1].hw.isar.reg = &cs->hw.isurf.isar_r; reset_isurf(cs, ISURF_RESET); test_and_set_bit(HW_ISAR, &cs->HW_Flags); - ISACVersion(cs, "ISurf:"); - cs->bc_hw_ops = &isar_ops; - ver = ISARVersion(cs, "ISurf:"); - if (ver < 0) { - printk(KERN_WARNING - "ISurf: wrong ISAR version (ret = %d)\n", ver); - isurf_release(cs); - return (0); - } - return (1); + isac_setup(cs, &isac_ops); + if (isar_setup(cs, &isar_ops)) + goto err; + return 1; + err: + hisax_release_resources(cs); + return 0; + } diff --git a/drivers/isdn/hisax/ix1_micro.c b/drivers/isdn/hisax/ix1_micro.c index 6697b8ff4b70..62b0f5f9d889 100644 --- a/drivers/isdn/hisax/ix1_micro.c +++ b/drivers/isdn/hisax/ix1_micro.c @@ -140,13 +140,6 @@ static struct bc_hw_ops hscx_ops = { .write_fifo = hscx_write_fifo, }; -static void -ix1_release(struct IsdnCardState *cs) -{ - if (cs->hw.ix1.cfg_reg) - release_region(cs->hw.ix1.cfg_reg, 4); -} - static int ix1_reset(struct IsdnCardState *cs) { @@ -162,16 +155,10 @@ ix1_reset(struct IsdnCardState *cs) return 0; } -static int -ix1_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - return(0); -} - static struct card_ops ix1_ops = { .init = inithscxisac, .reset = ix1_reset, - .release = ix1_release, + .release = hisax_release_resources, .irq_func = hscxisac_irq, }; @@ -199,8 +186,6 @@ setup_ix1micro(struct IsdnCard *card) strcpy(tmp, ix1_revision); printk(KERN_INFO "HiSax: ITK IX1 driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_IX1MICROR2) - return (0); #ifdef __ISAPNP__ if (!card->para[1] && isapnp_present()) { @@ -256,32 +241,17 @@ setup_ix1micro(struct IsdnCard *card) cs->hw.ix1.hscx = card->para[1] + HSCX_DATA_OFFSET; cs->hw.ix1.cfg_reg = card->para[1]; cs->irq = card->para[0]; - if (cs->hw.ix1.cfg_reg) { - if (check_region((cs->hw.ix1.cfg_reg), 4)) { - printk(KERN_WARNING - "HiSax: %s config port %x-%x already in use\n", - CardType[card->typ], - cs->hw.ix1.cfg_reg, - cs->hw.ix1.cfg_reg + 4); - return (0); - } else - request_region(cs->hw.ix1.cfg_reg, 4, "ix1micro cfg"); - } - printk(KERN_INFO - "HiSax: %s config irq:%d io:0x%X\n", - CardType[cs->typ], cs->irq, - cs->hw.ix1.cfg_reg); + if (!request_io(&cs->rs, cs->hw.ix1.cfg_reg, 4, "ix1micro cfg")) + goto err; + + printk(KERN_INFO "HiSax: %s config irq:%d io:0x%X\n", + CardType[cs->typ], cs->irq, cs->hw.ix1.cfg_reg); ix1_reset(cs); - cs->dc_hw_ops = &isac_ops; - cs->bc_hw_ops = &hscx_ops; - cs->cardmsg = &ix1_card_msg; cs->card_ops = &ix1_ops; - ISACVersion(cs, "ix1-Micro:"); - if (HscxVersion(cs, "ix1-Micro:")) { - printk(KERN_WARNING - "ix1-Micro: wrong HSCX versions check IO address\n"); - ix1_release(cs); - return (0); - } - return (1); + if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) + goto err; + return 1; + err: + hisax_release_resources(cs); + return 0; } diff --git a/drivers/isdn/hisax/jade.c b/drivers/isdn/hisax/jade.c index b5e6d968dda2..665ff00db0e4 100644 --- a/drivers/isdn/hisax/jade.c +++ b/drivers/isdn/hisax/jade.c @@ -40,7 +40,7 @@ jade_write_fifo(struct BCState *bcs, u8 *p, int len) cs->bc_hw_ops->write_fifo(cs, bcs->unit, p, len); } -int __init +static int JadeVersion(struct IsdnCardState *cs, char *s) { int ver,i; @@ -270,4 +270,11 @@ initjade(struct IsdnCardState *cs) modejade(cs->bcs + 1, 0, 0); } +int +jade_setup(struct IsdnCardState *cs, struct bc_hw_ops *jade_ops) +{ + cs->bc_hw_ops = jade_ops; + return JadeVersion(cs, "HiSax:"); +} + #include "jade_irq.c" diff --git a/drivers/isdn/hisax/jade.h b/drivers/isdn/hisax/jade.h index be9778228b31..d5c4bc3780c0 100644 --- a/drivers/isdn/hisax/jade.h +++ b/drivers/isdn/hisax/jade.h @@ -127,10 +127,10 @@ #define jade_TXAUDIOCH1CFG 0x17 #define jade_TXAUDIOCH2CFG 0x1A -extern int JadeVersion(struct IsdnCardState *cs, char *s); extern void jade_sched_event(struct BCState *bcs, int event); extern void modejade(struct BCState *bcs, int mode, int bc); extern void initjade(struct IsdnCardState *cs); -extern void jade_int_main(struct IsdnCardState *cs, u_char val, int jade); +extern void jade_int_main(struct IsdnCardState *cs, u8 val, int jade); +extern int jade_setup(struct IsdnCardState *cs, struct bc_hw_ops *jade_ops); #endif /* __JADE_H__ */ diff --git a/drivers/isdn/hisax/mic.c b/drivers/isdn/hisax/mic.c index 6bbc1e21e824..7e2731379816 100644 --- a/drivers/isdn/hisax/mic.c +++ b/drivers/isdn/hisax/mic.c @@ -132,67 +132,37 @@ static struct bc_hw_ops hscx_ops = { .write_fifo = hscx_write_fifo, }; -static void -mic_release(struct IsdnCardState *cs) -{ - if (cs->hw.mic.cfg_reg) - release_region(cs->hw.mic.cfg_reg, 8); -} - -static int -mic_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - return(0); -} - static struct card_ops mic_ops = { .init = inithscxisac, - .release = mic_release, + .release = hisax_release_resources, .irq_func = hscxisac_irq, }; int __init setup_mic(struct IsdnCard *card) { - int bytecnt; struct IsdnCardState *cs = card->cs; char tmp[64]; strcpy(tmp, mic_revision); printk(KERN_INFO "HiSax: mic driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_MIC) - return (0); - bytecnt = 8; cs->hw.mic.cfg_reg = card->para[1]; cs->irq = card->para[0]; cs->hw.mic.adr = cs->hw.mic.cfg_reg + MIC_ADR; cs->hw.mic.isac = cs->hw.mic.cfg_reg + MIC_ISAC; cs->hw.mic.hscx = cs->hw.mic.cfg_reg + MIC_HSCX; - if (!request_region((cs->hw.mic.cfg_reg), bytecnt, "mic isdn")) { - printk(KERN_WARNING - "HiSax: %s config port %x-%x already in use\n", - CardType[card->typ], - cs->hw.mic.cfg_reg, - cs->hw.mic.cfg_reg + bytecnt); - return (0); - } - - printk(KERN_INFO - "mic: defined at 0x%x IRQ %d\n", - cs->hw.mic.cfg_reg, - cs->irq); - cs->dc_hw_ops = &isac_ops; - cs->bc_hw_ops = &hscx_ops; - cs->cardmsg = &mic_card_msg; + if (!request_io(&cs->rs, cs->hw.mic.cfg_reg, 8, "mic isdn")) + goto err; + + printk(KERN_INFO "mic: defined at 0x%x IRQ %d\n", + cs->hw.mic.cfg_reg, cs->irq); cs->card_ops = &mic_ops; - ISACVersion(cs, "mic:"); - if (HscxVersion(cs, "mic:")) { - printk(KERN_WARNING - "mic: wrong HSCX versions check IO address\n"); - mic_release(cs); - return (0); - } - return (1); + if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) + goto err; + return 1; + err: + hisax_release_resources(cs); + return 0; } diff --git a/drivers/isdn/hisax/netjet.c b/drivers/isdn/hisax/netjet.c index fab21b6e6442..f832b1e26d62 100644 --- a/drivers/isdn/hisax/netjet.c +++ b/drivers/isdn/hisax/netjet.c @@ -839,6 +839,7 @@ static void tiger_l2l1(struct PStack *st, int pr, void *arg) { struct sk_buff *skb = arg; + struct IsdnCardState *cs = st->l1.bcs->cs; switch (pr) { case (PH_DATA | REQUEST): @@ -853,13 +854,13 @@ tiger_l2l1(struct PStack *st, int pr, void *arg) case (PH_ACTIVATE | REQUEST): test_and_set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag); mode_tiger(st->l1.bcs, st->l1.mode, st->l1.bc); - /* 2001/10/04 Christoph Ersfeld, Formula-n Europe AG */ - st->l1.bcs->cs->cardmsg(st->l1.bcs->cs, MDL_BC_ASSIGN, (void *)(&st->l1.bc)); + if (cs->hw.njet.bc_activate) + (cs->hw.njet.bc_activate)(cs, st->l1.bc); l1_msg_b(st, pr, arg); break; case (PH_DEACTIVATE | REQUEST): - /* 2001/10/04 Christoph Ersfeld, Formula-n Europe AG */ - st->l1.bcs->cs->cardmsg(st->l1.bcs->cs, MDL_BC_RELEASE, (void *)(&st->l1.bc)); + if (cs->hw.njet.bc_deactivate) + (cs->hw.njet.bc_deactivate)(cs, st->l1.bc); l1_msg_b(st, pr, arg); break; case (PH_DEACTIVATE | CONFIRM): @@ -1029,6 +1030,6 @@ netjet_release(struct IsdnCardState *cs) byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0); byteout(cs->hw.njet.base + NETJET_IRQMASK1, 0); releasetiger(cs); - release_region(cs->hw.njet.base, 256); + hisax_release_resources(cs); } diff --git a/drivers/isdn/hisax/niccy.c b/drivers/isdn/hisax/niccy.c index cb7d7194673f..3e6aefa11a4e 100644 --- a/drivers/isdn/hisax/niccy.c +++ b/drivers/isdn/hisax/niccy.c @@ -175,12 +175,8 @@ niccy_release(struct IsdnCardState *cs) val = inl(cs->hw.niccy.cfg_reg + PCI_IRQ_CTRL_REG); val &= PCI_IRQ_DISABLE; outl(val, cs->hw.niccy.cfg_reg + PCI_IRQ_CTRL_REG); - release_region(cs->hw.niccy.cfg_reg, 0x40); - release_region(cs->hw.niccy.isac, 4); - } else { - release_region(cs->hw.niccy.isac, 2); - release_region(cs->hw.niccy.isac_ale, 2); } + hisax_release_resources(cs); } static int @@ -196,12 +192,6 @@ niccy_reset(struct IsdnCardState *cs) return 0; } -static int -niccy_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - return(0); -} - static struct card_ops niccy_ops = { .init = inithscxisac, .reset = niccy_reset, @@ -222,8 +212,6 @@ setup_niccy(struct IsdnCard *card) strcpy(tmp, niccy_revision); printk(KERN_INFO "HiSax: Niccy driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_NICCY) - return (0); #ifdef __ISAPNP__ if (!card->para[1] && isapnp_present()) { struct pnp_card *pb; @@ -271,30 +259,13 @@ setup_niccy(struct IsdnCard *card) cs->hw.niccy.cfg_reg = 0; cs->subtyp = NICCY_PNP; cs->irq = card->para[0]; - if (!request_region(cs->hw.niccy.isac, 2, "niccy data")) { - printk(KERN_WARNING - "HiSax: %s data port %x-%x already in use\n", - CardType[card->typ], - cs->hw.niccy.isac, - cs->hw.niccy.isac + 1); - return (0); - } - if (!request_region(cs->hw.niccy.isac_ale, 2, "niccy addr")) { - printk(KERN_WARNING - "HiSax: %s address port %x-%x already in use\n", - CardType[card->typ], - cs->hw.niccy.isac_ale, - cs->hw.niccy.isac_ale + 1); - release_region(cs->hw.niccy.isac, 2); - return (0); - } + if (!request_io(&cs->rs, cs->hw.niccy.isac, 2, "niccy data")) + goto err; + if (!request_io(&cs->rs, cs->hw.niccy.isac_ale, 2, "niccy addr")) + goto err; } else { #if CONFIG_PCI u_int pci_ioaddr; - if (!pci_present()) { - printk(KERN_ERR "Niccy: no PCI bus present\n"); - return(0); - } cs->subtyp = 0; if ((niccy_dev = pci_find_device(PCI_VENDOR_ID_SATSAGEM, PCI_DEVICE_ID_SATSAGEM_NICCY, niccy_dev))) { @@ -326,43 +297,21 @@ setup_niccy(struct IsdnCard *card) cs->hw.niccy.isac_ale = pci_ioaddr + ISAC_PCI_ADDR; cs->hw.niccy.hscx = pci_ioaddr + HSCX_PCI_DATA; cs->hw.niccy.hscx_ale = pci_ioaddr + HSCX_PCI_ADDR; - if (!request_region(cs->hw.niccy.isac, 4, "niccy")) { - printk(KERN_WARNING - "HiSax: %s data port %x-%x already in use\n", - CardType[card->typ], - cs->hw.niccy.isac, - cs->hw.niccy.isac + 4); - return (0); - } - if (!request_region(cs->hw.niccy.cfg_reg, 0x40, "niccy pci")) { - printk(KERN_WARNING - "HiSax: %s pci port %x-%x already in use\n", - CardType[card->typ], - cs->hw.niccy.cfg_reg, - cs->hw.niccy.cfg_reg + 0x40); - release_region(cs->hw.niccy.isac, 4); - return (0); - } -#else - printk(KERN_WARNING "Niccy: io0 0 and NO_PCI_BIOS\n"); - printk(KERN_WARNING "Niccy: unable to config NICCY PCI\n"); - return (0); + + if (!request_io(&cs->rs, cs->hw.niccy.isac, 4, "niccy")) + goto err; + if (!request_io(&cs->rs, cs->hw.niccy.cfg_reg, 0x40, "niccy pci")) + goto err; #endif /* CONFIG_PCI */ } - printk(KERN_INFO - "HiSax: %s %s config irq:%d data:0x%X ale:0x%X\n", + printk(KERN_INFO "HiSax: %s %s config irq:%d data:0x%X ale:0x%X\n", CardType[cs->typ], (cs->subtyp==1) ? "PnP":"PCI", cs->irq, cs->hw.niccy.isac, cs->hw.niccy.isac_ale); - cs->dc_hw_ops = &isac_ops; - cs->bc_hw_ops = &hscx_ops; - cs->cardmsg = &niccy_card_msg; cs->card_ops = &niccy_ops; - ISACVersion(cs, "Niccy:"); - if (HscxVersion(cs, "Niccy:")) { - printk(KERN_WARNING - "Niccy: wrong HSCX versions check IO address\n"); - niccy_release(cs); - return (0); - } - return (1); + if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) + goto err; + return 1; + err: + niccy_release(cs); + return 0; } diff --git a/drivers/isdn/hisax/nj_s.c b/drivers/isdn/hisax/nj_s.c index a453bc877810..047b1d7c2a6c 100644 --- a/drivers/isdn/hisax/nj_s.c +++ b/drivers/isdn/hisax/nj_s.c @@ -92,12 +92,6 @@ nj_s_reset(struct IsdnCardState *cs) return 0; } -static int -NETjet_S_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - return(0); -} - static void nj_s_init(struct IsdnCardState *cs) { @@ -117,7 +111,6 @@ static struct pci_dev *dev_netjet __initdata = NULL; int __init setup_netjet_s(struct IsdnCard *card) { - int bytecnt; struct IsdnCardState *cs = card->cs; char tmp[64]; @@ -126,17 +119,8 @@ setup_netjet_s(struct IsdnCard *card) #endif strcpy(tmp, NETjet_S_revision); printk(KERN_INFO "HiSax: Traverse Tech. NETjet-S driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_NETJET_S) - return(0); -#if CONFIG_PCI - - for ( ;; ) - { - if (!pci_present()) { - printk(KERN_ERR "Netjet: no PCI bus present\n"); - return(0); - } + for ( ;; ) { if ((dev_netjet = pci_find_device(PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_300, dev_netjet))) { if (pci_enable_device(dev_netjet)) @@ -203,34 +187,15 @@ setup_netjet_s(struct IsdnCard *card) } break; } -#else - - printk(KERN_WARNING "NETjet-S: NO_PCI_BIOS\n"); - printk(KERN_WARNING "NETjet-S: unable to config NETJET-S PCI\n"); - return (0); - -#endif /* CONFIG_PCI */ - - bytecnt = 256; - printk(KERN_INFO "NETjet-S: PCI card configured at %#lx IRQ %d\n", cs->hw.njet.base, cs->irq); - if (check_region(cs->hw.njet.base, bytecnt)) { - printk(KERN_WARNING - "HiSax: %s config port %#lx-%#lx already in use\n", - CardType[card->typ], - cs->hw.njet.base, - cs->hw.njet.base + bytecnt); - return (0); - } else { - request_region(cs->hw.njet.base, bytecnt, "netjet-s isdn"); - } + if (!request_io(&cs->rs, cs->hw.njet.base, 0x100, "netjet-s isdn")) + return 0; + nj_s_reset(cs); - cs->dc_hw_ops = &netjet_dc_ops; - cs->cardmsg = &NETjet_S_card_msg; cs->irq_flags |= SA_SHIRQ; cs->card_ops = &nj_s_ops; - ISACVersion(cs, "NETjet-S:"); - return (1); + isac_setup(cs, &netjet_dc_ops); + return 1; } diff --git a/drivers/isdn/hisax/nj_u.c b/drivers/isdn/hisax/nj_u.c index 6e06670e55d2..24d6489f6927 100644 --- a/drivers/isdn/hisax/nj_u.c +++ b/drivers/isdn/hisax/nj_u.c @@ -94,12 +94,6 @@ nj_u_reset(struct IsdnCardState *cs) return 0; } -static int -NETjet_U_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - return(0); -} - static void nj_u_init(struct IsdnCardState *cs) { @@ -121,27 +115,15 @@ static struct pci_dev *dev_netjet __initdata = NULL; int __init setup_netjet_u(struct IsdnCard *card) { - int bytecnt; struct IsdnCardState *cs = card->cs; char tmp[64]; -#if CONFIG_PCI -#endif #ifdef __BIG_ENDIAN #error "not running on big endian machines now" #endif strcpy(tmp, NETjet_U_revision); printk(KERN_INFO "HiSax: Traverse Tech. NETspider-U driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_NETJET_U) - return(0); - -#if CONFIG_PCI - for ( ;; ) - { - if (!pci_present()) { - printk(KERN_ERR "Netjet: no PCI bus present\n"); - return(0); - } + for ( ;; ) { if ((dev_netjet = pci_find_device(PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_300, dev_netjet))) { if (pci_enable_device(dev_netjet)) @@ -201,32 +183,15 @@ setup_netjet_u(struct IsdnCard *card) } break; } -#else - - printk(KERN_WARNING "NETspider-U: NO_PCI_BIOS\n"); - printk(KERN_WARNING "NETspider-U: unable to config NETspider-U PCI\n"); - return (0); - -#endif /* CONFIG_PCI */ - - bytecnt = 256; - printk(KERN_INFO "NETspider-U: PCI card configured at %#lx IRQ %d\n", cs->hw.njet.base, cs->irq); - if (!request_region(cs->hw.njet.base, bytecnt, "netspider-u isdn")) { - printk(KERN_WARNING - "HiSax: %s config port %#lx-%#lx already in use\n", - CardType[card->typ], - cs->hw.njet.base, - cs->hw.njet.base + bytecnt); - return (0); - } + if (!request_io(&cs->rs, cs->hw.njet.base, 0x100, "netjet-s isdn")) + return 0; + nj_u_reset(cs); - cs->dc_hw_ops = &netjet_dc_ops; - cs->cardmsg = &NETjet_U_card_msg; cs->irq_flags |= SA_SHIRQ; cs->card_ops = &nj_u_ops; - ICCVersion(cs, "NETspider-U:"); - return (1); + icc_setup(cs, &netjet_dc_ops); + return 1; } diff --git a/drivers/isdn/hisax/s0box.c b/drivers/isdn/hisax/s0box.c index f41a3c7d3f7a..7a676aee0b40 100644 --- a/drivers/isdn/hisax/s0box.c +++ b/drivers/isdn/hisax/s0box.c @@ -166,21 +166,9 @@ static struct bc_hw_ops hscx_ops = { .write_fifo = hscx_write_fifo, }; -void -s0box_release(struct IsdnCardState *cs) -{ - release_region(cs->hw.teles3.cfg_reg, 8); -} - -static int -S0Box_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - return(0); -} - static struct card_ops s0box_ops = { .init = inithscxisac, - .release = s0box_release, + .release = hisax_release_resources, .irq_func = hscxisac_irq, }; @@ -192,9 +180,6 @@ setup_s0box(struct IsdnCard *card) strcpy(tmp, s0box_revision); printk(KERN_INFO "HiSax: S0Box IO driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_S0BOX) - return (0); - cs->hw.teles3.cfg_reg = card->para[1]; cs->hw.teles3.hscx[0] = -0x20; cs->hw.teles3.hscx[1] = 0x0; @@ -203,14 +188,8 @@ setup_s0box(struct IsdnCard *card) cs->hw.teles3.hscxfifo[0] = cs->hw.teles3.hscx[0] + 0x3e; cs->hw.teles3.hscxfifo[1] = cs->hw.teles3.hscx[1] + 0x3e; cs->irq = card->para[0]; - if (!request_region(cs->hw.teles3.cfg_reg,8, "S0Box parallel I/O")) { - printk(KERN_WARNING - "HiSax: %s ports %x-%x already in use\n", - CardType[cs->typ], - cs->hw.teles3.cfg_reg, - cs->hw.teles3.cfg_reg + 7); - return 0; - } + if (!request_io(&cs->rs, cs->hw.teles3.cfg_reg, 8, "S0Box parallel I/O")) + goto err; printk(KERN_INFO "HiSax: %s config irq:%d isac:0x%x cfg:0x%x\n", CardType[cs->typ], cs->irq, @@ -218,16 +197,11 @@ setup_s0box(struct IsdnCard *card) printk(KERN_INFO "HiSax: hscx A:0x%x hscx B:0x%x\n", cs->hw.teles3.hscx[0], cs->hw.teles3.hscx[1]); - cs->dc_hw_ops = &isac_ops; - cs->bc_hw_ops = &hscx_ops; - cs->cardmsg = &S0Box_card_msg; cs->card_ops = &s0box_ops; - ISACVersion(cs, "S0Box:"); - if (HscxVersion(cs, "S0Box:")) { - printk(KERN_WARNING - "S0Box: wrong HSCX versions check IO address\n"); - s0box_release(cs); - return (0); - } - return (1); + if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) + goto err; + return 1; + err: + hisax_release_resources(cs); + return 0; } diff --git a/drivers/isdn/hisax/saphir.c b/drivers/isdn/hisax/saphir.c index 3bafecc83244..ca2a46892e6f 100644 --- a/drivers/isdn/hisax/saphir.c +++ b/drivers/isdn/hisax/saphir.c @@ -155,8 +155,7 @@ saphir_release(struct IsdnCardState *cs) byteout(cs->hw.saphir.cfg_reg + IRQ_REG, 0xff); del_timer_sync(&cs->hw.saphir.timer); cs->hw.saphir.timer.function = NULL; - if (cs->hw.saphir.cfg_reg) - release_region(cs->hw.saphir.cfg_reg, 6); + hisax_release_resources(cs); } static int @@ -195,12 +194,6 @@ saphir_reset(struct IsdnCardState *cs) return (0); } -static int -saphir_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - return(0); -} - static struct card_ops saphir_ops = { .init = inithscxisac, .reset = saphir_reset, @@ -219,20 +212,15 @@ setup_saphir(struct IsdnCard *card) if (cs->typ != ISDN_CTYPE_HSTSAPHIR) return (0); + init_timer(&cs->hw.saphir.timer); /* IO-Ports */ cs->hw.saphir.cfg_reg = card->para[1]; cs->hw.saphir.isac = card->para[1] + ISAC_DATA; cs->hw.saphir.hscx = card->para[1] + HSCX_DATA; cs->hw.saphir.ale = card->para[1] + ADDRESS_REG; cs->irq = card->para[0]; - if (!request_region((cs->hw.saphir.cfg_reg), 6, "saphir")) { - printk(KERN_WARNING - "HiSax: %s config port %x-%x already in use\n", - CardType[card->typ], - cs->hw.saphir.cfg_reg, - cs->hw.saphir.cfg_reg + 5); - return (0); - } + if (!request_io(&cs->rs, cs->hw.saphir.cfg_reg, 6, "saphir")) + goto err; printk(KERN_INFO "HiSax: %s config irq:%d io:0x%X\n", @@ -241,23 +229,17 @@ setup_saphir(struct IsdnCard *card) cs->hw.saphir.timer.function = (void *) SaphirWatchDog; cs->hw.saphir.timer.data = (long) cs; - init_timer(&cs->hw.saphir.timer); cs->hw.saphir.timer.expires = jiffies + 4*HZ; add_timer(&cs->hw.saphir.timer); - if (saphir_reset(cs)) { - saphir_release(cs); - return (0); - } - cs->dc_hw_ops = &isac_ops; - cs->bc_hw_ops = &hscx_ops; - cs->cardmsg = &saphir_card_msg; + if (saphir_reset(cs)) + goto err; + cs->card_ops = &saphir_ops; - ISACVersion(cs, "saphir:"); - if (HscxVersion(cs, "saphir:")) { - printk(KERN_WARNING - "saphir: wrong HSCX versions check IO address\n"); - saphir_release(cs); - return (0); - } - return (1); + if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) + goto err; + + return 1; + err: + saphir_release(cs); + return 0; } diff --git a/drivers/isdn/hisax/sedlbauer.c b/drivers/isdn/hisax/sedlbauer.c index 218bb876c7bc..d88e43883bd8 100644 --- a/drivers/isdn/hisax/sedlbauer.c +++ b/drivers/isdn/hisax/sedlbauer.c @@ -391,20 +391,6 @@ sedlbauer_reset(struct IsdnCardState *cs) } static void -sedlbauer_release(struct IsdnCardState *cs) -{ - int bytecnt = 8; - - if (cs->subtyp == SEDL_SPEED_FAX) { - bytecnt = 16; - } else if (cs->hw.sedl.bus == SEDL_BUS_PCI) { - bytecnt = 256; - } - if (cs->hw.sedl.cfg_reg) - release_region(cs->hw.sedl.cfg_reg, bytecnt); -} - -static void sedlbauer_isar_release(struct IsdnCardState *cs) { isar_write(cs, 0, ISAR_IRQBIT, 0); @@ -412,33 +398,26 @@ sedlbauer_isar_release(struct IsdnCardState *cs) sedlbauer_reset(cs); isar_write(cs, 0, ISAR_IRQBIT, 0); isac_write(cs, ISAC_MASK, 0xFF); - sedlbauer_release(cs); + hisax_release_resources(cs); } -static int -Sedl_card_msg(struct IsdnCardState *cs, int mt, void *arg) +static void +sedlbauer_led_handler(struct IsdnCardState *cs) { - switch (mt) { - case MDL_INFO_CONN: - if (cs->subtyp != SEDL_SPEEDFAX_PYRAMID) - return(0); - if ((long) arg) - cs->hw.sedl.reset_off &= ~SEDL_ISAR_PCI_LED2; - else - cs->hw.sedl.reset_off &= ~SEDL_ISAR_PCI_LED1; - byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_off); - break; - case MDL_INFO_REL: - if (cs->subtyp != SEDL_SPEEDFAX_PYRAMID) - return(0); - if ((long) arg) - cs->hw.sedl.reset_off |= SEDL_ISAR_PCI_LED2; - else - cs->hw.sedl.reset_off |= SEDL_ISAR_PCI_LED1; - byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_off); - break; - } - return(0); + if (cs->subtyp != SEDL_SPEEDFAX_PYRAMID) + return; + + if (cs->status & 0x2000) + cs->hw.sedl.reset_off &= ~SEDL_ISAR_PCI_LED2; + else + cs->hw.sedl.reset_off |= SEDL_ISAR_PCI_LED2; + + if (cs->status & 0x1000) + cs->hw.sedl.reset_off &= ~SEDL_ISAR_PCI_LED1; + else + cs->hw.sedl.reset_off |= SEDL_ISAR_PCI_LED1; + + byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_off); } static void @@ -450,24 +429,27 @@ sedlbauer_isar_init(struct IsdnCardState *cs) } static struct card_ops sedlbauer_ops = { - .init = inithscxisac, - .reset = sedlbauer_reset, - .release = sedlbauer_release, - .irq_func = sedlbauer_interrupt, + .init = inithscxisac, + .reset = sedlbauer_reset, + .release = hisax_release_resources, + .led_handler = sedlbauer_led_handler, + .irq_func = sedlbauer_interrupt, }; static struct card_ops sedlbauer_ipac_ops = { - .init = ipac_init, - .reset = sedlbauer_reset, - .release = sedlbauer_release, - .irq_func = ipac_irq, + .init = ipac_init, + .reset = sedlbauer_reset, + .release = hisax_release_resources, + .led_handler = sedlbauer_led_handler, + .irq_func = ipac_irq, }; static struct card_ops sedlbauer_isar_ops = { - .init = sedlbauer_isar_init, - .reset = sedlbauer_reset, - .release = sedlbauer_isar_release, - .irq_func = sedlbauer_isar_interrupt, + .init = sedlbauer_isar_init, + .reset = sedlbauer_reset, + .release = sedlbauer_isar_release, + .led_handler = sedlbauer_led_handler, + .irq_func = sedlbauer_isar_interrupt, }; static struct pci_dev *dev_sedl __devinitdata = NULL; @@ -490,7 +472,7 @@ static struct pnp_card *pnp_c __devinitdata = NULL; int __devinit setup_sedlbauer(struct IsdnCard *card) { - int bytecnt, ver, val; + int bytecnt, val; struct IsdnCardState *cs = card->cs; char tmp[64]; u16 sub_vendor_id, sub_id; @@ -551,7 +533,7 @@ setup_sedlbauer(struct IsdnCard *card) printk(KERN_ERR "Sedlbauer PnP:some resources are missing %ld/%lx\n", pnp_irq(pd, 0), pnp_port_start(pd, 0)); pnp_device_detach(pd); - return(0); + goto err; } card->para[1] = pnp_port_start(pd, 0); card->para[0] = pnp_irq(pd, 0); @@ -568,7 +550,7 @@ setup_sedlbauer(struct IsdnCard *card) goto ready; } else { printk(KERN_ERR "Sedlbauer PnP: PnP error card found, no device\n"); - return(0); + goto err; } } pdev++; @@ -581,23 +563,19 @@ setup_sedlbauer(struct IsdnCard *card) #endif /* Probe for Sedlbauer speed pci */ #if CONFIG_PCI - if (!pci_present()) { - printk(KERN_ERR "Sedlbauer: no PCI bus present\n"); - return(0); - } if ((dev_sedl = pci_find_device(PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100, dev_sedl))) { if (pci_enable_device(dev_sedl)) - return(0); + goto err; cs->irq = dev_sedl->irq; if (!cs->irq) { printk(KERN_WARNING "Sedlbauer: No IRQ for PCI card found\n"); - return(0); + goto err; } cs->hw.sedl.cfg_reg = pci_resource_start(dev_sedl, 0); } else { printk(KERN_WARNING "Sedlbauer: No PCI card found\n"); - return(0); + goto err; } cs->irq_flags |= SA_SHIRQ; cs->hw.sedl.bus = SEDL_BUS_PCI; @@ -609,7 +587,7 @@ setup_sedlbauer(struct IsdnCard *card) cs->hw.sedl.cfg_reg); if (sub_id != PCI_SUB_ID_SEDLBAUER) { printk(KERN_ERR "Sedlbauer: unknown sub id %#x\n", sub_id); - return(0); + goto err; } if (sub_vendor_id == PCI_SUBVENDOR_SPEEDFAX_PYRAMID) { cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR; @@ -623,7 +601,7 @@ setup_sedlbauer(struct IsdnCard *card) } else { printk(KERN_ERR "Sedlbauer: unknown sub vendor id %#x\n", sub_vendor_id); - return(0); + goto err; } bytecnt = 256; cs->hw.sedl.reset_on = SEDL_ISAR_PCI_ISAR_RESET_ON; @@ -636,9 +614,6 @@ setup_sedlbauer(struct IsdnCard *card) current->state = TASK_UNINTERRUPTIBLE; schedule_timeout((10*HZ)/1000); byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_off); -#else - printk(KERN_WARNING "Sedlbauer: NO_PCI_BIOS\n"); - return (0); #endif /* CONFIG_PCI */ } ready: @@ -646,14 +621,9 @@ ready: * reserved for us by the card manager. So we do not check it * here, it would fail. */ - if (cs->hw.sedl.bus != SEDL_BUS_PCMCIA && - (!request_region((cs->hw.sedl.cfg_reg), bytecnt, "sedlbauer isdn"))) { - printk(KERN_WARNING - "HiSax: %s config port %x-%x already in use\n", - CardType[card->typ], - cs->hw.sedl.cfg_reg, - cs->hw.sedl.cfg_reg + bytecnt); - return (0); + if (cs->hw.sedl.bus != SEDL_BUS_PCMCIA) { + if (!request_io(&cs->rs, cs->hw.sedl.cfg_reg, bytecnt, "sedlbauer isdn")) + goto err; } printk(KERN_INFO @@ -662,8 +632,6 @@ ready: cs->hw.sedl.cfg_reg + bytecnt, cs->irq); - cs->cardmsg = &Sedl_card_msg; - /* * testing ISA and PCMCIA Cards for IPAC, default is ISAC * do not test for PCI card, because ports are different @@ -706,16 +674,12 @@ ready: cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC; cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC; } - cs->dc_hw_ops = &ipac_dc_ops; - cs->bc_hw_ops = &ipac_bc_ops; cs->card_ops = &sedlbauer_ipac_ops; - - val = readreg(cs, cs->hw.sedl.isac, IPAC_ID); - printk(KERN_INFO "Sedlbauer: IPAC version %x\n", val); + if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops)) + goto err; sedlbauer_reset(cs); } else { /* ISAC_HSCX oder ISAC_ISAR */ - cs->dc_hw_ops = &isac_ops; if (cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) { if (cs->hw.sedl.bus == SEDL_BUS_PCI) { cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + @@ -741,15 +705,9 @@ ready: test_and_set_bit(HW_ISAR, &cs->HW_Flags); cs->card_ops = &sedlbauer_isar_ops; cs->auxcmd = &isar_auxcmd; - ISACVersion(cs, "Sedlbauer:"); - cs->bc_hw_ops = &isar_ops; - ver = ISARVersion(cs, "Sedlbauer:"); - if (ver < 0) { - printk(KERN_WARNING - "Sedlbauer: wrong ISAR version (ret = %d)\n", ver); - sedlbauer_release(cs); - return (0); - } + isac_setup(cs, &isac_ops); + if (isar_setup(cs, &isar_ops)) + goto err; } else { if (cs->hw.sedl.bus == SEDL_BUS_PCMCIA) { cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_ADR; @@ -765,17 +723,14 @@ ready: cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_RESET_OFF; } cs->card_ops = &sedlbauer_ops; - cs->bc_hw_ops = &hscx_ops; - ISACVersion(cs, "Sedlbauer:"); - - if (HscxVersion(cs, "Sedlbauer:")) { - printk(KERN_WARNING - "Sedlbauer: wrong HSCX versions check IO address\n"); - sedlbauer_release(cs); - return (0); - } + if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) + goto err; + sedlbauer_reset(cs); } } - return (1); + return 1; + err: + hisax_release_resources(cs); + return 0; } diff --git a/drivers/isdn/hisax/sportster.c b/drivers/isdn/hisax/sportster.c index 3f12c0c88ae7..5c215a9857c7 100644 --- a/drivers/isdn/hisax/sportster.c +++ b/drivers/isdn/hisax/sportster.c @@ -170,7 +170,7 @@ static struct card_ops sportster_ops = { static int __init get_io_range(struct IsdnCardState *cs) { - int i, j, adr; + int i, adr; for (i=0;i<64;i++) { adr = cs->hw.spt.cfg_reg + i *1024; @@ -178,20 +178,18 @@ get_io_range(struct IsdnCardState *cs) printk(KERN_WARNING "HiSax: %s config port %x-%x already in use\n", CardType[cs->typ], adr, adr + 8); - break; + goto err; } } - if (i==64) - return(1); - else { - for (j=0; j<i; j++) { - adr = cs->hw.spt.cfg_reg + j *1024; - release_region(adr, 8); - } - return(0); + return 1; + err: + for (i=i-1; i >= 0; i--) { + adr = cs->hw.spt.cfg_reg + i *1024; + release_region(adr, 8); } + return 0; } - + int __init setup_sportster(struct IsdnCard *card) { @@ -200,8 +198,6 @@ setup_sportster(struct IsdnCard *card) strcpy(tmp, sportster_revision); printk(KERN_INFO "HiSax: USR Sportster driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_SPORTSTER) - return (0); cs->hw.spt.cfg_reg = card->para[1]; cs->irq = card->para[0]; @@ -231,21 +227,15 @@ setup_sportster(struct IsdnCard *card) return(0); } sportster_reset(cs); - printk(KERN_INFO - "HiSax: %s config irq:%d cfg:0x%X\n", - CardType[cs->typ], cs->irq, - cs->hw.spt.cfg_reg); + printk(KERN_INFO "HiSax: %s config irq:%d cfg:0x%X\n", + CardType[cs->typ], cs->irq, cs->hw.spt.cfg_reg); - cs->dc_hw_ops = &isac_ops; - cs->bc_hw_ops = &hscx_ops; cs->cardmsg = &Sportster_card_msg; cs->card_ops = &sportster_ops; - ISACVersion(cs, "Sportster:"); - if (HscxVersion(cs, "Sportster:")) { - printk(KERN_WARNING - "Sportster: wrong HSCX versions check IO address\n"); - sportster_release(cs); - return (0); - } - return (1); + if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) + goto err; + return 1; + err: + hisax_release_resources(cs); + return 0; } diff --git a/drivers/isdn/hisax/tei.c b/drivers/isdn/hisax/tei.c index 45c4398311ea..6d8990d470f4 100644 --- a/drivers/isdn/hisax/tei.c +++ b/drivers/isdn/hisax/tei.c @@ -74,6 +74,22 @@ static char *strTeiEvent[] = "EV_T202", }; +static inline void +mdl_assign(struct IsdnCardState *cs) +{ + cs->status |= 0x0001; + if (cs->card_ops->led_handler) + cs->card_ops->led_handler(cs); +} + +static inline void +mdl_remove(struct IsdnCardState *cs) +{ + cs->status = 0; + if (cs->card_ops->led_handler) + cs->card_ops->led_handler(cs); +} + unsigned int random_ri(void) { @@ -167,7 +183,7 @@ tei_id_assign(struct FsmInst *fi, int event, void *arg) FsmChangeState(&st->ma.tei_m, ST_TEI_NOP); L3L2(st, MDL_ASSIGN | REQUEST, (void *) (long) tei); cs = (struct IsdnCardState *) st->l1.hardware; - cs->cardmsg(cs, MDL_ASSIGN | REQUEST, NULL); + mdl_assign(cs); } } @@ -241,7 +257,7 @@ tei_id_remove(struct FsmInst *fi, int event, void *arg) FsmChangeState(&st->ma.tei_m, ST_TEI_NOP); L3L2(st, MDL_REMOVE | REQUEST, 0); cs = (struct IsdnCardState *) st->l1.hardware; - cs->cardmsg(cs, MDL_REMOVE | REQUEST, NULL); + mdl_remove(cs); } } @@ -277,7 +293,7 @@ tei_id_req_tout(struct FsmInst *fi, int event, void *arg) st->ma.tei_m.printdebug(&st->ma.tei_m, "assign req failed"); L3L2(st, MDL_ERROR | RESPONSE, 0); cs = (struct IsdnCardState *) st->l1.hardware; - cs->cardmsg(cs, MDL_REMOVE | REQUEST, NULL); + mdl_remove(cs); FsmChangeState(fi, ST_TEI_NOP); } } @@ -300,7 +316,7 @@ tei_id_ver_tout(struct FsmInst *fi, int event, void *arg) "verify req for tei %d failed", st->l2.tei); L3L2(st, MDL_REMOVE | REQUEST, 0); cs = (struct IsdnCardState *) st->l1.hardware; - cs->cardmsg(cs, MDL_REMOVE | REQUEST, NULL); + mdl_remove(cs); FsmChangeState(fi, ST_TEI_NOP); } } @@ -373,7 +389,7 @@ tei_l2tei(struct PStack *st, int pr, void *arg) "fixed assign tei %d", st->l2.tei); L3L2(st, MDL_ASSIGN | REQUEST, (void *) (long) st->l2.tei); cs = (struct IsdnCardState *) st->l1.hardware; - cs->cardmsg(cs, MDL_ASSIGN | REQUEST, NULL); + mdl_assign(cs); } return; } diff --git a/drivers/isdn/hisax/teleint.c b/drivers/isdn/hisax/teleint.c index c9caf4505553..88c60771dbe3 100644 --- a/drivers/isdn/hisax/teleint.c +++ b/drivers/isdn/hisax/teleint.c @@ -222,8 +222,7 @@ teleint_release(struct IsdnCardState *cs) { del_timer(&cs->hw.hfc.timer); releasehfc(cs); - if (cs->hw.hfc.addr) - release_region(cs->hw.hfc.addr, 2); + hisax_release_resources(cs); } static int @@ -241,12 +240,6 @@ teleint_reset(struct IsdnCardState *cs) return 0; } -static int -TeleInt_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - return(0); -} - static void teleint_init(struct IsdnCardState *cs) { @@ -271,8 +264,6 @@ setup_TeleInt(struct IsdnCard *card) strcpy(tmp, TeleInt_revision); printk(KERN_INFO "HiSax: TeleInt driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_TELEINT) - return (0); cs->hw.hfc.addr = card->para[1] & 0x3fe; cs->irq = card->para[0]; @@ -286,16 +277,9 @@ setup_TeleInt(struct IsdnCard *card) cs->hw.hfc.timer.function = (void *) TeleInt_Timer; cs->hw.hfc.timer.data = (long) cs; init_timer(&cs->hw.hfc.timer); - if (check_region((cs->hw.hfc.addr), 2)) { - printk(KERN_WARNING - "HiSax: %s config port %x-%x already in use\n", - CardType[card->typ], - cs->hw.hfc.addr, - cs->hw.hfc.addr + 2); - return (0); - } else { - request_region(cs->hw.hfc.addr, 2, "TeleInt isdn"); - } + if (!request_io(&cs->rs, cs->hw.hfc.addr, 2, "TeleInt isdn")) + goto err; + /* HW IO = IO */ byteout(cs->hw.hfc.addr, cs->hw.hfc.addr & 0xff); byteout(cs->hw.hfc.addr | 1, ((cs->hw.hfc.addr & 0x300) >> 8) | 0x54); @@ -320,8 +304,7 @@ setup_TeleInt(struct IsdnCard *card) break; default: printk(KERN_WARNING "TeleInt: wrong IRQ\n"); - teleint_release(cs); - return (0); + goto err; } byteout(cs->hw.hfc.addr | 1, cs->hw.hfc.cirm); byteout(cs->hw.hfc.addr | 1, cs->hw.hfc.ctmt); @@ -331,11 +314,12 @@ setup_TeleInt(struct IsdnCard *card) cs->hw.hfc.addr, cs->irq); - teleint_reset(cs); - cs->dc_hw_ops = &isac_ops; - cs->bc_hw_ops = &hfc_ops; - cs->cardmsg = &TeleInt_card_msg; cs->card_ops = &teleint_ops; - ISACVersion(cs, "TeleInt:"); - return (1); + teleint_reset(cs); + isac_setup(cs, &isac_ops); + hfc_setup(cs, &hfc_ops); + return 1; + err: + teleint_release(cs); + return 0; } diff --git a/drivers/isdn/hisax/teles0.c b/drivers/isdn/hisax/teles0.c index 90ff17925afe..b04c12bdfb33 100644 --- a/drivers/isdn/hisax/teles0.c +++ b/drivers/isdn/hisax/teles0.c @@ -48,7 +48,7 @@ static void isac_read_fifo(struct IsdnCardState *cs, u8 * data, int size) { int i; - unsigned long ad = cs->hw.teles0.membase + 0x100; + void *ad = cs->hw.teles0.membase + 0x100; for (i = 0; i < size; i++) data[i] = readb(ad); } @@ -57,7 +57,7 @@ static void isac_write_fifo(struct IsdnCardState *cs, u8 * data, int size) { int i; - unsigned long ad = cs->hw.teles0.membase + 0x100; + void *ad = cs->hw.teles0.membase + 0x100; for (i = 0; i < size; i++) { writeb(data[i], ad); mb(); } @@ -88,7 +88,7 @@ static void hscx_read_fifo(struct IsdnCardState *cs, int hscx, u8 *data, int size) { int i; - unsigned long ad = cs->hw.teles0.membase + (hscx ? 0x1c0 : 0x180); + void *ad = cs->hw.teles0.membase + (hscx ? 0x1c0 : 0x180); for (i = 0; i < size; i++) data[i] = readb(ad); } @@ -97,7 +97,7 @@ static void hscx_write_fifo(struct IsdnCardState *cs, int hscx, u8 *data, int size) { int i; - unsigned long ad = cs->hw.teles0.membase + (hscx ? 0x1c0 : 0x180); + void *ad = cs->hw.teles0.membase + (hscx ? 0x1c0 : 0x180); for (i = 0; i < size; i++) { writeb(data[i], ad); } @@ -110,15 +110,6 @@ static struct bc_hw_ops hscx_ops = { .write_fifo = hscx_write_fifo, }; -static void -teles0_release(struct IsdnCardState *cs) -{ - if (cs->hw.teles0.cfg_reg) - release_region(cs->hw.teles0.cfg_reg, 8); - iounmap((unsigned char *)cs->hw.teles0.membase); - release_mem_region(cs->hw.teles0.phymem, TELES_IOMEM_SIZE); -} - static int teles0_reset(struct IsdnCardState *cs) { @@ -167,16 +158,10 @@ teles0_reset(struct IsdnCardState *cs) return(0); } -static int -Teles_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - return(0); -} - static struct card_ops teles0_ops = { .init = inithscxisac, .reset = teles0_reset, - .release = teles0_release, + .release = hisax_release_resources, .irq_func = hscxisac_irq, }; @@ -189,9 +174,6 @@ setup_teles0(struct IsdnCard *card) strcpy(tmp, teles0_revision); printk(KERN_INFO "HiSax: Teles 8.0/16.0 driver Rev. %s\n", HiSax_getrev(tmp)); - if ((cs->typ != ISDN_CTYPE_16_0) && (cs->typ != ISDN_CTYPE_8_0)) - return (0); - if (cs->typ == ISDN_CTYPE_16_0) cs->hw.teles0.cfg_reg = card->para[2]; else /* 8.0 */ @@ -205,76 +187,50 @@ setup_teles0(struct IsdnCard *card) } cs->irq = card->para[0]; if (cs->hw.teles0.cfg_reg) { - if (!request_region(cs->hw.teles0.cfg_reg, 8, "teles cfg")) { - printk(KERN_WARNING - "HiSax: %s config port %x-%x already in use\n", - CardType[card->typ], - cs->hw.teles0.cfg_reg, - cs->hw.teles0.cfg_reg + 8); - return (0); - } - } - if (cs->hw.teles0.cfg_reg) { + if (!request_io(&cs->rs, cs->hw.teles0.cfg_reg, 8, "teles cfg")) + goto err; + if ((val = bytein(cs->hw.teles0.cfg_reg + 0)) != 0x51) { printk(KERN_WARNING "Teles0: 16.0 Byte at %x is %x\n", cs->hw.teles0.cfg_reg + 0, val); - release_region(cs->hw.teles0.cfg_reg, 8); - return (0); + goto err; } if ((val = bytein(cs->hw.teles0.cfg_reg + 1)) != 0x93) { printk(KERN_WARNING "Teles0: 16.0 Byte at %x is %x\n", cs->hw.teles0.cfg_reg + 1, val); - release_region(cs->hw.teles0.cfg_reg, 8); - return (0); + goto err; } - val = bytein(cs->hw.teles0.cfg_reg + 2); /* 0x1e=without AB - * 0x1f=with AB - * 0x1c 16.3 ??? - */ + val = bytein(cs->hw.teles0.cfg_reg + 2);/* 0x1e=without AB + * 0x1f=with AB + * 0x1c 16.3 ??? + */ if (val != 0x1e && val != 0x1f) { printk(KERN_WARNING "Teles0: 16.0 Byte at %x is %x\n", cs->hw.teles0.cfg_reg + 2, val); - release_region(cs->hw.teles0.cfg_reg, 8); - return (0); + goto err; } } /* 16.0 and 8.0 designed for IOM1 */ test_and_set_bit(HW_IOM1, &cs->HW_Flags); cs->hw.teles0.phymem = card->para[1]; - if (check_mem_region(cs->hw.teles0.phymem, TELES_IOMEM_SIZE)) { - printk(KERN_WARNING - "HiSax: %s memory region %lx-%lx already in use\n", - CardType[card->typ], - cs->hw.teles0.phymem, - cs->hw.teles0.phymem + TELES_IOMEM_SIZE); - if (cs->hw.teles0.cfg_reg) - release_region(cs->hw.teles0.cfg_reg, 8); - return (0); - } else { - request_mem_region(cs->hw.teles0.phymem, TELES_IOMEM_SIZE, - "teles iomem"); - } - cs->hw.teles0.membase = - (unsigned long) ioremap(cs->hw.teles0.phymem, TELES_IOMEM_SIZE); + cs->hw.teles0.membase = request_mmio(&cs->rs, cs->hw.teles0.phymem, TELES_IOMEM_SIZE, "teles iomem"); + if (!cs->hw.teles0.membase) + goto err; + printk(KERN_INFO - "HiSax: %s config irq:%d mem:0x%lX cfg:0x%X\n", + "HiSax: %s config irq:%d mem:0x%p cfg:0x%X\n", CardType[cs->typ], cs->irq, cs->hw.teles0.membase, cs->hw.teles0.cfg_reg); if (teles0_reset(cs)) { printk(KERN_WARNING "Teles0: wrong IRQ\n"); - teles0_release(cs); - return (0); + goto err; } - cs->dc_hw_ops = &isac_ops; - cs->bc_hw_ops = &hscx_ops; - cs->cardmsg = &Teles_card_msg; cs->card_ops = &teles0_ops; - ISACVersion(cs, "Teles0:"); - if (HscxVersion(cs, "Teles0:")) { - printk(KERN_WARNING - "Teles0: wrong HSCX versions check IO/MEM addresses\n"); - teles0_release(cs); - return (0); - } - return (1); + if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) + goto err; + return 1; + + err: + hisax_release_resources(cs); + return 0; } diff --git a/drivers/isdn/hisax/teles3.c b/drivers/isdn/hisax/teles3.c index 6205f1efd345..06528fdfa5db 100644 --- a/drivers/isdn/hisax/teles3.c +++ b/drivers/isdn/hisax/teles3.c @@ -113,34 +113,6 @@ static struct bc_hw_ops hscx_ops = { .write_fifo = hscx_write_fifo, }; -inline static void -release_ioregs(struct IsdnCardState *cs, int mask) -{ - if (mask & 1) - release_region(cs->hw.teles3.isac + 32, 32); - if (mask & 2) - release_region(cs->hw.teles3.hscx[0] + 32, 32); - if (mask & 4) - release_region(cs->hw.teles3.hscx[1] + 32, 32); -} - -static void -teles3_release(struct IsdnCardState *cs) -{ - if (cs->typ == ISDN_CTYPE_TELESPCMCIA) { - release_region(cs->hw.teles3.hscx[1], 96); - } else { - if (cs->hw.teles3.cfg_reg) { - if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) { - release_region(cs->hw.teles3.cfg_reg, 1); - } else { - release_region(cs->hw.teles3.cfg_reg, 8); - } - } - release_ioregs(cs, 0x7); - } -} - static int teles3_reset(struct IsdnCardState *cs) { @@ -197,16 +169,10 @@ teles3_reset(struct IsdnCardState *cs) return(0); } -static int -Teles_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - return(0); -} - static struct card_ops teles3_ops = { .init = inithscxisac, .reset = teles3_reset, - .release = teles3_release, + .release = hisax_release_resources, .irq_func = hscxisac_irq, }; @@ -325,95 +291,35 @@ setup_teles3(struct IsdnCard *card) cs->hw.teles3.hscxfifo[0] = cs->hw.teles3.hscx[0] + 0x3e; cs->hw.teles3.hscxfifo[1] = cs->hw.teles3.hscx[1] + 0x3e; if (cs->typ == ISDN_CTYPE_TELESPCMCIA) { - if (!request_region(cs->hw.teles3.hscx[1], 96, "HiSax Teles PCMCIA")) { - printk(KERN_WARNING - "HiSax: %s ports %x-%x already in use\n", - CardType[cs->typ], - cs->hw.teles3.hscx[1], - cs->hw.teles3.hscx[1] + 96); - return (0); - } + if (!request_io(&cs->rs, cs->hw.teles3.hscx[1], 96, "HiSax Teles PCMCIA")) + goto err; } else { if (cs->hw.teles3.cfg_reg) { if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) { - if (!request_region(cs->hw.teles3.cfg_reg, 1, "teles3 cfg")) { - printk(KERN_WARNING - "HiSax: %s config port %x already in use\n", - CardType[card->typ], - cs->hw.teles3.cfg_reg); - return (0); - } + if (!request_io(&cs->rs, cs->hw.teles3.cfg_reg, 1, "teles3 cfg")) + goto err; } else { - if (!request_region(cs->hw.teles3.cfg_reg, 8, "teles3 cfg")) { - printk(KERN_WARNING - "HiSax: %s config port %x-%x already in use\n", - CardType[card->typ], - cs->hw.teles3.cfg_reg, - cs->hw.teles3.cfg_reg + 8); - return (0); - } - } - } - if (!request_region(cs->hw.teles3.isac + 32, 32, "HiSax isac")) { - printk(KERN_WARNING - "HiSax: %s isac ports %x-%x already in use\n", - CardType[cs->typ], - cs->hw.teles3.isac + 32, - cs->hw.teles3.isac + 64); - if (cs->hw.teles3.cfg_reg) { - if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) { - release_region(cs->hw.teles3.cfg_reg, 1); - } else { - release_region(cs->hw.teles3.cfg_reg, 8); - } + if (!request_io(&cs->rs, cs->hw.teles3.cfg_reg, 8, "teles3 cfg")) + goto err; } - return (0); - } - if (!request_region(cs->hw.teles3.hscx[0] + 32, 32, "HiSax hscx A")) { - printk(KERN_WARNING - "HiSax: %s hscx A ports %x-%x already in use\n", - CardType[cs->typ], - cs->hw.teles3.hscx[0] + 32, - cs->hw.teles3.hscx[0] + 64); - if (cs->hw.teles3.cfg_reg) { - if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) { - release_region(cs->hw.teles3.cfg_reg, 1); - } else { - release_region(cs->hw.teles3.cfg_reg, 8); - } - } - release_ioregs(cs, 1); - return (0); - } - if (!request_region(cs->hw.teles3.hscx[1] + 32, 32, "HiSax hscx B")) { - printk(KERN_WARNING - "HiSax: %s hscx B ports %x-%x already in use\n", - CardType[cs->typ], - cs->hw.teles3.hscx[1] + 32, - cs->hw.teles3.hscx[1] + 64); - if (cs->hw.teles3.cfg_reg) { - if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) { - release_region(cs->hw.teles3.cfg_reg, 1); - } else { - release_region(cs->hw.teles3.cfg_reg, 8); - } - } - release_ioregs(cs, 3); - return (0); } + if (!request_io(&cs->rs, cs->hw.teles3.isac + 32, 32, "HiSax isac")) + goto err; + if (!request_io(&cs->rs, cs->hw.teles3.hscx[0] + 32, 32, "HiSax hscx A")) + goto err; + if (!request_io(&cs->rs, cs->hw.teles3.hscx[1] + 32, 32, "HiSax hscx B")) + goto err; } if ((cs->hw.teles3.cfg_reg) && (cs->typ != ISDN_CTYPE_COMPAQ_ISA)) { if ((val = bytein(cs->hw.teles3.cfg_reg + 0)) != 0x51) { printk(KERN_WARNING "Teles: 16.3 Byte at %x is %x\n", cs->hw.teles3.cfg_reg + 0, val); - teles3_release(cs); - return (0); + goto err; } if ((val = bytein(cs->hw.teles3.cfg_reg + 1)) != 0x93) { printk(KERN_WARNING "Teles: 16.3 Byte at %x is %x\n", cs->hw.teles3.cfg_reg + 1, val); - teles3_release(cs); - return (0); + goto err; } val = bytein(cs->hw.teles3.cfg_reg + 2);/* 0x1e=without AB * 0x1f=with AB @@ -425,8 +331,7 @@ setup_teles3(struct IsdnCard *card) if (val != 0x46 && val != 0x39 && val != 0x38 && val != 0x1c && val != 0x1e && val != 0x1f) { printk(KERN_WARNING "Teles: 16.3 Byte at %x is %x\n", cs->hw.teles3.cfg_reg + 2, val); - teles3_release(cs); - return (0); + goto err; } } printk(KERN_INFO @@ -439,19 +344,14 @@ setup_teles3(struct IsdnCard *card) if (teles3_reset(cs)) { printk(KERN_WARNING "Teles3: wrong IRQ\n"); - teles3_release(cs); - return (0); + goto err; } - cs->dc_hw_ops = &isac_ops; - cs->bc_hw_ops = &hscx_ops; - cs->cardmsg = &Teles_card_msg; cs->card_ops = &teles3_ops; - ISACVersion(cs, "Teles3:"); - if (HscxVersion(cs, "Teles3:")) { - printk(KERN_WARNING - "Teles3: wrong HSCX versions check IO address\n"); - teles3_release(cs); - return (0); - } - return (1); + if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) + goto err; + return 1; + err: + hisax_release_resources(cs); + return 0; + } diff --git a/drivers/isdn/hisax/telespci.c b/drivers/isdn/hisax/telespci.c index f19bb1d26a3f..5e4388256cf0 100644 --- a/drivers/isdn/hisax/telespci.c +++ b/drivers/isdn/hisax/telespci.c @@ -45,7 +45,7 @@ const char *telespci_revision = "$Revision: 2.16.6.5 $"; static u8 isac_read(struct IsdnCardState *cs, u8 off) { - unsigned long adr = cs->hw.teles0.membase + 0x200; + void *adr = cs->hw.teles0.membase + 0x200; unsigned int portdata; ZORAN_WAIT_NOBUSY; @@ -63,7 +63,7 @@ isac_read(struct IsdnCardState *cs, u8 off) static void isac_write(struct IsdnCardState *cs, u8 off, u8 data) { - unsigned long adr = cs->hw.teles0.membase + 0x200; + void *adr = cs->hw.teles0.membase + 0x200; unsigned int portdata; ZORAN_WAIT_NOBUSY; @@ -80,7 +80,7 @@ isac_write(struct IsdnCardState *cs, u8 off, u8 data) static void isac_read_fifo(struct IsdnCardState *cs, u8 *data, int size) { - unsigned long adr = cs->hw.teles0.membase + 0x200; + void *adr = cs->hw.teles0.membase + 0x200; unsigned int portdata; int i; @@ -99,7 +99,7 @@ isac_read_fifo(struct IsdnCardState *cs, u8 *data, int size) static void isac_write_fifo(struct IsdnCardState *cs, u8 *data, int size) { - unsigned long adr = cs->hw.teles0.membase + 0x200; + void *adr = cs->hw.teles0.membase + 0x200; unsigned int portdata; int i; @@ -124,7 +124,7 @@ static struct dc_hw_ops isac_ops = { static u8 hscx_read(struct IsdnCardState *cs, int hscx, u8 off) { - unsigned long adr = cs->hw.teles0.membase + 0x200; + void *adr = cs->hw.teles0.membase + 0x200; unsigned int portdata; ZORAN_WAIT_NOBUSY; @@ -141,7 +141,7 @@ hscx_read(struct IsdnCardState *cs, int hscx, u8 off) static void hscx_write(struct IsdnCardState *cs, int hscx, u8 off, u8 data) { - unsigned long adr = cs->hw.teles0.membase + 0x200; + void *adr = cs->hw.teles0.membase + 0x200; unsigned int portdata; ZORAN_WAIT_NOBUSY; @@ -157,7 +157,7 @@ hscx_write(struct IsdnCardState *cs, int hscx, u8 off, u8 data) static void hscx_read_fifo(struct IsdnCardState *cs, int hscx, u8 * data, int size) { - unsigned long adr = cs->hw.teles0.membase + 0x200; + void *adr = cs->hw.teles0.membase + 0x200; unsigned int portdata; int i; @@ -176,7 +176,7 @@ hscx_read_fifo(struct IsdnCardState *cs, int hscx, u8 * data, int size) static void hscx_write_fifo(struct IsdnCardState *cs, int hscx, u8 * data, int size) { - unsigned long adr = cs->hw.teles0.membase + 0x200; + void *adr = cs->hw.teles0.membase + 0x200; unsigned int portdata; int i; @@ -225,21 +225,9 @@ telespci_interrupt(int intno, void *dev_id, struct pt_regs *regs) spin_unlock(&cs->lock); } -void -telespci_release(struct IsdnCardState *cs) -{ - iounmap((void *)cs->hw.teles0.membase); -} - -static int -TelesPCI_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - return(0); -} - static struct card_ops telespci_ops = { .init = inithscxisac, - .release = telespci_release, + .release = hisax_release_resources, .irq_func = telespci_interrupt, }; @@ -256,13 +244,6 @@ setup_telespci(struct IsdnCard *card) #endif strcpy(tmp, telespci_revision); printk(KERN_INFO "HiSax: Teles/PCI driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_TELESPCI) - return (0); -#if CONFIG_PCI - if (!pci_present()) { - printk(KERN_ERR "TelesPCI: no PCI bus present\n"); - return(0); - } if ((dev_tel = pci_find_device (PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36120, dev_tel))) { if (pci_enable_device(dev_tel)) return(0); @@ -271,19 +252,15 @@ setup_telespci(struct IsdnCard *card) printk(KERN_WARNING "Teles: No IRQ for PCI card found\n"); return(0); } - cs->hw.teles0.membase = (u_long) ioremap(pci_resource_start(dev_tel, 0), - PAGE_SIZE); + cs->hw.teles0.membase = request_mmio(&cs->rs, pci_resource_start(dev_tel, 0), 4096, "telespci"); + if (!cs->hw.teles0.membase) + goto err; printk(KERN_INFO "Found: Zoran, base-address: 0x%lx, irq: 0x%x\n", pci_resource_start(dev_tel, 0), dev_tel->irq); } else { printk(KERN_WARNING "TelesPCI: No PCI card found\n"); return(0); } -#else - printk(KERN_WARNING "HiSax: Teles/PCI and NO_PCI_BIOS\n"); - printk(KERN_WARNING "HiSax: Teles/PCI unable to config\n"); - return (0); -#endif /* CONFIG_PCI */ /* Initialize Zoran PCI controller */ writel(0x00000000, cs->hw.teles0.membase + 0x28); @@ -293,23 +270,17 @@ setup_telespci(struct IsdnCard *card) writel(0x70000000, cs->hw.teles0.membase + 0x3C); writel(0x61000000, cs->hw.teles0.membase + 0x40); /* writel(0x00800000, cs->hw.teles0.membase + 0x200); */ - printk(KERN_INFO - "HiSax: %s config irq:%d mem:%lx\n", + "HiSax: %s config irq:%d mem:%p\n", CardType[cs->typ], cs->irq, cs->hw.teles0.membase); - cs->dc_hw_ops = &isac_ops; - cs->bc_hw_ops = &hscx_ops; - cs->cardmsg = &TelesPCI_card_msg; cs->irq_flags |= SA_SHIRQ; cs->card_ops = &telespci_ops; - ISACVersion(cs, "TelesPCI:"); - if (HscxVersion(cs, "TelesPCI:")) { - printk(KERN_WARNING - "TelesPCI: wrong HSCX versions check IO/MEM addresses\n"); - telespci_release(cs); - return (0); - } - return (1); + if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) + goto err; + return 1; + err: + hisax_release_resources(cs); + return 0; } diff --git a/drivers/isdn/hisax/w6692.c b/drivers/isdn/hisax/w6692.c index cc7f00dcb609..235d7e4dca6c 100644 --- a/drivers/isdn/hisax/w6692.c +++ b/drivers/isdn/hisax/w6692.c @@ -639,15 +639,9 @@ static void w6692_release(struct IsdnCardState *cs) { w6692_write_reg(cs, W_IMASK, 0xff); - release_region(cs->hw.w6692.iobase, 256); if (cs->subtyp == W6692_USR) w6692_write_reg(cs, W_XDATA, 0x04); -} - -static int -w6692_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - return (0); + hisax_release_resources(cs); } static struct card_ops w6692_ops = { @@ -674,6 +668,23 @@ static int id_idx ; static struct pci_dev *dev_w6692 __initdata = NULL; +static int +w6692_setup(struct IsdnCardState *cs, struct dc_hw_ops *dc_ops, + struct bc_hw_ops *bc_ops) +{ + cs->dc_hw_ops = dc_ops; + cs->bc_hw_ops = bc_ops; + dc_l1_init(cs, &w6692_dc_l1_ops); + cs->bc_l1_ops = &w6692_bc_l1_ops; + W6692Version(cs, "W6692:"); + printk(KERN_INFO "W6692 ISTA=0x%X\n", w6692_read_reg(cs, W_ISTA)); + printk(KERN_INFO "W6692 IMASK=0x%X\n", w6692_read_reg(cs, W_IMASK)); + printk(KERN_INFO "W6692 D_EXIR=0x%X\n", w6692_read_reg(cs, W_D_EXIR)); + printk(KERN_INFO "W6692 D_EXIM=0x%X\n", w6692_read_reg(cs, W_D_EXIM)); + printk(KERN_INFO "W6692 D_RSTA=0x%X\n", w6692_read_reg(cs, W_D_RSTA)); + return 0; +} + int __init setup_w6692(struct IsdnCard *card) { @@ -688,13 +699,6 @@ setup_w6692(struct IsdnCard *card) #endif strcpy(tmp, w6692_revision); printk(KERN_INFO "HiSax: W6692 driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_W6692) - return (0); -#if CONFIG_PCI - if (!pci_present()) { - printk(KERN_ERR "W6692: no PCI bus present\n"); - return (0); - } while (id_list[id_idx].vendor_id) { dev_w6692 = pci_find_device(id_list[id_idx].vendor_id, id_list[id_idx].device_id, @@ -738,38 +742,16 @@ setup_w6692(struct IsdnCard *card) printk(KERN_INFO "Found: %s %s, I/O base: 0x%x, irq: %d\n", id_list[cs->subtyp].vendor_name, id_list[cs->subtyp].card_name, pci_ioaddr, pci_irq); - if (!request_region((cs->hw.w6692.iobase), 256, - id_list[cs->subtyp].card_name)) { - printk(KERN_WARNING - "HiSax: %s I/O ports %x-%x already in use\n", - id_list[cs->subtyp].card_name, - cs->hw.w6692.iobase, - cs->hw.w6692.iobase + 255); - return (0); - } -#else - printk(KERN_WARNING "HiSax: W6692 and NO_PCI_BIOS\n"); - printk(KERN_WARNING "HiSax: W6692 unable to config\n"); - return (0); -#endif /* CONFIG_PCI */ - + if (!request_io(&cs->rs, cs->hw.w6692.iobase, 0x100, id_list[cs->subtyp].card_name)) + return 0; + printk(KERN_INFO "HiSax: %s config irq:%d I/O:%x\n", id_list[cs->subtyp].card_name, cs->irq, cs->hw.w6692.iobase); - cs->dc_hw_ops = &w6692_dc_hw_ops; - cs->bc_hw_ops = &w6692_bc_hw_ops; - dc_l1_init(cs, &w6692_dc_l1_ops); - cs->bc_l1_ops = &w6692_bc_l1_ops; - cs->cardmsg = &w6692_card_msg; - cs->irq_flags |= SA_SHIRQ; cs->card_ops = &w6692_ops; - W6692Version(cs, "W6692:"); - printk(KERN_INFO "W6692 ISTA=0x%X\n", w6692_read_reg(cs, W_ISTA)); - printk(KERN_INFO "W6692 IMASK=0x%X\n", w6692_read_reg(cs, W_IMASK)); - printk(KERN_INFO "W6692 D_EXIR=0x%X\n", w6692_read_reg(cs, W_D_EXIR)); - printk(KERN_INFO "W6692 D_EXIM=0x%X\n", w6692_read_reg(cs, W_D_EXIM)); - printk(KERN_INFO "W6692 D_RSTA=0x%X\n", w6692_read_reg(cs, W_D_RSTA)); + w6692_setup(cs, &w6692_dc_hw_ops, &w6692_bc_hw_ops); + cs->irq_flags |= SA_SHIRQ; return (1); } diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 687a9781ee71..ca6fb8ee5a52 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -262,7 +262,8 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses); DBG("Scanning behind PCI bridge %s, config %06x, pass %d\n", dev->slot_name, buses & 0xffffff, pass); - if ((buses & 0xffff00) && !pcibios_assign_all_busses()) { + if ((buses & 0xffff00) && !pcibios_assign_all_busses() && !is_cardbus) { + unsigned int cmax; /* * Bus already configured by firmware, process it in the first * pass and just note the configuration. @@ -274,13 +275,8 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max child->secondary = (buses >> 8) & 0xFF; child->subordinate = (buses >> 16) & 0xFF; child->number = child->secondary; - if (!is_cardbus) { - unsigned int cmax = pci_do_scan_bus(child); - if (cmax > max) max = cmax; - } else { - unsigned int cmax = child->subordinate; - if (cmax > max) max = cmax; - } + cmax = pci_do_scan_bus(child); + if (cmax > max) max = cmax; } else { /* * We need to assign a number to this bus which we always diff --git a/fs/compat.c b/fs/compat.c index 2a0bdefb362a..9e8906a35ccc 100644 --- a/fs/compat.c +++ b/fs/compat.c @@ -17,6 +17,8 @@ #include <linux/time.h> #include <linux/fs.h> #include <linux/fcntl.h> +#include <linux/namei.h> +#include <linux/file.h> #include <asm/uaccess.h> @@ -101,3 +103,58 @@ int put_compat_flock(struct flock *kfl, struct compat_flock *ufl) err |= __put_user(kfl->l_pid, &ufl->l_pid); return err; } + +static int put_compat_statfs(struct compat_statfs *ubuf, struct statfs *kbuf) +{ + if (verify_area(VERIFY_WRITE, ubuf, sizeof(*ubuf)) || + __put_user(kbuf->f_type, &ubuf->f_type) || + __put_user(kbuf->f_bsize, &ubuf->f_bsize) || + __put_user(kbuf->f_blocks, &ubuf->f_blocks) || + __put_user(kbuf->f_bfree, &ubuf->f_bfree) || + __put_user(kbuf->f_bavail, &ubuf->f_bavail) || + __put_user(kbuf->f_files, &ubuf->f_files) || + __put_user(kbuf->f_ffree, &ubuf->f_ffree) || + __put_user(kbuf->f_namelen, &ubuf->f_namelen) || + __put_user(kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]) || + __put_user(kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1])) + return -EFAULT; + return 0; +} + +/* + * The following statfs calls are copies of code from fs/open.c and + * should be checked against those from time to time + */ +asmlinkage long compat_sys_statfs(const char *path, struct compat_statfs *buf) +{ + struct nameidata nd; + int error; + + error = user_path_walk(path, &nd); + if (!error) { + struct statfs tmp; + error = vfs_statfs(nd.dentry->d_inode->i_sb, &tmp); + if (!error && put_compat_statfs(buf, &tmp)) + error = -EFAULT; + path_release(&nd); + } + return error; +} + +asmlinkage long compat_sys_fstatfs(unsigned int fd, struct compat_statfs *buf) +{ + struct file * file; + struct statfs tmp; + int error; + + error = -EBADF; + file = fget(fd); + if (!file) + goto out; + error = vfs_statfs(file->f_dentry->d_inode->i_sb, &tmp); + if (!error && put_compat_statfs(buf, &tmp)) + error = -EFAULT; + fput(file); +out: + return error; +} diff --git a/include/asm-i386/ptrace.h b/include/asm-i386/ptrace.h index e6d24421aa63..d80fd6557d05 100644 --- a/include/asm-i386/ptrace.h +++ b/include/asm-i386/ptrace.h @@ -51,6 +51,9 @@ struct pt_regs { #define PTRACE_OLDSETOPTIONS 21 +#define PTRACE_GET_THREAD_AREA 25 +#define PTRACE_SET_THREAD_AREA 26 + #ifdef __KERNEL__ #define user_mode(regs) ((VM_MASK & (regs)->eflags) || (3 & (regs)->xcs)) #define instruction_pointer(regs) ((regs)->eip) diff --git a/include/asm-s390x/compat.h b/include/asm-s390x/compat.h index d84bb8d4020d..1b2a43d03fe1 100644 --- a/include/asm-s390x/compat.h +++ b/include/asm-s390x/compat.h @@ -67,4 +67,17 @@ struct compat_flock { short __unused; }; +struct compat_statfs { + s32 f_type; + s32 f_bsize; + s32 f_blocks; + s32 f_bfree; + s32 f_bavail; + s32 f_files; + s32 f_ffree; + compat_fsid_t f_fsid; + s32 f_namelen; + s32 f_spare[6]; +}; + #endif /* _ASM_S390X_COMPAT_H */ diff --git a/kernel/module.c b/kernel/module.c index bd289a331692..5e299131c116 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -679,19 +679,19 @@ static int obsolete_params(const char *name, if (!kp) return -ENOMEM; - DEBUGP("Module %s has %u obsolete params\n", name, num); - for (i = 0; i < num; i++) - DEBUGP("Param %i: %s type %s\n", - num, obsparm[i].name, obsparm[i].type); - for (i = 0; i < num; i++) { + char sym_name[128 + sizeof(MODULE_SYMBOL_PREFIX)]; + + snprintf(sym_name, sizeof(sym_name), "%s%s", + MODULE_SYMBOL_PREFIX, obsparm[i].name); + kp[i].name = obsparm[i].name; kp[i].perm = 000; kp[i].set = set_obsolete; kp[i].get = NULL; obsparm[i].addr = (void *)find_local_symbol(sechdrs, symindex, strtab, - obsparm[i].name); + sym_name); if (!obsparm[i].addr) { printk("%s: falsely claims to have parameter %s\n", name, obsparm[i].name); @@ -1096,17 +1096,17 @@ static struct module *load_module(void *umod, mod = (void *)sechdrs[modindex].sh_addr; /* Now copy in args */ - err = strlen_user(uargs); - if (err < 0) + arglen = strlen_user(uargs); + if (!arglen) { + err = -EFAULT; goto free_hdr; - arglen = err; - - args = kmalloc(arglen+1, GFP_KERNEL); + } + args = kmalloc(arglen, GFP_KERNEL); if (!args) { err = -ENOMEM; goto free_hdr; } - if (copy_from_user(args, uargs, arglen+1) != 0) { + if (copy_from_user(args, uargs, arglen) != 0) { err = -EFAULT; goto free_mod; } |
