## Automatically generated incremental diff ## From: linux-2.5.64-bk3 ## To: linux-2.5.64-bk4 ## Robot: $Id: make-incremental-diff,v 1.11 2002/02/20 02:59:33 hpa Exp $ diff -urN linux-2.5.64-bk3/Documentation/basic_profiling.txt linux-2.5.64-bk4/Documentation/basic_profiling.txt --- linux-2.5.64-bk3/Documentation/basic_profiling.txt Wed Dec 31 16:00:00 1969 +++ linux-2.5.64-bk4/Documentation/basic_profiling.txt Mon Mar 31 12:25:43 2003 @@ -0,0 +1,48 @@ +These instructions are deliberately very basic. If you want something clever, +go read the real docs ;-) Please don't add more stuff, but feel free to +correct my mistakes ;-) (mbligh@aracnet.com) +Thanks to John Levon, Dave Hansen, et al. for help writing this. + + is the thing you're trying to measure. +Make sure you have the correct System.map / vmlinux referenced! +IMHO it's easier to use "make install" for linux and hack /sbin/installkernel +to copy config files, system.map, vmlinux to /boot. + +Readprofile +----------- +You need a fixed readprofile command for 2.5 ... either get hold of +a current version from: +http://www.kernel.org/pub/linux/utils/util-linux/ +or get readprofile binary fixed for 2.5 / akpm's 2.5 patch from +ftp://ftp.kernel.org/pub/linux/kernel/people/mbligh/tools/readprofile/ + +Add "profile=2" to the kernel command line. + +clear readprofile -r + +dump output readprofile -m /boot/System.map > captured_profile + +Oprofile +-------- +get source (I use 0.5) from http://oprofile.sourceforge.net/ +add "idle=poll" to the kernel command line +Configure with CONFIG_PROFILING=y and CONFIG_OPROFILE=y & reboot on new kernel +./configure --with-kernel-support +make install + +One time setup (pick appropriate one for your CPU): +P3 opcontrol --setup --vmlinux=/boot/vmlinux \ + --ctr0-event=CPU_CLK_UNHALTED --ctr0-count=100000 +Athlon/x86-64 opcontrol --setup --vmlinux=/boot/vmlinux \ + --ctr0-event=RETIRED_INSNS --ctr0-count=100000 +P4 opcontrol --setup --vmlinux=/boot/vmlinux \ + --ctr0-event=GLOBAL_POWER_EVENTS \ + --ctr0-unit-mask=1 --ctr0-count=100000 + +start daemon opcontrol --start-daemon +clear opcontrol --reset +start opcontrol --start + +stop opcontrol --stop +dump output oprofpp -dl -i /boot/vmlinux > output_file + diff -urN linux-2.5.64-bk3/Documentation/cdrom/cdrom-standard.tex linux-2.5.64-bk4/Documentation/cdrom/cdrom-standard.tex --- linux-2.5.64-bk3/Documentation/cdrom/cdrom-standard.tex Tue Mar 4 19:29:03 2003 +++ linux-2.5.64-bk4/Documentation/cdrom/cdrom-standard.tex Mon Mar 31 12:25:43 2003 @@ -758,11 +758,8 @@ \subsection{$Struct\ file_operations\ cdrom_fops$} The contents of this structure were described in section~\ref{cdrom.c}. -As already stated, this structure should be used to register block -devices with the kernel: -$$ -register_blkdev(major, , \&cdrom_fops); -$$ +A pointer to this structure is assigned to the $fops$ field +of the $struct gendisk$. \subsection{$Int\ register_cdrom( struct\ cdrom_device_info\ * cdi)$} diff -urN linux-2.5.64-bk3/Makefile linux-2.5.64-bk4/Makefile --- linux-2.5.64-bk3/Makefile Mon Mar 31 12:25:41 2003 +++ linux-2.5.64-bk4/Makefile Mon Mar 31 12:25:43 2003 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 5 SUBLEVEL = 64 -EXTRAVERSION = bk3 +EXTRAVERSION = bk4 # *DOCUMENTATION* # To see a list of typical targets execute "make help" diff -urN linux-2.5.64-bk3/arch/alpha/Kconfig linux-2.5.64-bk4/arch/alpha/Kconfig --- linux-2.5.64-bk3/arch/alpha/Kconfig Tue Mar 4 19:29:32 2003 +++ linux-2.5.64-bk4/arch/alpha/Kconfig Mon Mar 31 12:25:43 2003 @@ -15,10 +15,6 @@ bool default y -config SWAP - bool - default y - config UID16 bool diff -urN linux-2.5.64-bk3/arch/alpha/kernel/irq.c linux-2.5.64-bk4/arch/alpha/kernel/irq.c --- linux-2.5.64-bk3/arch/alpha/kernel/irq.c Tue Mar 4 19:29:33 2003 +++ linux-2.5.64-bk4/arch/alpha/kernel/irq.c Mon Mar 31 12:25:43 2003 @@ -515,6 +515,7 @@ #endif int i; struct irqaction * action; + unsigned long flags; #ifdef CONFIG_SMP seq_puts(p, " "); @@ -525,9 +526,10 @@ #endif for (i = 0; i < ACTUAL_NR_IRQS; i++) { + spin_lock_irqsave(&irq_desc[i].lock, flags); action = irq_desc[i].action; if (!action) - continue; + goto unlock; seq_printf(p, "%3d: ",i); #ifndef CONFIG_SMP seq_printf(p, "%10u ", kstat_irqs(i)); @@ -538,15 +540,18 @@ #endif seq_printf(p, " %14s", irq_desc[i].handler->typename); seq_printf(p, " %c%s", - (action->flags & SA_INTERRUPT)?'+':' ', - action->name); + (action->flags & SA_INTERRUPT)?'+':' ', + action->name); for (action=action->next; action; action = action->next) { seq_printf(p, ", %c%s", - (action->flags & SA_INTERRUPT)?'+':' ', - action->name); + (action->flags & SA_INTERRUPT)?'+':' ', + action->name); } + seq_putc(p, '\n'); +unlock: + spin_unlock_irqrestore(&irq_desc[i].lock, flags); } #if CONFIG_SMP seq_puts(p, "IPI: "); diff -urN linux-2.5.64-bk3/arch/arm/Kconfig linux-2.5.64-bk4/arch/arm/Kconfig --- linux-2.5.64-bk3/arch/arm/Kconfig Mon Mar 31 12:25:41 2003 +++ linux-2.5.64-bk4/arch/arm/Kconfig Mon Mar 31 12:25:43 2003 @@ -20,10 +20,6 @@ bool default y -config SWAP - bool - default y - config EISA bool ---help--- diff -urN linux-2.5.64-bk3/arch/arm/kernel/irq.c linux-2.5.64-bk4/arch/arm/kernel/irq.c --- linux-2.5.64-bk3/arch/arm/kernel/irq.c Tue Mar 4 19:28:52 2003 +++ linux-2.5.64-bk4/arch/arm/kernel/irq.c Mon Mar 31 12:25:43 2003 @@ -165,17 +165,22 @@ { int i; struct irqaction * action; + unsigned long flags; for (i = 0 ; i < NR_IRQS ; i++) { + spin_lock_irqsave(&irq_controller_lock, flags); action = irq_desc[i].action; if (!action) - continue; + goto unlock; + seq_printf(p, "%3d: %10u ", i, kstat_irqs(i)); seq_printf(p, " %s", action->name); - for (action = action->next; action; action = action->next) { + for (action = action->next; action; action = action->next) seq_printf(p, ", %s", action->name); - } + seq_putc(p, '\n'); +unlock: + spin_unlock_irqrestore(&irq_controller_lock, flags); } #ifdef CONFIG_ARCH_ACORN diff -urN linux-2.5.64-bk3/arch/cris/Kconfig linux-2.5.64-bk4/arch/cris/Kconfig --- linux-2.5.64-bk3/arch/cris/Kconfig Tue Mar 4 19:29:36 2003 +++ linux-2.5.64-bk4/arch/cris/Kconfig Mon Mar 31 12:25:43 2003 @@ -9,10 +9,6 @@ bool default y -config SWAP - bool - default y - config UID16 bool default y diff -urN linux-2.5.64-bk3/arch/cris/kernel/irq.c linux-2.5.64-bk4/arch/cris/kernel/irq.c --- linux-2.5.64-bk3/arch/cris/kernel/irq.c Tue Mar 4 19:29:54 2003 +++ linux-2.5.64-bk4/arch/cris/kernel/irq.c Mon Mar 31 12:25:43 2003 @@ -228,11 +228,13 @@ { int i; struct irqaction * action; + unsigned long flags; for (i = 0; i < NR_IRQS; i++) { + local_irq_save(flags); action = irq_action[i]; if (!action) - continue; + goto skip; seq_printf(p, "%2d: %10u %c %s", i, kstat_cpu(0).irqs[i], (action->flags & SA_INTERRUPT) ? '+' : ' ', @@ -243,6 +245,8 @@ action->name); } seq_putc(p, '\n'); +skip: + local_irq_restore(flags); } return 0; } diff -urN linux-2.5.64-bk3/arch/i386/Kconfig linux-2.5.64-bk4/arch/i386/Kconfig --- linux-2.5.64-bk3/arch/i386/Kconfig Tue Mar 4 19:29:00 2003 +++ linux-2.5.64-bk4/arch/i386/Kconfig Mon Mar 31 12:25:44 2003 @@ -18,15 +18,6 @@ bool default y -config SWAP - bool "Support for paging of anonymous memory" - default y - help - This option allows you to choose whether you want to have support - for socalled swap devices or swap files in your kernel that are - used to provide more virtual memory than the actual RAM present - in your computer. If unusre say Y. - config SBUS bool @@ -488,7 +479,7 @@ # Common NUMA Features config NUMA bool "Numa Memory Allocation Support" - depends on (HIGHMEM64G && (X86_NUMAQ || (X86_SUMMIT && ACPI && !ACPI_HT_ONLY))) + depends on (HIGHMEM64G && (X86_NUMAQ || (X86_SUMMIT && ACPI && !ACPI_HT_ONLY))) || X86_PC config DISCONTIGMEM bool diff -urN linux-2.5.64-bk3/arch/i386/kernel/i386_ksyms.c linux-2.5.64-bk4/arch/i386/kernel/i386_ksyms.c --- linux-2.5.64-bk3/arch/i386/kernel/i386_ksyms.c Tue Mar 4 19:29:54 2003 +++ linux-2.5.64-bk4/arch/i386/kernel/i386_ksyms.c Mon Mar 31 12:25:44 2003 @@ -68,6 +68,7 @@ EXPORT_SYMBOL(MCA_bus); #ifdef CONFIG_DISCONTIGMEM EXPORT_SYMBOL(node_data); +EXPORT_SYMBOL(physnode_map); #endif #ifdef CONFIG_X86_NUMAQ EXPORT_SYMBOL(xquad_portio); diff -urN linux-2.5.64-bk3/arch/i386/kernel/io_apic.c linux-2.5.64-bk4/arch/i386/kernel/io_apic.c --- linux-2.5.64-bk3/arch/i386/kernel/io_apic.c Mon Mar 31 12:25:41 2003 +++ linux-2.5.64-bk4/arch/i386/kernel/io_apic.c Mon Mar 31 12:25:44 2003 @@ -1167,11 +1167,8 @@ enable_8259A_irq(0); } -void __init UNEXPECTED_IO_APIC(void) +static inline void UNEXPECTED_IO_APIC(void) { - printk(KERN_WARNING "INFO: unexpected IO-APIC, please file a report at\n"); - printk(KERN_WARNING " http://bugzilla.kernel.org\n"); - printk(KERN_WARNING " if your kernel is less than 3 months old.\n"); } void __init print_IO_APIC(void) diff -urN linux-2.5.64-bk3/arch/i386/kernel/irq.c linux-2.5.64-bk4/arch/i386/kernel/irq.c --- linux-2.5.64-bk3/arch/i386/kernel/irq.c Tue Mar 4 19:28:58 2003 +++ linux-2.5.64-bk4/arch/i386/kernel/irq.c Mon Mar 31 12:25:44 2003 @@ -135,43 +135,47 @@ { int i, j; struct irqaction * action; + unsigned long flags; seq_printf(p, " "); for (j=0; jtypename); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) seq_printf(p, ", %s", action->name); + seq_putc(p, '\n'); +skip: + spin_unlock_irqrestore(&irq_desc[i].lock, flags); } seq_printf(p, "NMI: "); for (j = 0; j < NR_CPUS; j++) if (cpu_online(j)) - p += seq_printf(p, "%10u ", nmi_count(j)); + seq_printf(p, "%10u ", nmi_count(j)); seq_putc(p, '\n'); #if CONFIG_X86_LOCAL_APIC seq_printf(p, "LOC: "); for (j = 0; j < NR_CPUS; j++) if (cpu_online(j)) - p += seq_printf(p, "%10u ", irq_stat[j].apic_timer_irqs); + seq_printf(p, "%10u ", irq_stat[j].apic_timer_irqs); seq_putc(p, '\n'); #endif seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count)); diff -urN linux-2.5.64-bk3/arch/i386/kernel/numaq.c linux-2.5.64-bk4/arch/i386/kernel/numaq.c --- linux-2.5.64-bk3/arch/i386/kernel/numaq.c Tue Mar 4 19:29:32 2003 +++ linux-2.5.64-bk4/arch/i386/kernel/numaq.c Mon Mar 31 12:25:44 2003 @@ -31,8 +31,7 @@ #include /* These are needed before the pgdat's are created */ -unsigned long node_start_pfn[MAX_NUMNODES]; -unsigned long node_end_pfn[MAX_NUMNODES]; +extern long node_start_pfn[], node_end_pfn[]; #define MB_TO_PAGES(addr) ((addr) << (20 - PAGE_SHIFT)) @@ -66,26 +65,6 @@ } /* - * ----------------------------------------- - * - * functions related to physnode_map - * - * ----------------------------------------- - */ -/* - * physnode_map keeps track of the physical memory layout of the - * numaq nodes on a 256Mb break (each element of the array will - * represent 256Mb of memory and will be marked by the node id. so, - * if the first gig is on node 0, and the second gig is on node 1 - * physnode_map will contain: - * physnode_map[0-3] = 0; - * physnode_map[4-7] = 1; - * physnode_map[8- ] = -1; - */ -int physnode_map[MAX_ELEMENTS] = { [0 ... (MAX_ELEMENTS - 1)] = -1}; -EXPORT_SYMBOL(physnode_map); - -/* * for each node mark the regions * TOPOFMEM = hi_shrd_mem_start + hi_shrd_mem_size * diff -urN linux-2.5.64-bk3/arch/i386/kernel/smpboot.c linux-2.5.64-bk4/arch/i386/kernel/smpboot.c --- linux-2.5.64-bk3/arch/i386/kernel/smpboot.c Tue Mar 4 19:29:18 2003 +++ linux-2.5.64-bk4/arch/i386/kernel/smpboot.c Mon Mar 31 12:25:44 2003 @@ -966,6 +966,7 @@ if (APIC_init_uniprocessor()) printk(KERN_NOTICE "Local APIC not detected." " Using dummy APIC emulation.\n"); + map_cpu_to_logical_apicid(); return; } diff -urN linux-2.5.64-bk3/arch/i386/kernel/srat.c linux-2.5.64-bk4/arch/i386/kernel/srat.c --- linux-2.5.64-bk3/arch/i386/kernel/srat.c Tue Mar 4 19:29:03 2003 +++ linux-2.5.64-bk4/arch/i386/kernel/srat.c Mon Mar 31 12:25:44 2003 @@ -57,8 +57,7 @@ static int zholes_size_init; static unsigned long zholes_size[MAX_NUMNODES * MAX_NR_ZONES]; -unsigned long node_start_pfn[MAX_NUMNODES]; -unsigned long node_end_pfn[MAX_NUMNODES]; +extern unsigned long node_start_pfn[], node_end_pfn[]; extern void * boot_ioremap(unsigned long, unsigned long); @@ -182,30 +181,19 @@ } } -/* - * physnode_map keeps track of the physical memory layout of the - * numaq nodes on a 256Mb break (each element of the array will - * represent 256Mb of memory and will be marked by the node id. so, - * if the first gig is on node 0, and the second gig is on node 1 - * physnode_map will contain: - * physnode_map[0-3] = 0; - * physnode_map[4-7] = 1; - * physnode_map[8- ] = -1; - */ -int pfnnode_map[MAX_ELEMENTS] = { [0 ... (MAX_ELEMENTS - 1)] = -1}; -EXPORT_SYMBOL(pfnnode_map); - -static void __init initialize_pfnnode_map(void) +static void __init initialize_physnode_map(void) { - unsigned long topofchunk, cur = 0; int i; - - for (i = 0; i < num_memory_chunks; i++) { - cur = node_memory_chunk[i].start_pfn; - topofchunk = node_memory_chunk[i].end_pfn; - while (cur < topofchunk) { - pfnnode_map[PFN_TO_ELEMENT(cur)] = node_memory_chunk[i].nid; - cur ++; + unsigned long pfn; + struct node_memory_chunk_s *nmcp; + + /* Run the list of memory chunks and fill in the phymap. */ + nmcp = node_memory_chunk; + for (i = num_memory_chunks; --i >= 0; nmcp++) { + for (pfn = nmcp->start_pfn; pfn <= nmcp->end_pfn; + pfn += PAGES_PER_ELEMENT) + { + physnode_map[pfn / PAGES_PER_ELEMENT] = (int)nmcp->nid; } } } @@ -272,7 +260,7 @@ for (i = 0; i < num_memory_chunks; i++) node_memory_chunk[i].nid = pxm_to_nid_map[node_memory_chunk[i].pxm]; - initialize_pfnnode_map(); + initialize_physnode_map(); printk("pxm bitmap: "); for (i = 0; i < sizeof(pxm_bitmap); i++) { diff -urN linux-2.5.64-bk3/arch/i386/mm/discontig.c linux-2.5.64-bk4/arch/i386/mm/discontig.c --- linux-2.5.64-bk3/arch/i386/mm/discontig.c Tue Mar 4 19:29:21 2003 +++ linux-2.5.64-bk4/arch/i386/mm/discontig.c Mon Mar 31 12:25:44 2003 @@ -36,11 +36,36 @@ struct pglist_data *node_data[MAX_NUMNODES]; bootmem_data_t node0_bdata; +/* + * numa interface - we expect the numa architecture specfic code to have + * populated the following initialisation. + * + * 1) numnodes - the total number of nodes configured in the system + * 2) physnode_map - the mapping between a pfn and owning node + * 3) node_start_pfn - the starting page frame number for a node + * 3) node_end_pfn - the ending page fram number for a node + */ + +/* + * physnode_map keeps track of the physical memory layout of a generic + * numa node on a 256Mb break (each element of the array will + * represent 256Mb of memory and will be marked by the node id. so, + * if the first gig is on node 0, and the second gig is on node 1 + * physnode_map will contain: + * + * physnode_map[0-3] = 0; + * physnode_map[4-7] = 1; + * physnode_map[8- ] = -1; + */ +u8 physnode_map[MAX_ELEMENTS] = { [0 ... (MAX_ELEMENTS - 1)] = -1}; + +unsigned long node_start_pfn[MAX_NUMNODES]; +unsigned long node_end_pfn[MAX_NUMNODES]; + extern unsigned long find_max_low_pfn(void); extern void find_max_pfn(void); extern void one_highpage_init(struct page *, int, int); -extern unsigned long node_start_pfn[], node_end_pfn[]; extern struct e820map e820; extern char _end; extern unsigned long highend_pfn, highstart_pfn; @@ -57,6 +82,36 @@ void set_pmd_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags); /* + * FLAT - support for basic PC memory model with discontig enabled, essentially + * a single node with all available processors in it with a flat + * memory map. + */ +void __init get_memcfg_numa_flat(void) +{ + int pfn; + + printk("NUMA - single node, flat memory mode\n"); + + /* Run the memory configuration and find the top of memory. */ + find_max_pfn(); + node_start_pfn[0] = 0; + node_end_pfn[0] = max_pfn; + + /* Fill in the physnode_map with our simplistic memory model, + * all memory is in node 0. + */ + for (pfn = node_start_pfn[0]; pfn <= node_end_pfn[0]; + pfn += PAGES_PER_ELEMENT) + { + physnode_map[pfn / PAGES_PER_ELEMENT] = 0; + } + + /* Indicate there is one node available. */ + node_set_online(0); + numnodes = 1; +} + +/* * Find the highest page frame number we have available for the node */ static void __init find_max_pfn_node(int nid) diff -urN linux-2.5.64-bk3/arch/ia64/Kconfig linux-2.5.64-bk4/arch/ia64/Kconfig --- linux-2.5.64-bk3/arch/ia64/Kconfig Mon Mar 31 12:25:41 2003 +++ linux-2.5.64-bk4/arch/ia64/Kconfig Mon Mar 31 12:25:44 2003 @@ -22,10 +22,6 @@ bool default y -config SWAP - bool - default y - config RWSEM_XCHGADD_ALGORITHM bool default y diff -urN linux-2.5.64-bk3/arch/ia64/kernel/irq.c linux-2.5.64-bk4/arch/ia64/kernel/irq.c --- linux-2.5.64-bk3/arch/ia64/kernel/irq.c Mon Mar 31 12:25:41 2003 +++ linux-2.5.64-bk4/arch/ia64/kernel/irq.c Mon Mar 31 12:25:44 2003 @@ -154,6 +154,7 @@ int i, j; struct irqaction * action; irq_desc_t *idesc; + unsigned long flags; seq_puts(p, " "); for (j=0; jlock, flags); action = idesc->action; if (!action) - continue; + goto skip; seq_printf(p, "%3d: ",i); #ifndef CONFIG_SMP seq_printf(p, "%10u ", kstat_irqs(i)); @@ -176,10 +178,12 @@ #endif seq_printf(p, " %14s", idesc->handler->typename); seq_printf(p, " %s", action->name); - for (action=action->next; action; action = action->next) seq_printf(p, ", %s", action->name); + seq_putc(p, '\n'); +skip: + spin_unlock_irqrestore(&idesc->lock, flags); } seq_puts(p, "NMI: "); for (j = 0; j < NR_CPUS; j++) diff -urN linux-2.5.64-bk3/arch/m68k/Kconfig linux-2.5.64-bk4/arch/m68k/Kconfig --- linux-2.5.64-bk3/arch/m68k/Kconfig Tue Mar 4 19:29:23 2003 +++ linux-2.5.64-bk4/arch/m68k/Kconfig Mon Mar 31 12:25:44 2003 @@ -10,10 +10,6 @@ bool default y -config SWAP - bool - default y - config UID16 bool default y diff -urN linux-2.5.64-bk3/arch/m68k/atari/stram.c linux-2.5.64-bk4/arch/m68k/atari/stram.c --- linux-2.5.64-bk3/arch/m68k/atari/stram.c Tue Mar 4 19:29:32 2003 +++ linux-2.5.64-bk4/arch/m68k/atari/stram.c Mon Mar 31 12:25:44 2003 @@ -1052,8 +1052,7 @@ if (!stram_disk) return -ENOMEM; - if (register_blkdev( STRAM_MAJOR, "stram", &stram_fops)) { - printk(KERN_ERR "stram: Unable to get major %d\n", STRAM_MAJOR); + if (register_blkdev(STRAM_MAJOR, "stram")) { put_disk(stram_disk); return -ENXIO; } diff -urN linux-2.5.64-bk3/arch/m68knommu/Kconfig linux-2.5.64-bk4/arch/m68knommu/Kconfig --- linux-2.5.64-bk3/arch/m68knommu/Kconfig Tue Mar 4 19:29:31 2003 +++ linux-2.5.64-bk4/arch/m68knommu/Kconfig Mon Mar 31 12:25:44 2003 @@ -9,10 +9,6 @@ bool default n -config SWAP - bool - default n - config FPU bool default n diff -urN linux-2.5.64-bk3/arch/mips/Kconfig linux-2.5.64-bk4/arch/mips/Kconfig --- linux-2.5.64-bk3/arch/mips/Kconfig Tue Mar 4 19:29:18 2003 +++ linux-2.5.64-bk4/arch/mips/Kconfig Mon Mar 31 12:25:44 2003 @@ -10,10 +10,6 @@ bool default y -config SWAP - bool - default y - config SMP bool ---help--- diff -urN linux-2.5.64-bk3/arch/mips/baget/irq.c linux-2.5.64-bk4/arch/mips/baget/irq.c --- linux-2.5.64-bk3/arch/mips/baget/irq.c Tue Mar 4 19:29:30 2003 +++ linux-2.5.64-bk4/arch/mips/baget/irq.c Mon Mar 31 12:25:44 2003 @@ -146,11 +146,13 @@ { int i; struct irqaction * action; + unsigned long flags; for (i = 0 ; i < BAGET_IRQ_NR ; i++) { + local_irq_save(flags); action = irq_action[i]; if (!action) - continue; + goto skip; seq_printf(p, "%2d: %8d %c %s", i, kstat_cpu(0).irqs[i], (action->flags & SA_INTERRUPT) ? '+' : ' ', @@ -161,6 +163,8 @@ action->name); } seq_putc(p, '\n'); +skip: + local_irq_restore(flags); } return 0; } diff -urN linux-2.5.64-bk3/arch/mips/dec/irq.c linux-2.5.64-bk4/arch/mips/dec/irq.c --- linux-2.5.64-bk3/arch/mips/dec/irq.c Tue Mar 4 19:29:22 2003 +++ linux-2.5.64-bk4/arch/mips/dec/irq.c Mon Mar 31 12:25:44 2003 @@ -97,11 +97,13 @@ { int i; struct irqaction *action; + unsigned long flags; for (i = 0; i < 32; i++) { + local_irq_save(flags); action = irq_action[i]; if (!action) - continue; + goto skip; seq_printf(p, "%2d: %8d %c %s", i, kstat_cpu(0).irqs[i], (action->flags & SA_INTERRUPT) ? '+' : ' ', @@ -112,6 +114,8 @@ action->name); } seq_putc(p, '\n'); +skip: + local_irq_restore(flags); } return 0; } diff -urN linux-2.5.64-bk3/arch/mips/ite-boards/generic/irq.c linux-2.5.64-bk4/arch/mips/ite-boards/generic/irq.c --- linux-2.5.64-bk3/arch/mips/ite-boards/generic/irq.c Tue Mar 4 19:29:21 2003 +++ linux-2.5.64-bk4/arch/mips/ite-boards/generic/irq.c Mon Mar 31 12:25:44 2003 @@ -222,6 +222,7 @@ { int i, j; struct irqaction * action; + unsigned long flags; seq_printf(p, " "); for (j=0; jhandler ) - continue; + goto skip; seq_printf(p, "%3d: ", i); seq_printf(p, "%10u ", kstat_irqs(i)); if ( irq_desc[i].handler ) seq_printf(p, " %s ", irq_desc[i].handler->typename ); else seq_puts(p, " None "); + seq_printf(p, " %s",action->name); for (action=action->next; action; action = action->next) { seq_printf(p, ", %s", action->name); } seq_putc(p, '\n'); +skip: + spin_unlock_irqrestore(&irq_desc[i].lock, flags); } seq_printf(p, "BAD: %10lu\n", spurious_count); return 0; @@ -437,6 +443,7 @@ irq_desc[i].action = 0; irq_desc[i].depth = 1; irq_desc[i].handler = &it8172_irq_type; + spin_lock_init(&irq_desc[i].lock); } /* diff -urN linux-2.5.64-bk3/arch/mips/kernel/irq.c linux-2.5.64-bk4/arch/mips/kernel/irq.c --- linux-2.5.64-bk3/arch/mips/kernel/irq.c Tue Mar 4 19:28:59 2003 +++ linux-2.5.64-bk4/arch/mips/kernel/irq.c Mon Mar 31 12:25:44 2003 @@ -73,17 +73,19 @@ int show_interrupts(struct seq_file *p, void *v) { struct irqaction * action; + unsigned long flags; int i; - + seq_puts(p, " "); for (i=0; i < 1 /*smp_num_cpus*/; i++) seq_printf(p, "CPU%d ", i); seq_putc(p, '\n'); for (i = 0 ; i < NR_IRQS ; i++) { + spin_lock_irqsave(&irq_desc[i].lock, flags); action = irq_desc[i].action; if (!action) - continue; + goto unlock; seq_printf(p, "%3d: ",i); seq_printf(p, "%10u ", kstat_irqs(i)); seq_printf(p, " %14s", irq_desc[i].handler->typename); @@ -92,6 +94,8 @@ for (action=action->next; action; action = action->next) seq_printf(p, ", %s", action->name); seq_putc(p, '\n'); +unlock: + spin_unlock_irqrestore(&irq_desc[i].lock, flags); } seq_printf(p, "ERR: %10lu\n", irq_err_count); return 0; diff -urN linux-2.5.64-bk3/arch/mips/kernel/old-irq.c linux-2.5.64-bk4/arch/mips/kernel/old-irq.c --- linux-2.5.64-bk3/arch/mips/kernel/old-irq.c Tue Mar 4 19:29:20 2003 +++ linux-2.5.64-bk4/arch/mips/kernel/old-irq.c Mon Mar 31 12:25:44 2003 @@ -128,11 +128,13 @@ { int i; struct irqaction * action; + unsigned long flags; for (i = 0 ; i < 32 ; i++) { + local_irq_save(flags); action = irq_action[i]; if (!action) - continue; + goto skip; seq_printf(p, "%2d: %8d %c %s", i, kstat_cpu(0).irqs[i], (action->flags & SA_INTERRUPT) ? '+' : ' ', @@ -143,6 +145,8 @@ action->name); } seq_putc(p, '\n'); +skip: + local_irq_restore(flags); } return 0; } diff -urN linux-2.5.64-bk3/arch/mips/mips-boards/atlas/atlas_int.c linux-2.5.64-bk4/arch/mips/mips-boards/atlas/atlas_int.c --- linux-2.5.64-bk3/arch/mips/mips-boards/atlas/atlas_int.c Tue Mar 4 19:29:31 2003 +++ linux-2.5.64-bk4/arch/mips/mips-boards/atlas/atlas_int.c Mon Mar 31 12:25:44 2003 @@ -99,11 +99,13 @@ int i; int num = 0; struct irqaction *action; + unsigned long flags; for (i = 0; i < ATLASINT_END; i++, num++) { + spin_lock_irqsave(&irq_desc[i].lock, flags); action = irq_desc[i].action; if (!action) - continue; + goto skip; seq_printf(p, "%2d: %8d %c %s", num, kstat_cpu(0).irqs[num], (action->flags & SA_INTERRUPT) ? '+' : ' ', @@ -114,6 +116,8 @@ action->name); } seq_printf(p, " [hw0]\n"); +skip: + spin_unlock_irqrestore(&irq_desc[i].lock, flags); } return 0; } @@ -243,6 +247,7 @@ irq_desc[i].action = 0; irq_desc[i].depth = 1; irq_desc[i].handler = &atlas_irq_type; + spin_lock_init(&irq_desc[i].lock); } #ifdef CONFIG_REMOTE_DEBUG diff -urN linux-2.5.64-bk3/arch/mips/philips/nino/irq.c linux-2.5.64-bk4/arch/mips/philips/nino/irq.c --- linux-2.5.64-bk3/arch/mips/philips/nino/irq.c Tue Mar 4 19:28:58 2003 +++ linux-2.5.64-bk4/arch/mips/philips/nino/irq.c Mon Mar 31 12:25:44 2003 @@ -119,11 +119,13 @@ { int i; struct irqaction *action; + unsigned long flags; for (i = 0; i < NR_IRQS; i++) { + local_irq_save(flags); action = irq_action[i]; if (!action) - continue; + goto skip; seq_printf(p, "%2d: %8d %c %s", i, kstat_cpu(0).irqs[i], (action->flags & SA_INTERRUPT) ? '+' : ' ', @@ -134,6 +136,8 @@ action->name); } seq_putc(p, '\n'); +skip: + local_irq_restore(flags); } return 0; } diff -urN linux-2.5.64-bk3/arch/mips64/Kconfig linux-2.5.64-bk4/arch/mips64/Kconfig --- linux-2.5.64-bk3/arch/mips64/Kconfig Tue Mar 4 19:29:04 2003 +++ linux-2.5.64-bk4/arch/mips64/Kconfig Mon Mar 31 12:25:44 2003 @@ -9,10 +9,6 @@ bool default y -config SWAP - bool - default y - source "init/Kconfig" diff -urN linux-2.5.64-bk3/arch/mips64/mips-boards/atlas/atlas_int.c linux-2.5.64-bk4/arch/mips64/mips-boards/atlas/atlas_int.c --- linux-2.5.64-bk3/arch/mips64/mips-boards/atlas/atlas_int.c Tue Mar 4 19:29:54 2003 +++ linux-2.5.64-bk4/arch/mips64/mips-boards/atlas/atlas_int.c Mon Mar 31 12:25:44 2003 @@ -95,11 +95,13 @@ int i; int num = 0; struct irqaction *action; + unsigned long flags; for (i = 0; i < ATLASINT_END; i++, num++) { + spin_lock_irqsave(&irq_desc[i].lock, flags); action = irq_desc[i].action; if (!action) - continue; + goto unlock; seq_printf(p, "%2d: %8d %c %s", num, kstat_cpu(0).irqs[num], (action->flags & SA_INTERRUPT) ? '+' : ' ', @@ -110,6 +112,8 @@ action->name); } seq_puts(p, " [hw0]\n"); +unlock: + spin_unlock_irqrestore(&irq_desc[i].lock, flags); } return 0; } @@ -239,6 +243,7 @@ irq_desc[i].action = 0; irq_desc[i].depth = 1; irq_desc[i].handler = &atlas_irq_type; + spin_lock_init(&irq_desc[i].lock); } #ifdef CONFIG_REMOTE_DEBUG diff -urN linux-2.5.64-bk3/arch/mips64/mips-boards/malta/malta_int.c linux-2.5.64-bk4/arch/mips64/mips-boards/malta/malta_int.c --- linux-2.5.64-bk3/arch/mips64/mips-boards/malta/malta_int.c Tue Mar 4 19:29:31 2003 +++ linux-2.5.64-bk4/arch/mips64/mips-boards/malta/malta_int.c Mon Mar 31 12:25:44 2003 @@ -125,11 +125,13 @@ int i; int num = 0; struct irqaction *action; + unsigned long flags; for (i = 0; i < 8; i++, num++) { + local_irq_save(flags); action = irq_action[i]; if (!action) - continue; + goto skip_1; seq_printf(p, "%2d: %8d %c %s", num, kstat_cpu(0).irqs[num], (action->flags & SA_INTERRUPT) ? '+' : ' ', @@ -140,11 +142,14 @@ action->name); } seq_puts(p, " [on-chip]\n"); +skip_1: + local_irq_restore(flags); } for (i = 0; i < MALTAINT_END; i++, num++) { + local_irq_save(flags); action = hw0_irq_action[i]; if (!action) - continue; + goto skip_2; seq_printf(p, "%2d: %8d %c %s", num, kstat_cpu(0).irqs[num], (action->flags & SA_INTERRUPT) ? '+' : ' ', @@ -155,6 +160,8 @@ action->name); } seq_puts(p, " [hw0]\n"); +skip_2: + local_irq_restore(flags); } return 0; } diff -urN linux-2.5.64-bk3/arch/mips64/sgi-ip22/ip22-int.c linux-2.5.64-bk4/arch/mips64/sgi-ip22/ip22-int.c --- linux-2.5.64-bk3/arch/mips64/sgi-ip22/ip22-int.c Tue Mar 4 19:28:58 2003 +++ linux-2.5.64-bk4/arch/mips64/sgi-ip22/ip22-int.c Mon Mar 31 12:25:44 2003 @@ -237,11 +237,13 @@ int i; int num = 0; struct irqaction * action; + unsigned long flags; for (i = 0 ; i < 16 ; i++, num++) { + local_irq_save(flags); action = irq_action[i]; if (!action) - continue; + goto skip_1; seq_printf(p, "%2d: %8d %c %s", num, kstat_cpu(0).irqs[num], (action->flags & SA_INTERRUPT) ? '+' : ' ', @@ -252,11 +254,14 @@ action->name); } seq_puts(p, " [on-chip]\n"); +skip_1: + local_irq_restore(flags); } for (i = 0 ; i < 24 ; i++, num++) { + local_irq_save(flags); action = local_irq_action[i]; if (!action) - continue; + goto skip_2; seq_printf(p, "%2d: %8d %c %s", num, kstat_cpu(0).irqs[num], (action->flags & SA_INTERRUPT) ? '+' : ' ', @@ -267,6 +272,8 @@ action->name); } seq_puts(p, " [local]\n"); +skip_2: + local_irq_restore(flags); } return 0; } diff -urN linux-2.5.64-bk3/arch/mips64/sgi-ip27/ip27-irq.c linux-2.5.64-bk4/arch/mips64/sgi-ip27/ip27-irq.c --- linux-2.5.64-bk3/arch/mips64/sgi-ip27/ip27-irq.c Tue Mar 4 19:29:19 2003 +++ linux-2.5.64-bk4/arch/mips64/sgi-ip27/ip27-irq.c Mon Mar 31 12:25:44 2003 @@ -141,11 +141,13 @@ { int i; struct irqaction * action; + unsigned long flags; for (i = 0 ; i < NR_IRQS ; i++) { + local_irq_save(flags); action = irq_action[i]; if (!action) - continue; + goto skip; seq_printf(p, "%2d: %8d %c %s", i, kstat_cpu(0).irqs[i], (action->flags & SA_INTERRUPT) ? '+' : ' ', action->name); @@ -156,6 +158,8 @@ action->name); } seq_putc(p, '\n'); +skip: + local_irq_restore(flags); } return 0; } diff -urN linux-2.5.64-bk3/arch/parisc/Kconfig linux-2.5.64-bk4/arch/parisc/Kconfig --- linux-2.5.64-bk3/arch/parisc/Kconfig Tue Mar 4 19:29:23 2003 +++ linux-2.5.64-bk4/arch/parisc/Kconfig Mon Mar 31 12:25:44 2003 @@ -18,10 +18,6 @@ bool default y -config SWAP - bool - default y - config STACK_GROWSUP bool default y diff -urN linux-2.5.64-bk3/arch/ppc/Kconfig linux-2.5.64-bk4/arch/ppc/Kconfig --- linux-2.5.64-bk3/arch/ppc/Kconfig Tue Mar 4 19:29:54 2003 +++ linux-2.5.64-bk4/arch/ppc/Kconfig Mon Mar 31 12:25:44 2003 @@ -1126,22 +1126,6 @@ config PIN_TLB bool "Pinned Kernel TLBs (860 ONLY)" depends on ADVANCED_OPTIONS && 8xx - -config SWAP - bool "Enable support for swap" - depends on ADVANCED_OPTIONS - help - This option allows you to turn off support for swapfiles in - the kernel. This can be useful if you know that your system - will never have swap. - - Say Y here unless you know what you are doing. - -config SWAP - bool - depends on !ADVANCED_OPTIONS - default y - endmenu source "drivers/mtd/Kconfig" diff -urN linux-2.5.64-bk3/arch/ppc/kernel/irq.c linux-2.5.64-bk4/arch/ppc/kernel/irq.c --- linux-2.5.64-bk3/arch/ppc/kernel/irq.c Tue Mar 4 19:29:33 2003 +++ linux-2.5.64-bk4/arch/ppc/kernel/irq.c Mon Mar 31 12:25:44 2003 @@ -346,6 +346,7 @@ { int i, j; struct irqaction * action; + unsigned long flags; seq_puts(p, " "); for (j=0; jhandler ) - continue; + goto skip; seq_printf(p, "%3d: ", i); #ifdef CONFIG_SMP for (j = 0; j < NR_CPUS; j++) @@ -373,8 +375,10 @@ seq_printf(p, "%s", (irq_desc[i].status & IRQ_LEVEL) ? "Level " : "Edge "); seq_printf(p, " %s", action->name); for (action = action->next; action; action = action->next) - seq_printf(p, ", %s", action->name); + seq_printf(p, ", %s", action->name); seq_putc(p, '\n'); +skip: + spin_unlock_irqrestore(&irq_desc[i].lock, flags); } #ifdef CONFIG_TAU_INT if (tau_initialized){ diff -urN linux-2.5.64-bk3/arch/ppc64/Kconfig linux-2.5.64-bk4/arch/ppc64/Kconfig --- linux-2.5.64-bk3/arch/ppc64/Kconfig Tue Mar 4 19:29:21 2003 +++ linux-2.5.64-bk4/arch/ppc64/Kconfig Mon Mar 31 12:25:44 2003 @@ -7,10 +7,6 @@ bool default y -config SWAP - bool - default y - config UID16 bool diff -urN linux-2.5.64-bk3/arch/ppc64/kernel/irq.c linux-2.5.64-bk4/arch/ppc64/kernel/irq.c --- linux-2.5.64-bk3/arch/ppc64/kernel/irq.c Tue Mar 4 19:29:17 2003 +++ linux-2.5.64-bk4/arch/ppc64/kernel/irq.c Mon Mar 31 12:25:44 2003 @@ -341,6 +341,7 @@ { int i, j; struct irqaction * action; + unsigned long flags; seq_printf(p, " "); for (j=0; jhandler) - continue; + goto skip; seq_printf(p, "%3d: ", i); #ifdef CONFIG_SMP for (j = 0; j < NR_CPUS; j++) { @@ -371,6 +373,8 @@ for (action=action->next; action; action = action->next) seq_printf(p, ", %s", action->name); seq_putc(p, '\n'); +skip: + spin_unlock_irqrestore(&irq_desc[i].lock, flags); } seq_printf(p, "BAD: %10u\n", ppc_spurious_interrupts); return 0; diff -urN linux-2.5.64-bk3/arch/s390/Kconfig linux-2.5.64-bk4/arch/s390/Kconfig --- linux-2.5.64-bk3/arch/s390/Kconfig Tue Mar 4 19:29:16 2003 +++ linux-2.5.64-bk4/arch/s390/Kconfig Mon Mar 31 12:25:44 2003 @@ -7,10 +7,6 @@ bool default y -config SWAP - bool - default y - config UID16 bool default y diff -urN linux-2.5.64-bk3/arch/s390x/Kconfig linux-2.5.64-bk4/arch/s390x/Kconfig --- linux-2.5.64-bk3/arch/s390x/Kconfig Tue Mar 4 19:29:19 2003 +++ linux-2.5.64-bk4/arch/s390x/Kconfig Mon Mar 31 12:25:44 2003 @@ -7,10 +7,6 @@ bool default y -config SWAP - bool - default y - config RWSEM_GENERIC_SPINLOCK bool diff -urN linux-2.5.64-bk3/arch/sh/Kconfig linux-2.5.64-bk4/arch/sh/Kconfig --- linux-2.5.64-bk3/arch/sh/Kconfig Tue Mar 4 19:29:54 2003 +++ linux-2.5.64-bk4/arch/sh/Kconfig Mon Mar 31 12:25:44 2003 @@ -18,10 +18,6 @@ bool default y -config SWAP - bool - default y - config UID16 bool default y diff -urN linux-2.5.64-bk3/arch/sh/kernel/irq.c linux-2.5.64-bk4/arch/sh/kernel/irq.c --- linux-2.5.64-bk3/arch/sh/kernel/irq.c Tue Mar 4 19:29:16 2003 +++ linux-2.5.64-bk4/arch/sh/kernel/irq.c Mon Mar 31 12:25:44 2003 @@ -90,6 +90,7 @@ { int i, j; struct irqaction * action; + unsigned long flags; seq_puts(p, " "); for (j=0; jtypename); @@ -108,6 +110,8 @@ for (action=action->next; action; action = action->next) seq_printf(p, ", %s", action->name); seq_putc(p, '\n'); +unlock: + spin_unlock_irqrestore(&irq_desc[i].lock, flags); } return 0; } diff -urN linux-2.5.64-bk3/arch/sparc/Kconfig linux-2.5.64-bk4/arch/sparc/Kconfig --- linux-2.5.64-bk3/arch/sparc/Kconfig Tue Mar 4 19:28:52 2003 +++ linux-2.5.64-bk4/arch/sparc/Kconfig Mon Mar 31 12:25:44 2003 @@ -9,10 +9,6 @@ bool default y -config SWAP - bool - default y - config UID16 bool default y diff -urN linux-2.5.64-bk3/arch/sparc/kernel/irq.c linux-2.5.64-bk4/arch/sparc/kernel/irq.c --- linux-2.5.64-bk3/arch/sparc/kernel/irq.c Tue Mar 4 19:28:56 2003 +++ linux-2.5.64-bk4/arch/sparc/kernel/irq.c Mon Mar 31 12:25:44 2003 @@ -104,6 +104,7 @@ { int i; struct irqaction * action; + unsigned long flags; #ifdef CONFIG_SMP int j; #endif @@ -114,9 +115,10 @@ return show_sun4d_interrupts(p, v); } for (i = 0 ; i < NR_IRQS ; i++) { + local_irq_save(flags); action = *(i + irq_action); if (!action) - continue; + goto skip; seq_printf(p, "%3d: ", i); #ifndef CONFIG_SMP seq_printf(p, "%10u ", kstat_irqs(i)); @@ -136,6 +138,8 @@ action->name); } seq_putc(p, '\n'); +skip: + local_irq_restore(flags); } return 0; } diff -urN linux-2.5.64-bk3/arch/sparc64/Kconfig linux-2.5.64-bk4/arch/sparc64/Kconfig --- linux-2.5.64-bk3/arch/sparc64/Kconfig Mon Mar 31 12:25:41 2003 +++ linux-2.5.64-bk4/arch/sparc64/Kconfig Mon Mar 31 12:25:44 2003 @@ -9,10 +9,6 @@ bool default y -config SWAP - bool - default y - source "init/Kconfig" diff -urN linux-2.5.64-bk3/arch/sparc64/defconfig linux-2.5.64-bk4/arch/sparc64/defconfig --- linux-2.5.64-bk3/arch/sparc64/defconfig Tue Mar 4 19:29:15 2003 +++ linux-2.5.64-bk4/arch/sparc64/defconfig Mon Mar 31 12:25:44 2003 @@ -39,9 +39,11 @@ # CONFIG_PREEMPT is not set CONFIG_NR_CPUS=4 CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_PROC_INTF=y CONFIG_CPU_FREQ_TABLE=y CONFIG_US3_FREQ=m +CONFIG_CPU_FREQ_PROC_INTF=y +CONFIG_CPU_FREQ_GOV_USERSPACE=m +# CONFIG_CPU_FREQ_24_API is not set CONFIG_SPARC64=y CONFIG_HOTPLUG=y CONFIG_HAVE_DEC_LOCK=y @@ -354,6 +356,8 @@ CONFIG_XFRM_USER=m CONFIG_IPV6=m CONFIG_IPV6_PRIVACY=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m # # SCTP Configuration (EXPERIMENTAL) @@ -872,6 +876,7 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_AIPTEK is not set CONFIG_USB_WACOM=m +CONFIG_USB_KBTAB=m # CONFIG_USB_POWERMATE is not set # CONFIG_USB_XPAD is not set @@ -928,6 +933,7 @@ # CONFIG_USB_SERIAL_EDGEPORT_TI is not set CONFIG_USB_SERIAL_KEYSPAN_PDA=m CONFIG_USB_SERIAL_KEYSPAN=m +# CONFIG_USB_SERIAL_KEYSPAN_MPR is not set # CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set # CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set # CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set @@ -938,6 +944,7 @@ # CONFIG_USB_SERIAL_KEYSPAN_USA19QW is not set # CONFIG_USB_SERIAL_KEYSPAN_USA19QI is not set # CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA49WLC is not set CONFIG_USB_SERIAL_KLSI=m # CONFIG_USB_SERIAL_KOBIL_SCT is not set CONFIG_USB_SERIAL_MCT_U232=m diff -urN linux-2.5.64-bk3/arch/sparc64/kernel/ioctl32.c linux-2.5.64-bk4/arch/sparc64/kernel/ioctl32.c --- linux-2.5.64-bk3/arch/sparc64/kernel/ioctl32.c Tue Mar 4 19:29:35 2003 +++ linux-2.5.64-bk4/arch/sparc64/kernel/ioctl32.c Mon Mar 31 12:25:44 2003 @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -4850,6 +4851,7 @@ COMPATIBLE_IOCTL(AUTOFS_IOC_CATATONIC) COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOVER) COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE) +COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE_MULTI) /* DEVFS */ COMPATIBLE_IOCTL(DEVFSDIOC_GET_PROTO_REV) COMPATIBLE_IOCTL(DEVFSDIOC_SET_EVENT_MASK) diff -urN linux-2.5.64-bk3/arch/sparc64/kernel/pci_common.c linux-2.5.64-bk4/arch/sparc64/kernel/pci_common.c --- linux-2.5.64-bk3/arch/sparc64/kernel/pci_common.c Tue Mar 4 19:29:03 2003 +++ linux-2.5.64-bk4/arch/sparc64/kernel/pci_common.c Mon Mar 31 12:25:44 2003 @@ -78,20 +78,6 @@ return 0; } -/* Remove a PCI device from the device trees, then - * free it up. Note that this must run before - * the device's resources are registered because we - * do not handle unregistering them here. - */ -static void pci_device_delete(struct pci_dev *pdev) -{ - list_del(&pdev->global_list); - list_del(&pdev->bus_list); - - /* Ok, all references are gone, free it up. */ - kfree(pdev); -} - /* Older versions of OBP on PCI systems encode 64-bit MEM * space assignments incorrectly, this fixes them up. We also * take the opportunity here to hide other kinds of bogus @@ -164,7 +150,7 @@ * second EBUS/HappyMeal pair if the external * connector for it is not present. */ - pci_device_delete(pdev); + pci_remove_bus_device(pdev); return; } diff -urN linux-2.5.64-bk3/arch/sparc64/kernel/smp.c linux-2.5.64-bk4/arch/sparc64/kernel/smp.c --- linux-2.5.64-bk3/arch/sparc64/kernel/smp.c Tue Mar 4 19:28:53 2003 +++ linux-2.5.64-bk4/arch/sparc64/kernel/smp.c Mon Mar 31 12:25:44 2003 @@ -1137,17 +1137,17 @@ do { sparc64_do_profile(regs); if (!--prof_counter(cpu)) { - if (cpu == boot_cpu_id) { - irq_enter(); + irq_enter(); + if (cpu == boot_cpu_id) { kstat_cpu(cpu).irqs[0]++; timer_tick_interrupt(regs); - - irq_exit(); } update_process_times(user); + irq_exit(); + prof_counter(cpu) = prof_multiplier(cpu); } diff -urN linux-2.5.64-bk3/arch/um/Kconfig linux-2.5.64-bk4/arch/um/Kconfig --- linux-2.5.64-bk3/arch/um/Kconfig Tue Mar 4 19:29:18 2003 +++ linux-2.5.64-bk4/arch/um/Kconfig Mon Mar 31 12:25:44 2003 @@ -7,10 +7,6 @@ bool default y -config SWAP - bool - default y - mainmenu "Linux/Usermode Kernel Configuration" config ISA diff -urN linux-2.5.64-bk3/arch/um/drivers/ubd_kern.c linux-2.5.64-bk4/arch/um/drivers/ubd_kern.c --- linux-2.5.64-bk3/arch/um/drivers/ubd_kern.c Tue Mar 4 19:29:18 2003 +++ linux-2.5.64-bk4/arch/um/drivers/ubd_kern.c Mon Mar 31 12:25:44 2003 @@ -673,7 +673,7 @@ static int ubd_mc_init(void) { mconsole_register_dev(&ubd_mc); - return(0); + return 0; } __initcall(ubd_mc_init); @@ -682,29 +682,24 @@ { int i; - ubd_dir_handle = devfs_mk_dir (NULL, "ubd", NULL); - if(register_blkdev(MAJOR_NR, "ubd", &ubd_blops)){ - printk(KERN_ERR "ubd: unable to get major %d\n", MAJOR_NR); + ubd_dir_handle = devfs_mk_dir(NULL, "ubd", NULL); + if (register_blkdev(MAJOR_NR, "ubd")) return -1; - } blk_init_queue(&ubd_queue, do_ubd_request, &ubd_io_lock); elevator_init(&ubd_queue, &elevator_noop); - if(fake_major != 0){ + if (fake_major != 0) { char name[sizeof("ubd_nnn\0")]; snprintf(name, sizeof(name), "ubd_%d", fake_major); ubd_fake_dir_handle = devfs_mk_dir(NULL, name, NULL); - if(register_blkdev(fake_major, "ubd", &ubd_blops)){ - printk(KERN_ERR "ubd: unable to get major %d\n", - fake_major); + if (register_blkdev(fake_major, "ubd")) return -1; - } } - for(i = 0; i < MAX_DEV; i++) + for (i = 0; i < MAX_DEV; i++) ubd_add(i); - return(0); + return 0; } late_initcall(ubd_init); diff -urN linux-2.5.64-bk3/arch/v850/Kconfig linux-2.5.64-bk4/arch/v850/Kconfig --- linux-2.5.64-bk3/arch/v850/Kconfig Tue Mar 4 19:29:18 2003 +++ linux-2.5.64-bk4/arch/v850/Kconfig Mon Mar 31 12:25:44 2003 @@ -10,9 +10,6 @@ config MMU bool default n -config SWAP - bool - default n config UID16 bool default n diff -urN linux-2.5.64-bk3/arch/v850/kernel/irq.c linux-2.5.64-bk4/arch/v850/kernel/irq.c --- linux-2.5.64-bk3/arch/v850/kernel/irq.c Tue Mar 4 19:29:32 2003 +++ linux-2.5.64-bk4/arch/v850/kernel/irq.c Mon Mar 31 12:25:44 2003 @@ -78,6 +78,7 @@ { int i; struct irqaction * action; + unsigned long flags; seq_puts(p, " "); for (i=0; i < 1 /*smp_num_cpus*/; i++) @@ -87,10 +88,10 @@ for (i = 0 ; i < NR_IRQS ; i++) { int j, count, num; const char *type_name = irq_desc[i].handler->typename; - + spin_lock_irqsave(&irq_desc[j].lock, flags); action = irq_desc[i].action; if (!action) - continue; + goto skip; count = 0; num = -1; @@ -108,11 +109,13 @@ seq_printf(p, " %*s%d", 14 - prec, type_name, num); } else seq_printf(p, " %14s", type_name); + seq_printf(p, " %s", action->name); - for (action=action->next; action; action = action->next) seq_printf(p, ", %s", action->name); seq_putc(p, '\n'); +skip: + spin_unlock_irqrestore(&irq_desc[j].lock, flags); } seq_printf(p, "ERR: %10lu\n", irq_err_count); return 0; diff -urN linux-2.5.64-bk3/arch/x86_64/Kconfig linux-2.5.64-bk4/arch/x86_64/Kconfig --- linux-2.5.64-bk3/arch/x86_64/Kconfig Tue Mar 4 19:29:33 2003 +++ linux-2.5.64-bk4/arch/x86_64/Kconfig Mon Mar 31 12:25:44 2003 @@ -24,10 +24,6 @@ bool default y -config SWAP - bool - default y - config ISA bool diff -urN linux-2.5.64-bk3/arch/x86_64/kernel/irq.c linux-2.5.64-bk4/arch/x86_64/kernel/irq.c --- linux-2.5.64-bk3/arch/x86_64/kernel/irq.c Tue Mar 4 19:29:17 2003 +++ linux-2.5.64-bk4/arch/x86_64/kernel/irq.c Mon Mar 31 12:25:44 2003 @@ -135,6 +135,7 @@ { int i, j; struct irqaction * action; + unsigned long flags; seq_printf(p, " "); for (j=0; jtypename); - seq_printf(p, " %s", action->name); + seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) seq_printf(p, ", %s", action->name); seq_putc(p, '\n'); +skip: + spin_unlock_irqrestore(&irq_desc[i].lock, flags); } seq_printf(p, "NMI: "); for (j = 0; j < NR_CPUS; j++) diff -urN linux-2.5.64-bk3/drivers/acorn/block/fd1772.c linux-2.5.64-bk4/drivers/acorn/block/fd1772.c --- linux-2.5.64-bk3/drivers/acorn/block/fd1772.c Tue Mar 4 19:29:15 2003 +++ linux-2.5.64-bk4/drivers/acorn/block/fd1772.c Mon Mar 31 12:25:44 2003 @@ -1539,11 +1539,9 @@ goto err_disk; } - err = register_blkdev(MAJOR_NR, "fd", &floppy_fops); - if (err) { - printk("Unable to get major %d for floppy\n", MAJOR_NR); + err = register_blkdev(MAJOR_NR, "fd"); + if (err) goto err_disk; - } err = -EBUSY; if (request_dma(FLOPPY_DMA, "fd1772")) { diff -urN linux-2.5.64-bk3/drivers/acorn/block/mfmhd.c linux-2.5.64-bk4/drivers/acorn/block/mfmhd.c --- linux-2.5.64-bk3/drivers/acorn/block/mfmhd.c Tue Mar 4 19:29:03 2003 +++ linux-2.5.64-bk4/drivers/acorn/block/mfmhd.c Mon Mar 31 12:25:44 2003 @@ -1267,11 +1267,9 @@ if (!request_region (mfm_addr, 10, "mfm")) goto out1; - ret = register_blkdev(MAJOR_NR, "mfm", &mfm_fops); - if (ret) { - printk("mfm_init: unable to get major number %d\n", MAJOR_NR); + ret = register_blkdev(MAJOR_NR, "mfm"); + if (ret) goto out2; - } /* Stuff for the assembler routines to get to */ hdc63463_baseaddress = ioaddr(mfm_addr); diff -urN linux-2.5.64-bk3/drivers/block/DAC960.c linux-2.5.64-bk4/drivers/block/DAC960.c --- linux-2.5.64-bk3/drivers/block/DAC960.c Tue Mar 4 19:29:32 2003 +++ linux-2.5.64-bk4/drivers/block/DAC960.c Mon Mar 31 12:25:45 2003 @@ -13,9 +13,6 @@ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for complete details. - The author respectfully requests that any modifications to this software be - sent directly to him for evaluation and testing. - */ @@ -2381,13 +2378,9 @@ /* Register the Block Device Major Number for this DAC960 Controller. */ - if (register_blkdev(MajorNumber, "dac960", - &DAC960_BlockDeviceOperations) < 0) - { - DAC960_Error("UNABLE TO ACQUIRE MAJOR NUMBER %d - DETACHING\n", - Controller, MajorNumber); + if (register_blkdev(MajorNumber, "dac960") < 0) return false; - } + /* Initialize the I/O Request Queue. */ diff -urN linux-2.5.64-bk3/drivers/block/acsi.c linux-2.5.64-bk4/drivers/block/acsi.c --- linux-2.5.64-bk3/drivers/block/acsi.c Tue Mar 4 19:29:54 2003 +++ linux-2.5.64-bk4/drivers/block/acsi.c Mon Mar 31 12:25:45 2003 @@ -1613,7 +1613,6 @@ int acsi_init( void ) - { int err = 0; int i, target, lun; @@ -1623,8 +1622,7 @@ #endif if (!MACH_IS_ATARI || !ATARIHW_PRESENT(ACSI)) return 0; - if (register_blkdev( ACSI_MAJOR, "ad", &acsi_fops )) { - printk( KERN_ERR "Unable to get major %d for ACSI\n", ACSI_MAJOR ); + if (register_blkdev(ACSI_MAJOR, "ad")) { err = -EBUSY; goto out1; } diff -urN linux-2.5.64-bk3/drivers/block/amiflop.c linux-2.5.64-bk4/drivers/block/amiflop.c --- linux-2.5.64-bk3/drivers/block/amiflop.c Tue Mar 4 19:29:18 2003 +++ linux-2.5.64-bk4/drivers/block/amiflop.c Mon Mar 31 12:25:45 2003 @@ -1754,10 +1754,9 @@ if (!AMIGAHW_PRESENT(AMI_FLOPPY)) return -ENXIO; - if (register_blkdev(FLOPPY_MAJOR,"fd",&floppy_fops)) { - printk("fd: Unable to get major %d for floppy\n",FLOPPY_MAJOR); + if (register_blkdev(FLOPPY_MAJOR,"fd")) return -EBUSY; - } + /* * We request DSKPTR, DSKLEN and DSKDATA only, because the other * floppy registers are too spreaded over the custom register space diff -urN linux-2.5.64-bk3/drivers/block/ataflop.c linux-2.5.64-bk4/drivers/block/ataflop.c --- linux-2.5.64-bk3/drivers/block/ataflop.c Tue Mar 4 19:29:00 2003 +++ linux-2.5.64-bk4/drivers/block/ataflop.c Mon Mar 31 12:25:45 2003 @@ -1929,10 +1929,8 @@ /* Hades doesn't have Atari-compatible floppy */ return -ENXIO; - if (register_blkdev(FLOPPY_MAJOR,"fd",&floppy_fops)) { - printk(KERN_ERR "Unable to get major %d for floppy\n",FLOPPY_MAJOR); + if (register_blkdev(FLOPPY_MAJOR,"fd")) return -EBUSY; - } for (i = 0; i < FD_MAX_UNITS; i++) { unit[i].disk = alloc_disk(1); diff -urN linux-2.5.64-bk3/drivers/block/cciss.c linux-2.5.64-bk4/drivers/block/cciss.c --- linux-2.5.64-bk3/drivers/block/cciss.c Mon Mar 31 12:25:41 2003 +++ linux-2.5.64-bk4/drivers/block/cciss.c Mon Mar 31 12:25:45 2003 @@ -2451,14 +2451,12 @@ return -ENODEV; } - if( register_blkdev(COMPAQ_CISS_MAJOR+i, hba[i]->devname, &cciss_fops)) - { - printk(KERN_ERR "cciss: Unable to get major number " - "%d for %s\n", COMPAQ_CISS_MAJOR+i, hba[i]->devname); + if (register_blkdev(COMPAQ_CISS_MAJOR+i, hba[i]->devname)) { release_io_mem(hba[i]); free_hba(i); - return(-1); + return -1; } + /* make sure the board interrupts are off */ hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_OFF); if( request_irq(hba[i]->intr, do_cciss_intr, diff -urN linux-2.5.64-bk3/drivers/block/cpqarray.c linux-2.5.64-bk4/drivers/block/cpqarray.c --- linux-2.5.64-bk3/drivers/block/cpqarray.c Tue Mar 4 19:29:00 2003 +++ linux-2.5.64-bk4/drivers/block/cpqarray.c Mon Mar 31 12:25:45 2003 @@ -339,11 +339,9 @@ for(i=0; i < nr_ctlr; i++) { /* If this successful it should insure that we are the only */ /* instance of the driver */ - if (register_blkdev(COMPAQ_SMART2_MAJOR+i, hba[i]->devname, &ida_fops)) { - printk(KERN_ERR "cpqarray: Unable to get major number %d for ida\n", - COMPAQ_SMART2_MAJOR+i); + if (register_blkdev(COMPAQ_SMART2_MAJOR+i, hba[i]->devname)) continue; - } + hba[i]->access.set_intr_mask(hba[i], 0); if (request_irq(hba[i]->intr, do_ida_intr, SA_INTERRUPT|SA_SHIRQ, hba[i]->devname, hba[i])) { diff -urN linux-2.5.64-bk3/drivers/block/floppy.c linux-2.5.64-bk4/drivers/block/floppy.c --- linux-2.5.64-bk3/drivers/block/floppy.c Tue Mar 4 19:29:00 2003 +++ linux-2.5.64-bk4/drivers/block/floppy.c Mon Mar 31 12:25:45 2003 @@ -4232,8 +4232,7 @@ } devfs_mk_dir (NULL, "floppy", NULL); - if (register_blkdev(FLOPPY_MAJOR,"fd",&floppy_fops)) { - printk("Unable to get major %d for floppy\n",FLOPPY_MAJOR); + if (register_blkdev(FLOPPY_MAJOR,"fd")) { err = -EBUSY; goto out; } diff -urN linux-2.5.64-bk3/drivers/block/genhd.c linux-2.5.64-bk4/drivers/block/genhd.c --- linux-2.5.64-bk3/drivers/block/genhd.c Tue Mar 4 19:29:18 2003 +++ linux-2.5.64-bk4/drivers/block/genhd.c Mon Mar 31 12:25:45 2003 @@ -14,10 +14,16 @@ #include #include +#define MAX_PROBE_HASH 255 /* random */ static struct subsystem block_subsys; -#define MAX_PROBE_HASH 23 /* random */ +/* Can be merged with blk_probe or deleted altogether. Later. */ +static struct blk_major_name { + struct blk_major_name *next; + int major; + char name[16]; +} *major_names[MAX_PROBE_HASH]; static struct blk_probe { struct blk_probe *next; @@ -30,9 +36,132 @@ } *probes[MAX_PROBE_HASH]; /* index in the above - for now: assume no multimajor ranges */ +static inline int major_to_index(int major) +{ + return major % MAX_PROBE_HASH; +} + static inline int dev_to_index(dev_t dev) { - return MAJOR(dev) % MAX_PROBE_HASH; + return major_to_index(MAJOR(dev)); +} + +const char *__bdevname(dev_t dev) +{ + static char buffer[40]; + char *name = "unknown-block"; + unsigned int major = MAJOR(dev); + unsigned int minor = MINOR(dev); + int index = major_to_index(major); + struct blk_major_name *n; + + down_read(&block_subsys.rwsem); + for (n = major_names[index]; n; n = n->next) + if (n->major == major) + break; + if (n) + name = &(n->name[0]); + sprintf(buffer, "%s(%u,%u)", name, major, minor); + up_read(&block_subsys.rwsem); + + return buffer; +} + +/* get block device names in somewhat random order */ +int get_blkdev_list(char *p) +{ + struct blk_major_name *n; + int i, len; + + len = sprintf(p, "\nBlock devices:\n"); + + down_read(&block_subsys.rwsem); + for (i = 0; i < ARRAY_SIZE(major_names); i++) { + for (n = major_names[i]; n; n = n->next) + len += sprintf(p+len, "%3d %s\n", + n->major, n->name); + } + up_read(&block_subsys.rwsem); + + return len; +} + +int register_blkdev(unsigned int major, const char *name) +{ + struct blk_major_name **n, *p; + int index, ret = 0; + + if (devfs_only()) + return 0; + + /* temporary */ + if (major == 0) { + down_read(&block_subsys.rwsem); + for (index = ARRAY_SIZE(major_names)-1; index > 0; index--) + if (major_names[index] == NULL) + break; + up_read(&block_subsys.rwsem); + + if (index == 0) { + printk("register_blkdev: failed to get major for %s\n", + name); + return -EBUSY; + } + ret = major = index; + } + + p = kmalloc(sizeof(struct blk_major_name), GFP_KERNEL); + if (p == NULL) + return -ENOMEM; + + p->major = major; + strncpy(p->name, name, sizeof(p->name)-1); + p->name[sizeof(p->name)-1] = 0; + p->next = 0; + index = major_to_index(major); + + down_write(&block_subsys.rwsem); + for (n = &major_names[index]; *n; n = &(*n)->next) + if ((*n)->major == major) + break; + if (!*n) + *n = p; + else + ret = -EBUSY; + up_write(&block_subsys.rwsem); + + if (ret < 0) + printk("register_blkdev: cannot get major %d for %s\n", + major, name); + + return ret; +} + +/* todo: make void - error printk here */ +int unregister_blkdev(unsigned int major, const char *name) +{ + struct blk_major_name **n, *p; + int index; + int ret = 0; + + if (devfs_only()) + return 0; + index = major_to_index(major); + + down_write(&block_subsys.rwsem); + for (n = &major_names[index]; *n; n = &(*n)->next) + if ((*n)->major == major) + break; + if (!*n || strcmp((*n)->name, name)) + ret = -EINVAL; + else { + p = *n; + *n = p->next; + kfree(p); + } + up_write(&block_subsys.rwsem); + + return ret; } /* @@ -48,6 +177,9 @@ struct blk_probe *p = kmalloc(sizeof(struct blk_probe), GFP_KERNEL); struct blk_probe **s; + if (p == NULL) + return; + p->owner = module; p->get = probe; p->lock = lock; @@ -98,9 +230,9 @@ /** * add_gendisk - add partitioning information to kernel list - * @gp: per-device partitioning information + * @disk: per-device partitioning information * - * This function registers the partitioning information in @gp + * This function registers the partitioning information in @disk * with the kernel. */ void add_disk(struct gendisk *disk) @@ -318,7 +450,7 @@ return (jif / HZ) * 1000 + (jif % HZ) * 1000 / HZ; #endif } -static ssize_t disk_stat_read(struct gendisk * disk, char *page) +static ssize_t disk_stats_read(struct gendisk * disk, char *page) { disk_round_stats(disk); return sprintf(page, @@ -326,14 +458,16 @@ "%8u %8u %8llu %8u " "%8u %8u %8u" "\n", - disk->reads, disk->read_merges, - (unsigned long long)disk->read_sectors, - jiffies_to_msec(disk->read_ticks), - disk->writes, disk->write_merges, - (unsigned long long)disk->write_sectors, - jiffies_to_msec(disk->write_ticks), - disk->in_flight, jiffies_to_msec(disk->io_ticks), - jiffies_to_msec(disk->time_in_queue)); + disk_stat_read(disk, reads), disk_stat_read(disk, read_merges), + (unsigned long long)disk_stat_read(disk, read_sectors), + jiffies_to_msec(disk_stat_read(disk, read_ticks)), + disk_stat_read(disk, writes), + disk_stat_read(disk, write_merges), + (unsigned long long)disk_stat_read(disk, write_sectors), + jiffies_to_msec(disk_stat_read(disk, write_ticks)), + disk_stat_read(disk, in_flight), + jiffies_to_msec(disk_stat_read(disk, io_ticks)), + jiffies_to_msec(disk_stat_read(disk, time_in_queue))); } static struct disk_attribute disk_attr_dev = { .attr = {.name = "dev", .mode = S_IRUGO }, @@ -349,7 +483,7 @@ }; static struct disk_attribute disk_attr_stat = { .attr = {.name = "stat", .mode = S_IRUGO }, - .show = disk_stat_read + .show = disk_stats_read }; static struct attribute * default_attrs[] = { @@ -365,6 +499,7 @@ struct gendisk *disk = to_disk(kobj); kfree(disk->random); kfree(disk->part); + free_disk_stats(disk); kfree(disk); } @@ -384,6 +519,10 @@ struct gendisk *disk = kmalloc(sizeof(struct gendisk), GFP_KERNEL); if (disk) { memset(disk, 0, sizeof(struct gendisk)); + if (!init_disk_stats(disk)) { + kfree(disk); + return NULL; + } if (minors > 1) { int size = (minors - 1) * sizeof(struct hd_struct); disk->part = kmalloc(size, GFP_KERNEL); diff -urN linux-2.5.64-bk3/drivers/block/ll_rw_blk.c linux-2.5.64-bk4/drivers/block/ll_rw_blk.c --- linux-2.5.64-bk3/drivers/block/ll_rw_blk.c Tue Mar 4 19:28:58 2003 +++ linux-2.5.64-bk4/drivers/block/ll_rw_blk.c Mon Mar 31 12:25:45 2003 @@ -1475,17 +1475,17 @@ return; if (rw == READ) { - rq->rq_disk->read_sectors += nr_sectors; + disk_stat_add(rq->rq_disk, read_sectors, nr_sectors); if (!new_io) - rq->rq_disk->read_merges++; + disk_stat_inc(rq->rq_disk, read_merges); } else if (rw == WRITE) { - rq->rq_disk->write_sectors += nr_sectors; + disk_stat_add(rq->rq_disk, write_sectors, nr_sectors); if (!new_io) - rq->rq_disk->write_merges++; + disk_stat_inc(rq->rq_disk, write_merges); } if (new_io) { disk_round_stats(rq->rq_disk); - rq->rq_disk->in_flight++; + disk_stat_inc(rq->rq_disk, in_flight); } } @@ -1525,11 +1525,12 @@ { unsigned long now = jiffies; - disk->time_in_queue += disk->in_flight * (now - disk->stamp); + disk_stat_add(disk, time_in_queue, + disk_stat_read(disk, in_flight) * (now - disk->stamp)); disk->stamp = now; - if (disk->in_flight) - disk->io_ticks += (now - disk->stamp_idle); + if (disk_stat_read(disk, in_flight)) + disk_stat_add(disk, io_ticks, (now - disk->stamp_idle)); disk->stamp_idle = now; } @@ -1647,7 +1648,7 @@ if (req->rq_disk) { disk_round_stats(req->rq_disk); - req->rq_disk->in_flight--; + disk_stat_dec(req->rq_disk, in_flight); } __blk_put_request(q, next); @@ -2199,16 +2200,16 @@ unsigned long duration = jiffies - req->start_time; switch (rq_data_dir(req)) { case WRITE: - disk->writes++; - disk->write_ticks += duration; + disk_stat_inc(disk, writes); + disk_stat_add(disk, write_ticks, duration); break; case READ: - disk->reads++; - disk->read_ticks += duration; + disk_stat_inc(disk, reads); + disk_stat_add(disk, read_ticks, duration); break; } disk_round_stats(disk); - disk->in_flight--; + disk_stat_dec(disk, in_flight); } __blk_put_request(req->q, req); } diff -urN linux-2.5.64-bk3/drivers/block/loop.c linux-2.5.64-bk4/drivers/block/loop.c --- linux-2.5.64-bk3/drivers/block/loop.c Tue Mar 4 19:29:22 2003 +++ linux-2.5.64-bk4/drivers/block/loop.c Mon Mar 31 12:25:45 2003 @@ -1017,11 +1017,8 @@ max_loop = 8; } - if (register_blkdev(LOOP_MAJOR, "loop", &lo_fops)) { - printk(KERN_WARNING "Unable to get major number %d for loop" - " device\n", LOOP_MAJOR); + if (register_blkdev(LOOP_MAJOR, "loop")) return -EIO; - } devfs_mk_dir(NULL, "loop", NULL); diff -urN linux-2.5.64-bk3/drivers/block/nbd.c linux-2.5.64-bk4/drivers/block/nbd.c --- linux-2.5.64-bk3/drivers/block/nbd.c Tue Mar 4 19:29:03 2003 +++ linux-2.5.64-bk4/drivers/block/nbd.c Mon Mar 31 12:25:45 2003 @@ -564,9 +564,7 @@ nbd_dev[i].disk = disk; } - if (register_blkdev(NBD_MAJOR, "nbd", &nbd_fops)) { - printk("Unable to get major number %d for NBD\n", - NBD_MAJOR); + if (register_blkdev(NBD_MAJOR, "nbd")) { err = -EIO; goto out; } diff -urN linux-2.5.64-bk3/drivers/block/paride/pcd.c linux-2.5.64-bk4/drivers/block/paride/pcd.c --- linux-2.5.64-bk3/drivers/block/paride/pcd.c Tue Mar 4 19:29:53 2003 +++ linux-2.5.64-bk4/drivers/block/paride/pcd.c Mon Mar 31 12:25:45 2003 @@ -942,8 +942,7 @@ /* get the atapi capabilities page */ pcd_probe_capabilities(); - if (register_blkdev(major, name, &pcd_bdops)) { - printk("pcd: unable to get major number %d\n", major); + if (register_blkdev(major, name)) { for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) put_disk(cd->disk); return -1; diff -urN linux-2.5.64-bk3/drivers/block/paride/pd.c linux-2.5.64-bk4/drivers/block/paride/pd.c --- linux-2.5.64-bk3/drivers/block/paride/pd.c Tue Mar 4 19:29:33 2003 +++ linux-2.5.64-bk4/drivers/block/paride/pd.c Mon Mar 31 12:25:45 2003 @@ -890,10 +890,9 @@ { if (disable) return -1; - if (register_blkdev(major, name, &pd_fops)) { - printk("%s: unable to get major number %d\n", name, major); + if (register_blkdev(major, name)) return -1; - } + blk_init_queue(&pd_queue, do_pd_request, &pd_lock); blk_queue_max_sectors(&pd_queue, cluster); diff -urN linux-2.5.64-bk3/drivers/block/paride/pf.c linux-2.5.64-bk4/drivers/block/paride/pf.c --- linux-2.5.64-bk3/drivers/block/paride/pf.c Tue Mar 4 19:29:30 2003 +++ linux-2.5.64-bk4/drivers/block/paride/pf.c Mon Mar 31 12:25:45 2003 @@ -957,8 +957,7 @@ return -1; pf_busy = 0; - if (register_blkdev(major, name, &pf_fops)) { - printk("pf_init: unable to get major number %d\n", major); + if (register_blkdev(major, name)) { for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++) put_disk(pf->disk); return -1; @@ -969,6 +968,7 @@ for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++) { struct gendisk *disk = pf->disk; + if (!pf->present) continue; disk->private_data = pf; diff -urN linux-2.5.64-bk3/drivers/block/ps2esdi.c linux-2.5.64-bk4/drivers/block/ps2esdi.c --- linux-2.5.64-bk3/drivers/block/ps2esdi.c Tue Mar 4 19:28:53 2003 +++ linux-2.5.64-bk4/drivers/block/ps2esdi.c Mon Mar 31 12:25:45 2003 @@ -146,13 +146,10 @@ int error = 0; - /* register the device - pass the name, major number and operations - vector . */ - if (register_blkdev(PS2ESDI_MAJOR, "ed", &ps2esdi_fops)) { - printk("%s: Unable to get major number %d\n", DEVICE_NAME, - PS2ESDI_MAJOR); + /* register the device - pass the name and major number */ + if (register_blkdev(PS2ESDI_MAJOR, "ed")) return -1; - } + /* set up some global information - indicating device specific info */ blk_init_queue(&ps2esdi_queue, do_ps2esdi_request, &ps2esdi_lock); diff -urN linux-2.5.64-bk3/drivers/block/rd.c linux-2.5.64-bk4/drivers/block/rd.c --- linux-2.5.64-bk3/drivers/block/rd.c Tue Mar 4 19:29:24 2003 +++ linux-2.5.64-bk4/drivers/block/rd.c Mon Mar 31 12:25:45 2003 @@ -409,8 +409,7 @@ goto out; } - if (register_blkdev(RAMDISK_MAJOR, "ramdisk", &rd_bd_op)) { - printk("RAMDISK: Could not get major %d", RAMDISK_MAJOR); + if (register_blkdev(RAMDISK_MAJOR, "ramdisk")) { err = -EIO; goto out; } diff -urN linux-2.5.64-bk3/drivers/block/swim3.c linux-2.5.64-bk4/drivers/block/swim3.c --- linux-2.5.64-bk3/drivers/block/swim3.c Tue Mar 4 19:29:16 2003 +++ linux-2.5.64-bk4/drivers/block/swim3.c Mon Mar 31 12:25:45 2003 @@ -1004,9 +1004,7 @@ goto out; } - if (register_blkdev(FLOPPY_MAJOR, "fd", &floppy_fops)) { - printk(KERN_ERR"Unable to get major %d for floppy\n", - FLOPPY_MAJOR); + if (register_blkdev(FLOPPY_MAJOR, "fd")) { err = -EBUSY; goto out; } diff -urN linux-2.5.64-bk3/drivers/block/swim_iop.c linux-2.5.64-bk4/drivers/block/swim_iop.c --- linux-2.5.64-bk3/drivers/block/swim_iop.c Tue Mar 4 19:28:53 2003 +++ linux-2.5.64-bk4/drivers/block/swim_iop.c Mon Mar 31 12:25:45 2003 @@ -137,13 +137,12 @@ current_req = NULL; floppy_count = 0; - if (!iop_ism_present) return -ENODEV; + if (!iop_ism_present) + return -ENODEV; - if (register_blkdev(FLOPPY_MAJOR, "fd", &floppy_fops)) { - printk(KERN_ERR "SWIM-IOP: Unable to get major %d for floppy\n", - FLOPPY_MAJOR); + if (register_blkdev(FLOPPY_MAJOR, "fd")) return -EBUSY; - } + blk_init_queue(&swim_queue, do_fd_request, &swim_iop_lock); printk("SWIM-IOP: %s by Joshua M. Thompson (funaho@jurai.org)\n", DRIVER_VERSION); diff -urN linux-2.5.64-bk3/drivers/block/umem.c linux-2.5.64-bk4/drivers/block/umem.c --- linux-2.5.64-bk3/drivers/block/umem.c Tue Mar 4 19:29:54 2003 +++ linux-2.5.64-bk4/drivers/block/umem.c Mon Mar 31 12:25:45 2003 @@ -1145,11 +1145,9 @@ if (retval) return -ENOMEM; - err = major_nr = register_blkdev(0, "umem", &mm_fops); - if (err < 0) { - printk(KERN_ERR "MM: Could not register block device\n"); + err = major_nr = register_blkdev(0, "umem"); + if (err < 0) return -EIO; - } for (i = 0; i < num_cards; i++) { mm_gendisk[i] = alloc_disk(1 << MM_SHIFT); diff -urN linux-2.5.64-bk3/drivers/block/xd.c linux-2.5.64-bk4/drivers/block/xd.c --- linux-2.5.64-bk3/drivers/block/xd.c Tue Mar 4 19:29:33 2003 +++ linux-2.5.64-bk4/drivers/block/xd.c Mon Mar 31 12:25:45 2003 @@ -154,9 +154,9 @@ #ifdef MODULE for (i = 4; i > 0; i--) - if(((xd[i] = xd[i-1]) >= 0) && !count) + if (((xd[i] = xd[i-1]) >= 0) && !count) count = i; - if((xd[0] = count)) + if ((xd[0] = count)) do_xd_setup(xd); #endif @@ -170,10 +170,9 @@ } err = -EBUSY; - if (register_blkdev(XT_DISK_MAJOR,"xd",&xd_fops)) { - printk("xd: Unable to get major number %d\n",XT_DISK_MAJOR); + if (register_blkdev(XT_DISK_MAJOR, "xd")) goto out1; - } + devfs_mk_dir(NULL, "xd", NULL); blk_init_queue(&xd_queue, do_xd_request, &xd_lock); if (xd_detect(&controller,&address)) { diff -urN linux-2.5.64-bk3/drivers/block/z2ram.c linux-2.5.64-bk4/drivers/block/z2ram.c --- linux-2.5.64-bk3/drivers/block/z2ram.c Tue Mar 4 19:29:29 2003 +++ linux-2.5.64-bk4/drivers/block/z2ram.c Mon Mar 31 12:25:45 2003 @@ -331,21 +331,18 @@ static struct request_queue z2_queue; int __init -z2_init( void ) +z2_init(void) { - if ( !MACH_IS_AMIGA ) + if (!MACH_IS_AMIGA) return -ENXIO; - if ( register_blkdev( Z2RAM_MAJOR, DEVICE_NAME, &z2_fops ) ) - { - printk( KERN_ERR DEVICE_NAME ": Unable to get major %d\n", - Z2RAM_MAJOR ); + if (register_blkdev(Z2RAM_MAJOR, DEVICE_NAME)) return -EBUSY; - } + z2ram_gendisk = alloc_disk(1); if (!z2ram_gendisk) { - unregister_blkdev( Z2RAM_MAJOR, DEVICE_NAME ); + unregister_blkdev(Z2RAM_MAJOR, DEVICE_NAME); return -ENOMEM; } z2ram_gendisk->major = Z2RAM_MAJOR; diff -urN linux-2.5.64-bk3/drivers/cdrom/aztcd.c linux-2.5.64-bk4/drivers/cdrom/aztcd.c --- linux-2.5.64-bk3/drivers/cdrom/aztcd.c Tue Mar 4 19:29:37 2003 +++ linux-2.5.64-bk4/drivers/cdrom/aztcd.c Mon Mar 31 12:25:45 2003 @@ -1910,12 +1910,12 @@ azt_disk = alloc_disk(1); if (!azt_disk) goto err_out; - if (register_blkdev(MAJOR_NR, "aztcd", &azt_fops) != 0) { - printk(KERN_WARNING "aztcd: Unable to get major %d for Aztech" - " CD-ROM\n", MAJOR_NR); + + if (register_blkdev(MAJOR_NR, "aztcd")) { ret = -EIO; goto err_out2; } + blk_init_queue(&azt_queue, do_aztcd_request, &aztSpin); blk_queue_hardsect_size(&azt_queue, 2048); azt_disk->major = MAJOR_NR; @@ -1931,7 +1931,7 @@ azt_invalidate_buffers(); aztPresent = 1; aztCloseDoor(); - return (0); + return 0; err_out2: put_disk(azt_disk); err_out: diff -urN linux-2.5.64-bk3/drivers/cdrom/cdu31a.c linux-2.5.64-bk4/drivers/cdrom/cdu31a.c --- linux-2.5.64-bk3/drivers/cdrom/cdu31a.c Tue Mar 4 19:29:31 2003 +++ linux-2.5.64-bk4/drivers/cdrom/cdu31a.c Mon Mar 31 12:25:45 2003 @@ -3368,11 +3368,8 @@ if (!request_region(cdu31a_port, 4, "cdu31a")) goto errout3; - if (register_blkdev(MAJOR_NR, "cdu31a", &scd_bdops)) { - printk("Unable to get major %d for CDU-31a\n", - MAJOR_NR); + if (register_blkdev(MAJOR_NR, "cdu31a")) goto errout2; - } disk = alloc_disk(1); if (!disk) diff -urN linux-2.5.64-bk3/drivers/cdrom/cm206.c linux-2.5.64-bk4/drivers/cdrom/cm206.c --- linux-2.5.64-bk3/drivers/cdrom/cm206.c Tue Mar 4 19:29:35 2003 +++ linux-2.5.64-bk4/drivers/cdrom/cm206.c Mon Mar 31 12:25:45 2003 @@ -1489,10 +1489,10 @@ goto out_probe; } printk(".\n"); - if (register_blkdev(MAJOR_NR, "cm206", &cm206_bdops) != 0) { - printk(KERN_INFO "Cannot register for major %d!\n", MAJOR_NR); + + if (register_blkdev(MAJOR_NR, "cm206")) goto out_blkdev; - } + disk = alloc_disk(1); if (!disk) goto out_disk; diff -urN linux-2.5.64-bk3/drivers/cdrom/gscd.c linux-2.5.64-bk4/drivers/cdrom/gscd.c --- linux-2.5.64-bk3/drivers/cdrom/gscd.c Tue Mar 4 19:28:53 2003 +++ linux-2.5.64-bk4/drivers/cdrom/gscd.c Mon Mar 31 12:25:45 2003 @@ -959,12 +959,11 @@ gscd_disk->fops = &gscd_fops; sprintf(gscd_disk->disk_name, "gscd"); - if (register_blkdev(MAJOR_NR, "gscd", &gscd_fops) != 0) { - printk(KERN_WARNING "GSCD: Unable to get major %d for GoldStar " - "CD-ROM\n", MAJOR_NR); + if (register_blkdev(MAJOR_NR, "gscd")) { ret = -EIO; goto err_out2; } + devfs_register(NULL, "gscd", DEVFS_FL_DEFAULT, MAJOR_NR, 0, S_IFBLK | S_IRUGO | S_IWUGO, &gscd_fops, NULL); diff -urN linux-2.5.64-bk3/drivers/cdrom/mcd.c linux-2.5.64-bk4/drivers/cdrom/mcd.c --- linux-2.5.64-bk3/drivers/cdrom/mcd.c Tue Mar 4 19:29:24 2003 +++ linux-2.5.64-bk4/drivers/cdrom/mcd.c Mon Mar 31 12:25:45 2003 @@ -1068,8 +1068,7 @@ put_disk(disk); return -EIO; } - if (register_blkdev(MAJOR_NR, "mcd", &mcd_bdops) != 0) { - printk(KERN_ERR "mcd: Unable to get major %d for Mitsumi CD-ROM\n", MAJOR_NR); + if (register_blkdev(MAJOR_NR, "mcd")) { put_disk(disk); return -EIO; } diff -urN linux-2.5.64-bk3/drivers/cdrom/mcdx.c linux-2.5.64-bk4/drivers/cdrom/mcdx.c --- linux-2.5.64-bk3/drivers/cdrom/mcdx.c Tue Mar 4 19:29:18 2003 +++ linux-2.5.64-bk4/drivers/cdrom/mcdx.c Mon Mar 31 12:25:45 2003 @@ -1193,11 +1193,9 @@ } xtrace(INIT, "init() register blkdev\n"); - if (register_blkdev(MAJOR_NR, "mcdx", &mcdx_bdops) != 0) { + if (register_blkdev(MAJOR_NR, "mcdx")) { release_region((unsigned long) stuffp->wreg_data, MCDX_IO_SIZE); - xwarn("%s=0x%3p,%d: Init failed. Can't get major %d.\n", - MCDX, stuffp->wreg_data, stuffp->irq, MAJOR_NR); kfree(stuffp); put_disk(disk); return 1; diff -urN linux-2.5.64-bk3/drivers/cdrom/optcd.c linux-2.5.64-bk4/drivers/cdrom/optcd.c --- linux-2.5.64-bk3/drivers/cdrom/optcd.c Tue Mar 4 19:29:03 2003 +++ linux-2.5.64-bk4/drivers/cdrom/optcd.c Mon Mar 31 12:25:45 2003 @@ -2047,8 +2047,7 @@ put_disk(optcd_disk); return -EIO; } - if (register_blkdev(MAJOR_NR, "optcd", &opt_fops) != 0) { - printk(KERN_ERR "optcd: unable to get major %d\n", MAJOR_NR); + if (register_blkdev(MAJOR_NR, "optcd")) { release_region(optcd_port, 4); put_disk(optcd_disk); return -EIO; diff -urN linux-2.5.64-bk3/drivers/cdrom/sbpcd.c linux-2.5.64-bk4/drivers/cdrom/sbpcd.c --- linux-2.5.64-bk3/drivers/cdrom/sbpcd.c Tue Mar 4 19:29:00 2003 +++ linux-2.5.64-bk4/drivers/cdrom/sbpcd.c Mon Mar 31 12:25:45 2003 @@ -5795,15 +5795,14 @@ OUT(MIXER_data,0xCC); /* one nibble per channel, max. value: 0xFF */ #endif /* SOUND_BASE */ - if (register_blkdev(MAJOR_NR, major_name, &sbpcd_bdops) != 0) - { - msg(DBG_INF, "Can't get MAJOR %d for Matsushita CDROM\n", MAJOR_NR); + if (register_blkdev(MAJOR_NR, major_name)) { #ifdef MODULE return -EIO; #else goto init_done; #endif /* MODULE */ } + blk_init_queue(&sbpcd_queue, do_sbpcd_request, &sbpcd_lock); devfs_mk_dir (NULL, "sbp", NULL); diff -urN linux-2.5.64-bk3/drivers/cdrom/sjcd.c linux-2.5.64-bk4/drivers/cdrom/sjcd.c --- linux-2.5.64-bk3/drivers/cdrom/sjcd.c Tue Mar 4 19:29:30 2003 +++ linux-2.5.64-bk4/drivers/cdrom/sjcd.c Mon Mar 31 12:25:45 2003 @@ -1677,11 +1677,8 @@ printk("SJCD: sjcd=0x%x: ", sjcd_base); #endif - if (register_blkdev(MAJOR_NR, "sjcd", &sjcd_fops) != 0) { - printk("SJCD: Unable to get major %d for Sanyo CD-ROM\n", - MAJOR_NR); - return (-EIO); - } + if (register_blkdev(MAJOR_NR, "sjcd")) + return -EIO; blk_init_queue(&sjcd_queue, do_sjcd_request, &sjcd_lock); blk_queue_hardsect_size(&sjcd_queue, 2048); diff -urN linux-2.5.64-bk3/drivers/cdrom/sonycd535.c linux-2.5.64-bk4/drivers/cdrom/sonycd535.c --- linux-2.5.64-bk3/drivers/cdrom/sonycd535.c Tue Mar 4 19:29:15 2003 +++ linux-2.5.64-bk4/drivers/cdrom/sonycd535.c Mon Mar 31 12:25:45 2003 @@ -1546,9 +1546,7 @@ printk("IRQ%d, ", tmp_irq); printk("using %d byte buffer\n", sony_buffer_size); - if (register_blkdev(MAJOR_NR, CDU535_HANDLE, &cdu_fops)) { - printk("Unable to get major %d for %s\n", - MAJOR_NR, CDU535_MESSAGE_NAME); + if (register_blkdev(MAJOR_NR, CDU535_HANDLE)) { err = -EIO; goto out1; } diff -urN linux-2.5.64-bk3/drivers/char/raw.c linux-2.5.64-bk4/drivers/char/raw.c --- linux-2.5.64-bk3/drivers/char/raw.c Tue Mar 4 19:29:24 2003 +++ linux-2.5.64-bk4/drivers/char/raw.c Mon Mar 31 12:25:45 2003 @@ -19,14 +19,16 @@ #include +#define MAX_RAW_MINORS 256 + struct raw_device_data { struct block_device *binding; int inuse; }; -static struct raw_device_data raw_devices[256]; +static struct raw_device_data raw_devices[MAX_RAW_MINORS]; static DECLARE_MUTEX(raw_mutex); -static struct file_operations raw_ctl_fops; +static struct file_operations raw_ctl_fops; /* forward declaration */ /* * Open/close code for raw IO. @@ -85,11 +87,16 @@ { const int minor= minor(inode->i_rdev); struct block_device *bdev; - + down(&raw_mutex); bdev = raw_devices[minor].binding; raw_devices[minor].inuse--; up(&raw_mutex); + + /* Here inode->i_mapping == bdev->bd_inode->i_mapping */ + inode->i_mapping = &inode->i_data; + inode->i_mapping->backing_dev_info = &default_backing_dev_info; + bd_release(bdev); blkdev_put(bdev, BDEV_RAW); return 0; @@ -130,11 +137,13 @@ goto out; err = -EINVAL; - if (rq.raw_minor < 0 || rq.raw_minor > MINORMASK) + if (rq.raw_minor < 0 || rq.raw_minor >= MAX_RAW_MINORS) goto out; rawdev = &raw_devices[rq.raw_minor]; if (command == RAW_SETBIND) { + dev_t dev; + /* * This is like making block devices, so demand the * same capability @@ -151,9 +160,10 @@ */ err = -EINVAL; + dev = MKDEV(rq.block_major, rq.block_minor); if ((rq.block_major == 0 && rq.block_minor != 0) || - rq.block_major > MAX_BLKDEV || - rq.block_minor > MINORMASK) + MAJOR(dev) != rq.block_major || + MINOR(dev) != rq.block_minor) goto out; down(&raw_mutex); @@ -170,10 +180,7 @@ /* unbind */ rawdev->binding = NULL; } else { - kdev_t kdev; - - kdev = mk_kdev(rq.block_major, rq.block_minor); - rawdev->binding = bdget(kdev_t_to_nr(kdev)); + rawdev->binding = bdget(dev); MOD_INC_USE_COUNT; } up(&raw_mutex); diff -urN linux-2.5.64-bk3/drivers/char/watchdog/amd7xx_tco.c linux-2.5.64-bk4/drivers/char/watchdog/amd7xx_tco.c --- linux-2.5.64-bk3/drivers/char/watchdog/amd7xx_tco.c Tue Mar 4 19:29:03 2003 +++ linux-2.5.64-bk4/drivers/char/watchdog/amd7xx_tco.c Mon Mar 31 12:25:45 2003 @@ -1,6 +1,6 @@ /* * AMD 766/768 TCO Timer Driver - * (c) Copyright 2002 Zwane Mwaikambo + * (c) Copyright 2002 Zwane Mwaikambo * All Rights Reserved. * * Parts from; @@ -34,35 +34,48 @@ #include #include -#define AMDTCO_MODULE_VER "build 20020601" +#define AMDTCO_MODULE_VER "build 20021116" #define AMDTCO_MODULE_NAME "amd7xx_tco" #define PFX AMDTCO_MODULE_NAME ": " -#define MAX_TIMEOUT 38 /* max of 38 seconds */ +#define MAX_TIMEOUT 38 /* max of 38 seconds, although the system will only + * reset itself after the second timeout */ /* pmbase registers */ -#define GLOBAL_SMI_REG 0x2a -#define TCO_EN (1 << 1) /* bit 1 in global SMI register */ #define TCO_RELOAD_REG 0x40 /* bits 0-5 are current count, 6-7 are reserved */ #define TCO_INITVAL_REG 0x41 /* bits 0-5 are value to load, 6-7 are reserved */ #define TCO_TIMEOUT_MASK 0x3f +#define TCO_STATUS1_REG 0x44 #define TCO_STATUS2_REG 0x46 #define NDTO_STS2 (1 << 1) /* we're interested in the second timeout */ #define BOOT_STS (1 << 2) /* will be set if NDTO_STS2 was set before reboot */ #define TCO_CTRL1_REG 0x48 #define TCO_HALT (1 << 11) +#define NO_REBOOT (1 << 10) /* in DevB:3x48 */ -static char banner[] __initdata = KERN_INFO PFX AMDTCO_MODULE_VER; -static int timeout = 38; +static char banner[] __initdata = KERN_INFO PFX AMDTCO_MODULE_VER "\n"; +static int timeout = MAX_TIMEOUT; static u32 pmbase; /* PMxx I/O base */ static struct pci_dev *dev; static struct semaphore open_sem; -spinlock_t amdtco_lock; /* only for device access */ +static spinlock_t amdtco_lock; /* only for device access */ static int expect_close = 0; MODULE_PARM(timeout, "i"); MODULE_PARM_DESC(timeout, "range is 0-38 seconds, default is 38"); +static inline u8 seconds_to_ticks(int seconds) +{ + /* the internal timer is stored as ticks which decrement + * every 0.6 seconds */ + return (seconds * 10) / 6; +} + +static inline int ticks_to_seconds(u8 ticks) +{ + return (ticks * 6) / 10; +} + static inline int amdtco_status(void) { u16 reg; @@ -81,28 +94,19 @@ static inline void amdtco_ping(void) { - u8 reg; - - spin_lock(&amdtco_lock); - reg = inb(pmbase+TCO_RELOAD_REG); - outb(1 | reg, pmbase+TCO_RELOAD_REG); - spin_unlock(&amdtco_lock); + outb(1, pmbase+TCO_RELOAD_REG); } static inline int amdtco_gettimeout(void) { - return inb(TCO_RELOAD_REG) & TCO_TIMEOUT_MASK; + u8 reg = inb(pmbase+TCO_RELOAD_REG) & TCO_TIMEOUT_MASK; + return ticks_to_seconds(reg); } static inline void amdtco_settimeout(unsigned int timeout) { - u8 reg; - - spin_lock(&amdtco_lock); - reg = inb(pmbase+TCO_INITVAL_REG); - reg |= timeout & TCO_TIMEOUT_MASK; + u8 reg = seconds_to_ticks(timeout) & TCO_TIMEOUT_MASK; outb(reg, pmbase+TCO_INITVAL_REG); - spin_unlock(&amdtco_lock); } static inline void amdtco_global_enable(void) @@ -110,9 +114,12 @@ u16 reg; spin_lock(&amdtco_lock); - reg = inw(pmbase+GLOBAL_SMI_REG); - reg |= TCO_EN; - outw(reg, pmbase+GLOBAL_SMI_REG); + + /* clear NO_REBOOT on DevB:3x48 p97 */ + pci_read_config_word(dev, 0x48, ®); + reg &= ~NO_REBOOT; + pci_write_config_word(dev, 0x48, reg); + spin_unlock(&amdtco_lock); } @@ -146,10 +153,12 @@ if (timeout > MAX_TIMEOUT) timeout = MAX_TIMEOUT; + amdtco_disable(); amdtco_settimeout(timeout); amdtco_global_enable(); + amdtco_enable(); amdtco_ping(); - printk(KERN_INFO PFX "Watchdog enabled, timeout = %d/%d seconds", + printk(KERN_INFO PFX "Watchdog enabled, timeout = %ds of %ds\n", amdtco_gettimeout(), timeout); return 0; @@ -198,7 +207,7 @@ case WDIOC_GETTIMEOUT: return put_user(amdtco_gettimeout(), (int *)arg); - + case WDIOC_SETOPTIONS: if (copy_from_user(&tmp, (int *)arg, sizeof tmp)) return -EFAULT; @@ -221,7 +230,7 @@ printk(KERN_INFO PFX "Watchdog disabled\n"); } else { amdtco_ping(); - printk(KERN_CRIT PFX "Unexpected close!, timeout in %d seconds)\n", timeout); + printk(KERN_CRIT PFX "Unexpected close!, timeout in %d seconds\n", timeout); } up(&open_sem); @@ -249,10 +258,9 @@ } #endif amdtco_ping(); - return len; } - return 0; + return len; } @@ -357,6 +365,9 @@ if (ints[0] > 0) timeout = ints[1]; + if (!timeout || timeout > MAX_TIMEOUT) + timeout = MAX_TIMEOUT; + return 1; } @@ -366,8 +377,7 @@ module_init(amdtco_init); module_exit(amdtco_exit); -MODULE_AUTHOR("Zwane Mwaikambo "); +MODULE_AUTHOR("Zwane Mwaikambo "); MODULE_DESCRIPTION("AMD 766/768 TCO Timer Driver"); MODULE_LICENSE("GPL"); -EXPORT_NO_SYMBOLS; diff -urN linux-2.5.64-bk3/drivers/ide/ide-probe.c linux-2.5.64-bk4/drivers/ide/ide-probe.c --- linux-2.5.64-bk3/drivers/ide/ide-probe.c Tue Mar 4 19:29:23 2003 +++ linux-2.5.64-bk4/drivers/ide/ide-probe.c Mon Mar 31 12:25:45 2003 @@ -1292,11 +1292,8 @@ /* we set it back to 1 if all is ok below */ hwif->present = 0; - if (register_blkdev (hwif->major, hwif->name, ide_fops)) { - printk("%s: UNABLE TO GET MAJOR NUMBER %d\n", - hwif->name, hwif->major); + if (register_blkdev(hwif->major, hwif->name)) return 0; - } if (alloc_disks(hwif) < 0) goto out; diff -urN linux-2.5.64-bk3/drivers/ide/legacy/hd.c linux-2.5.64-bk4/drivers/ide/legacy/hd.c --- linux-2.5.64-bk3/drivers/ide/legacy/hd.c Tue Mar 4 19:28:53 2003 +++ linux-2.5.64-bk4/drivers/ide/legacy/hd.c Mon Mar 31 12:25:45 2003 @@ -708,10 +708,10 @@ static int __init hd_init(void) { int drive; - if (register_blkdev(MAJOR_NR,"hd",&hd_fops)) { - printk("hd: unable to get major %d for hard disk\n",MAJOR_NR); + + if (register_blkdev(MAJOR_NR,"hd")) return -1; - } + blk_init_queue(&hd_queue, do_hd_request, &hd_lock); blk_queue_max_sectors(&hd_queue, 255); init_timer(&device_timer); diff -urN linux-2.5.64-bk3/drivers/isdn/hardware/avm/b1pci.c linux-2.5.64-bk4/drivers/isdn/hardware/avm/b1pci.c --- linux-2.5.64-bk3/drivers/isdn/hardware/avm/b1pci.c Tue Mar 4 19:28:55 2003 +++ linux-2.5.64-bk4/drivers/isdn/hardware/avm/b1pci.c Mon Mar 31 12:25:45 2003 @@ -343,12 +343,16 @@ static void __devexit b1pci_pci_remove(struct pci_dev *pdev) { +#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4 avmcard *card = pci_get_drvdata(pdev); if (card->dma) b1pciv4_remove(pdev); else b1pci_remove(pdev); +#else + b1pci_remove(pdev); +#endif } static struct pci_driver b1pci_pci_driver = { diff -urN linux-2.5.64-bk3/drivers/isdn/hisax/amd7930.c linux-2.5.64-bk4/drivers/isdn/hisax/amd7930.c --- linux-2.5.64-bk3/drivers/isdn/hisax/amd7930.c Tue Mar 4 19:29:16 2003 +++ linux-2.5.64-bk4/drivers/isdn/hisax/amd7930.c Wed Dec 31 16:00:00 1969 @@ -1,717 +0,0 @@ -/* $Id: amd7930.c,v 1.5.6.4 2001/09/23 22:24:46 kai Exp $ - * - * HiSax ISDN driver - chip specific routines for AMD 7930 - * - * Author Brent Baccala - * Copyright by Brent Baccala - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * - Existing ISDN HiSax driver provides all the smarts - * - it compiles, runs, talks to an isolated phone switch, connects - * to a Cisco, pings go through - * - AMD 7930 support only (no DBRI yet) - * - no US NI-1 support (may not work on US phone system - untested) - * - periodic packet loss, apparently due to lost interrupts - * - ISDN sometimes freezes, requiring reboot before it will work again - * - * The code is unreliable enough to be consider alpha - * - * This file is (c) under GNU General Public License - * - * Advanced Micro Devices' Am79C30A is an ISDN/audio chip used in the - * SparcStation 1+. The chip provides microphone and speaker interfaces - * which provide mono-channel audio at 8K samples per second via either - * 8-bit A-law or 8-bit mu-law encoding. Also, the chip features an - * ISDN BRI Line Interface Unit (LIU), I.430 S/T physical interface, - * which performs basic D channel LAPD processing and provides raw - * B channel data. The digital audio channel, the two ISDN B channels, - * and two 64 Kbps channels to the microprocessor are all interconnected - * via a multiplexer. - * - * This driver interfaces to the Linux HiSax ISDN driver, which performs - * all high-level Q.921 and Q.931 ISDN functions. The file is not - * itself a hardware driver; rather it uses functions exported by - * the AMD7930 driver in the sparcaudio subsystem (drivers/sbus/audio), - * allowing the chip to be simultaneously used for both audio and ISDN data. - * The hardware driver does _no_ buffering, but provides several callbacks - * which are called during interrupt service and should therefore run quickly. - * - * D channel transmission is performed by passing the hardware driver the - * address and size of an skb's data area, then waiting for a callback - * to signal successful transmission of the packet. A task is then - * queued to notify the HiSax driver that another packet may be transmitted. - * - * D channel reception is quite simple, mainly because of: - * 1) the slow speed of the D channel - 16 kbps, and - * 2) the presence of an 8- or 32-byte (depending on chip version) FIFO - * to buffer the D channel data on the chip - * Worst case scenario of back-to-back packets with the 8 byte buffer - * at 16 kbps yields an service time of 4 ms - long enough to preclude - * the need for fancy buffering. We queue a background task that copies - * data out of the receive buffer into an skb, and the hardware driver - * simply does nothing until we're done with the receive buffer and - * reset it for a new packet. - * - * B channel processing is more complex, because of: - * 1) the faster speed - 64 kbps, - * 2) the lack of any on-chip buffering (it interrupts for every byte), and - * 3) the lack of any chip support for HDLC encapsulation - * - * The HiSax driver can put each B channel into one of three modes - - * L1_MODE_NULL (channel disabled), L1_MODE_TRANS (transparent data relay), - * and L1_MODE_HDLC (HDLC encapsulation by low-level driver). - * L1_MODE_HDLC is the most common, used for almost all "pure" digital - * data sessions. L1_MODE_TRANS is used for ISDN audio. - * - * HDLC B channel transmission is performed via a large buffer into - * which the skb is copied while performing HDLC bit-stuffing. A CRC - * is computed and attached to the end of the buffer, which is then - * passed to the low-level routines for raw transmission. Once - * transmission is complete, the hardware driver is set to enter HDLC - * idle by successive transmission of mark (all 1) bytes, waiting for - * the ISDN driver to prepare another packet for transmission and - * deliver it. - * - * HDLC B channel reception is performed via an X-byte ring buffer - * divided into N sections of X/N bytes each. Defaults: X=256 bytes, N=4. - * As the hardware driver notifies us that each section is full, we - * hand it the next section and schedule a background task to peruse - * the received section, bit-by-bit, with an HDLC decoder. As - * packets are detected, they are copied into a large buffer while - * decoding HDLC bit-stuffing. The ending CRC is verified, and if - * it is correct, we alloc a new skb of the correct length (which we - * now know), copy the packet into it, and hand it to the upper layers. - * Optimization: for large packets, we hand the buffer (which also - * happens to be an skb) directly to the upper layer after an skb_trim, - * and alloc a new large buffer for future packets, thus avoiding a copy. - * Then we return to HDLC processing; state is saved between calls. - * - */ - -#include "hisax.h" -#include "../../sbus/audio/amd7930.h" -#include "isac.h" -#include "isdnl1.h" -#include "rawhdlc.h" -#include - -static const char *amd7930_revision = "$Revision: 1.5.6.4 $"; - -#define RCV_BUFSIZE 1024 /* Size of raw receive buffer in bytes */ -#define RCV_BUFBLKS 4 /* Number of blocks to divide buffer into - * (must divide RCV_BUFSIZE) */ - -static void Bchan_fill_fifo(struct BCState *, struct sk_buff *); - -static void -Bchan_xmt_bh(void *data) -{ - struct BCState *bcs = data; - struct sk_buff *skb; - - if (bcs->hw.amd7930.tx_skb != NULL) { - dev_kfree_skb(bcs->hw.amd7930.tx_skb); - bcs->hw.amd7930.tx_skb = NULL; - } - xmit_ready_b(bcs); -} - -static void -Bchan_xmit_callback(struct BCState *bcs) -{ - schedule_work(&bcs->hw.amd7930.xmt_work); -} - -/* B channel transmission: two modes (three, if you count L1_MODE_NULL) - * - * L1_MODE_HDLC - We need to do HDLC encapsulation before transmiting - * the packet (i.e. make_raw_hdlc_data). Since this can be a - * time-consuming operation, our completion callback just schedules - * a bottom half to do encapsulation for the next packet. In between, - * the link will just idle - * - * L1_MODE_TRANS - Data goes through, well, transparent. No HDLC encap, - * and we can't just let the link idle, so the "bottom half" actually - * gets called during the top half (it's our callback routine in this case), - * but it's a lot faster now since we don't call make_raw_hdlc_data - */ - -static void -Bchan_fill_fifo(struct BCState *bcs, struct sk_buff *skb) -{ - struct IsdnCardState *cs = bcs->cs; - int len; - - if ((cs->debug & L1_DEB_HSCX) || (cs->debug & L1_DEB_HSCX_FIFO)) { - char tmp[1024]; - char *t = tmp; - - t += sprintf(t, "amd7930_fill_fifo %c cnt %d", - bcs->channel ? 'B' : 'A', skb->len); - if (cs->debug & L1_DEB_HSCX_FIFO) - QuickHex(t, skb->data, skb->len); - debugl1(cs, tmp); - } - - if (bcs->mode == L1_MODE_HDLC) { - len = make_raw_hdlc_data(skb->data, skb->len, - bcs->hw.amd7930.tx_buff, RAW_BUFMAX); - if (len > 0) - amd7930_bxmit(0, bcs->channel, - bcs->hw.amd7930.tx_buff, len, - (void *) &Bchan_xmit_callback, - (void *) bcs); - dev_kfree_skb(skb); - } else if (bcs->mode == L1_MODE_TRANS) { - amd7930_bxmit(0, bcs->channel, - bcs->hw.amd7930.tx_buff, skb->len, - (void *) &Bchan_xmt_bh, - (void *) bcs); - bcs->hw.amd7930.tx_skb = skb; - } else { - dev_kfree_skb(skb); - } -} - -static void -Bchan_mode(struct BCState *bcs, int mode, int bc) -{ - struct IsdnCardState *cs = bcs->cs; - - if (cs->debug & L1_DEB_HSCX) { - char tmp[40]; - sprintf(tmp, "AMD 7930 mode %d bchan %d/%d", - mode, bc, bcs->channel); - debugl1(cs, tmp); - } - bcs->mode = mode; -} - -/* Bchan_l2l1 is the entry point for upper layer routines that want to - * transmit on the B channel. PH_DATA_REQ is a normal packet that - * we either start transmitting (if idle) or queue (if busy). - * PH_PULL_REQ can be called to request a callback message (PH_PULL_CNF) - * once the link is idle. After a "pull" callback, the upper layer - * routines can use PH_PULL_IND to send data. - */ - -static void -Bchan_l2l1(struct PStack *st, int pr, void *arg) -{ - struct sk_buff *skb = arg; - - switch (pr) { - case (PH_DATA_REQ): - if (test_bit(BC_FLG_BUSY, &st->l1.bcs->Flag)) { - skb_queue_tail(&st->l1.bcs->squeue, skb); - } else { - test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag); - Bchan_fill_fifo(st->l1.bcs, skb); - } - break; - case (PH_PULL_IND): - if (test_bit(BC_FLG_BUSY, &st->l1.bcs->Flag)) { - printk(KERN_WARNING "amd7930: this shouldn't happen\n"); - break; - } - test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag); - Bchan_fill_fifo(st->l1.bcs, skb); - break; - case (PH_PULL_REQ): - if (!test_bit(BC_FLG_BUSY, &st->l1.bcs->Flag)) { - clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - st->l1.l1l2(st, PH_PULL_CNF, NULL); - } else - set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - break; - } -} - -/* Receiver callback and bottom half - decodes HDLC at leisure (if - * L1_MODE_HDLC) and passes newly received skb on via bcs->rqueue. If - * a large packet is received, stick rv_skb (the buffer that the - * packet has been decoded into) on the receive queue and alloc a new - * (large) skb to act as buffer for future receives. If a small - * packet is received, leave rv_skb alone, alloc a new skb of the - * correct size, and copy the packet into it - */ - -static void -Bchan_recv_callback(struct BCState *bcs) -{ - struct amd7930_hw *hw = &bcs->hw.amd7930; - - hw->rv_buff_in += RCV_BUFSIZE/RCV_BUFBLKS; - hw->rv_buff_in %= RCV_BUFSIZE; - - if (hw->rv_buff_in != hw->rv_buff_out) { - amd7930_brecv(0, bcs->channel, - hw->rv_buff + hw->rv_buff_in, - RCV_BUFSIZE/RCV_BUFBLKS, - (void *) &Bchan_recv_callback, (void *) bcs); - } - - schedule_work(&hw->rcv_work); -} - -static void -Bchan_rcv_bh(void *data) -{ - struct BCState *bcs = data; - struct IsdnCardState *cs = bcs->cs; - struct amd7930_hw *hw = &bcs->hw.amd7930; - struct sk_buff *skb; - int len; - - if (cs->debug & L1_DEB_HSCX) { - char tmp[1024]; - - sprintf(tmp, "amd7930_Bchan_rcv (%d/%d)", - hw->rv_buff_in, hw->rv_buff_out); - debugl1(cs, tmp); - QuickHex(tmp, hw->rv_buff + hw->rv_buff_out, - RCV_BUFSIZE/RCV_BUFBLKS); - debugl1(cs, tmp); - } - - do { - if (bcs->mode == L1_MODE_HDLC) { - while ((len = read_raw_hdlc_data(hw->hdlc_state, - hw->rv_buff + hw->rv_buff_out, RCV_BUFSIZE/RCV_BUFBLKS, - hw->rv_skb->tail, HSCX_BUFMAX))) { - if (len > 0 && (cs->debug & L1_DEB_HSCX_FIFO)) { - char tmp[1024]; - char *t = tmp; - - t += sprintf(t, "amd7930_Bchan_rcv %c cnt %d", bcs->channel ? 'B' : 'A', len); - QuickHex(t, hw->rv_skb->tail, len); - debugl1(cs, tmp); - } - - if (len > HSCX_BUFMAX/2) { - /* Large packet received */ - - if (!(skb = dev_alloc_skb(HSCX_BUFMAX))) { - printk(KERN_WARNING "amd7930: receive out of memory"); - } else { - skb_put(hw->rv_skb, len); - skb_queue_tail(&bcs->rqueue, hw->rv_skb); - hw->rv_skb = skb; - bcs->event |= 1 << B_RCVBUFREADY; - schedule_work(&bcs->work); - } - } else if (len > 0) { - /* Small packet received */ - - if (!(skb = dev_alloc_skb(len))) { - printk(KERN_WARNING "amd7930: receive out of memory\n"); - } else { - memcpy(skb_put(skb, len), hw->rv_skb->tail, len); - skb_queue_tail(&bcs->rqueue, skb); - bcs->event |= 1 << B_RCVBUFREADY; - schedule_work(&bcs->work); - } - } else { - /* Reception Error */ - /* printk("amd7930: B channel receive error\n"); */ - } - } - } else if (bcs->mode == L1_MODE_TRANS) { - if (!(skb = dev_alloc_skb(RCV_BUFSIZE/RCV_BUFBLKS))) { - printk(KERN_WARNING "amd7930: receive out of memory\n"); - } else { - memcpy(skb_put(skb, RCV_BUFSIZE/RCV_BUFBLKS), - hw->rv_buff + hw->rv_buff_out, - RCV_BUFSIZE/RCV_BUFBLKS); - skb_queue_tail(&bcs->rqueue, skb); - bcs->event |= 1 << B_RCVBUFREADY; - schedule_work(&bcs->work); - } - } - - if (hw->rv_buff_in == hw->rv_buff_out) { - /* Buffer was filled up - need to restart receiver */ - amd7930_brecv(0, bcs->channel, - hw->rv_buff + hw->rv_buff_in, - RCV_BUFSIZE/RCV_BUFBLKS, - (void *) &Bchan_recv_callback, - (void *) bcs); - } - - hw->rv_buff_out += RCV_BUFSIZE/RCV_BUFBLKS; - hw->rv_buff_out %= RCV_BUFSIZE; - - } while (hw->rv_buff_in != hw->rv_buff_out); -} - -static void -Bchan_close(struct BCState *bcs) -{ - struct sk_buff *skb; - - Bchan_mode(bcs, 0, 0); - amd7930_bclose(0, bcs->channel); - - if (test_bit(BC_FLG_INIT, &bcs->Flag)) { - skb_queue_purge(&bcs->rqueue); - skb_queue_purge(&bcs->squeue); - } - test_and_clear_bit(BC_FLG_INIT, &bcs->Flag); -} - -static int -Bchan_open(struct BCState *bcs) -{ - struct amd7930_hw *hw = &bcs->hw.amd7930; - - if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) { - skb_queue_head_init(&bcs->rqueue); - skb_queue_head_init(&bcs->squeue); - } - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - - amd7930_bopen(0, bcs->channel, 0xff); - hw->rv_buff_in = 0; - hw->rv_buff_out = 0; - hw->tx_skb = NULL; - init_hdlc_state(hw->hdlc_state, 0); - amd7930_brecv(0, bcs->channel, - hw->rv_buff + hw->rv_buff_in, RCV_BUFSIZE/RCV_BUFBLKS, - (void *) &Bchan_recv_callback, (void *) bcs); - - bcs->event = 0; - bcs->tx_cnt = 0; - return (0); -} - -static void -Bchan_init(struct BCState *bcs) -{ - if (!(bcs->hw.amd7930.tx_buff = kmalloc(RAW_BUFMAX, GFP_ATOMIC))) { - printk(KERN_WARNING - "HiSax: No memory for amd7930.tx_buff\n"); - return; - } - if (!(bcs->hw.amd7930.rv_buff = kmalloc(RCV_BUFSIZE, GFP_ATOMIC))) { - printk(KERN_WARNING - "HiSax: No memory for amd7930.rv_buff\n"); - return; - } - if (!(bcs->hw.amd7930.rv_skb = dev_alloc_skb(HSCX_BUFMAX))) { - printk(KERN_WARNING - "HiSax: No memory for amd7930.rv_skb\n"); - return; - } - if (!(bcs->hw.amd7930.hdlc_state = kmalloc(sizeof(struct hdlc_state), - GFP_ATOMIC))) { - printk(KERN_WARNING - "HiSax: No memory for amd7930.hdlc_state\n"); - return; - } - - INIT_WORK(&bcs->hw.amd7930.rcv_work, &Bchan_rcv_bh, bcs); - INIT_WORK(&bcs->hw.amd7930.xmt_work, &Bchan_xmt_bh, bcs); -} - -static void -Bchan_manl1(struct PStack *st, int pr, - void *arg) -{ - switch (pr) { - case (PH_ACTIVATE_REQ): - test_and_set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag); - Bchan_mode(st->l1.bcs, st->l1.mode, st->l1.bc); - st->l1.l1man(st, PH_ACTIVATE_CNF, NULL); - break; - case (PH_DEACTIVATE_REQ): - if (!test_bit(BC_FLG_BUSY, &st->l1.bcs->Flag)) - Bchan_mode(st->l1.bcs, 0, 0); - test_and_clear_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag); - break; - } -} - -int -setstack_amd7930(struct PStack *st, struct BCState *bcs) -{ - if (Bchan_open(bcs)) - return (-1); - st->l1.bcs = bcs; - st->l2.l2l1 = Bchan_l2l1; - st->ma.manl1 = Bchan_manl1; - setstack_manager(st); - bcs->st = st; - return (0); -} - - -static void -amd7930_drecv_callback(void *arg, int error, unsigned int count) -{ - struct IsdnCardState *cs = (struct IsdnCardState *) arg; - static struct work_struct task; - struct sk_buff *skb; - - /* NOTE: This function is called directly from an interrupt handler */ - - if (1) { - if (!(skb = alloc_skb(count, GFP_ATOMIC))) - printk(KERN_WARNING "HiSax: D receive out of memory\n"); - else { - memcpy(skb_put(skb, count), cs->rcvbuf, count); - skb_queue_tail(&cs->rq, skb); - } - - INIT_WORK(&task, (void *) DChannel_proc_rcv, (void *) cs); - schedule_work(&task); - } - - if (cs->debug & L1_DEB_ISAC_FIFO) { - char tmp[128]; - char *t = tmp; - - t += sprintf(t, "amd7930 Drecv cnt %d", count); - if (error) t += sprintf(t, " ERR %x", error); - QuickHex(t, cs->rcvbuf, count); - debugl1(cs, tmp); - } - - amd7930_drecv(0, cs->rcvbuf, MAX_DFRAME_LEN, - &amd7930_drecv_callback, cs); -} - -static void -amd7930_dxmit_callback(void *arg, int error) -{ - struct IsdnCardState *cs = (struct IsdnCardState *) arg; - static struct work_struct task; - - /* NOTE: This function is called directly from an interrupt handler */ - - /* may wish to do retransmission here, if error indicates collision */ - - if (cs->debug & L1_DEB_ISAC_FIFO) { - char tmp[128]; - char *t = tmp; - - t += sprintf(t, "amd7930 Dxmit cnt %d", cs->tx_skb->len); - if (error) t += sprintf(t, " ERR %x", error); - QuickHex(t, cs->tx_skb->data, cs->tx_skb->len); - debugl1(cs, tmp); - } - - cs->tx_skb = NULL; - - INIT_WORK(&task, (void *) DChannel_proc_xmt, (void *) cs); - schedule_work(&task); -} - -static void -amd7930_Dchan_l2l1(struct PStack *st, int pr, void *arg) -{ - struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware; - struct sk_buff *skb = arg; - char str[64]; - - switch (pr) { - case (PH_DATA_REQ): - if (cs->tx_skb) { - skb_queue_tail(&cs->sq, skb); -#ifdef L2FRAME_DEBUG /* psa */ - if (cs->debug & L1_DEB_LAPD) - Logl2Frame(cs, skb, "PH_DATA Queued", 0); -#endif - } else { - if ((cs->dlogflag) && (!(skb->data[2] & 1))) { - /* I-FRAME */ - LogFrame(cs, skb->data, skb->len); - sprintf(str, "Q.931 frame user->network tei %d", st->l2.tei); - dlogframe(cs, skb->data+4, skb->len-4, - str); - } - cs->tx_skb = skb; - cs->tx_cnt = 0; -#ifdef L2FRAME_DEBUG /* psa */ - if (cs->debug & L1_DEB_LAPD) - Logl2Frame(cs, skb, "PH_DATA", 0); -#endif - amd7930_dxmit(0, skb->data, skb->len, - &amd7930_dxmit_callback, cs); - } - break; - case (PH_PULL_IND): - if (cs->tx_skb) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, " l2l1 tx_skb exist this shouldn't happen"); - skb_queue_tail(&cs->sq, skb); - break; - } - if ((cs->dlogflag) && (!(skb->data[2] & 1))) { /* I-FRAME */ - LogFrame(cs, skb->data, skb->len); - sprintf(str, "Q.931 frame user->network tei %d", st->l2.tei); - dlogframe(cs, skb->data + 4, skb->len - 4, - str); - } - cs->tx_skb = skb; - cs->tx_cnt = 0; -#ifdef L2FRAME_DEBUG /* psa */ - if (cs->debug & L1_DEB_LAPD) - Logl2Frame(cs, skb, "PH_DATA_PULLED", 0); -#endif - amd7930_dxmit(0, cs->tx_skb->data, cs->tx_skb->len, - &amd7930_dxmit_callback, cs); - break; - case (PH_PULL_REQ): -#ifdef L2FRAME_DEBUG /* psa */ - if (cs->debug & L1_DEB_LAPD) - debugl1(cs, "-> PH_REQUEST_PULL"); -#endif - if (!cs->tx_skb) { - test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - st->l1.l1l2(st, PH_PULL_CNF, NULL); - } else - test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - break; - } -} - -int -setDstack_amd7930(struct PStack *st, struct IsdnCardState *cs) -{ - st->l2.l2l1 = amd7930_Dchan_l2l1; - if (! cs->rcvbuf) { - printk("setDstack_amd7930: No cs->rcvbuf!\n"); - } else { - amd7930_drecv(0, cs->rcvbuf, MAX_DFRAME_LEN, - &amd7930_drecv_callback, cs); - } - return (0); -} - -static void -manl1_msg(struct IsdnCardState *cs, int msg, void *arg) { - struct PStack *st; - - st = cs->stlist; - while (st) { - st->ma.manl1(st, msg, arg); - st = st->next; - } -} - -static void -amd7930_new_ph(struct IsdnCardState *cs) -{ - switch (amd7930_get_liu_state(0)) { - case 3: - manl1_msg(cs, PH_POWERUP_CNF, NULL); - break; - - case 7: - manl1_msg(cs, PH_I4_P8_IND, NULL); - break; - - case 8: - manl1_msg(cs, PH_RSYNC_IND, NULL); - break; - } -} - -/* amd7930 LIU state change callback */ - -static void -amd7930_liu_callback(struct IsdnCardState *cs) -{ - static struct work_struct task; - - if (!cs) - return; - - if (cs->debug & L1_DEB_ISAC) { - char tmp[32]; - sprintf(tmp, "amd7930_liu state %d", amd7930_get_liu_state(0)); - debugl1(cs, tmp); - } - - INIT_WORK(&task, (void *) &amd7930_new_ph, (void *) cs); - schedule_work(&task); -} - -void -amd7930_l1cmd(struct IsdnCardState *cs, int msg, void *arg) -{ - u8 val; - char tmp[32]; - - if (cs->debug & L1_DEB_ISAC) { - char tmp[32]; - sprintf(tmp, "amd7930_l1cmd msg %x", msg); - debugl1(cs, tmp); - } - - switch(msg) { - case PH_RESET_REQ: - if (amd7930_get_liu_state(0) <= 3) - amd7930_liu_activate(0,0); - else - amd7930_liu_deactivate(0); - break; - case PH_ENABLE_REQ: - break; - case PH_INFO3_REQ: - amd7930_liu_activate(0,0); - break; - case PH_TESTLOOP_REQ: - break; - default: - if (cs->debug & L1_DEB_WARN) { - sprintf(tmp, "amd7930_l1cmd unknown %4x", msg); - debugl1(cs, tmp); - } - break; - } -} - -static void init_amd7930(struct IsdnCardState *cs) -{ - Bchan_init(&cs->bcs[0]); - Bchan_init(&cs->bcs[1]); - cs->bcs[0].BC_SetStack = setstack_amd7930; - cs->bcs[1].BC_SetStack = setstack_amd7930; - cs->bcs[0].BC_Close = Bchan_close; - cs->bcs[1].BC_Close = Bchan_close; - Bchan_mode(cs->bcs, 0, 0); - Bchan_mode(cs->bcs + 1, 0, 0); -} - -static int -amd7930_init(struct IsdnCardState *cs) -{ - 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) -{ - struct IsdnCardState *cs = card->cs; - char tmp[64]; - - strcpy(tmp, amd7930_revision); - printk(KERN_INFO "HiSax: AMD7930 driver Rev. %s\n", HiSax_getrev(tmp)); - - cs->irq = amd7930_get_irqnum(0); - if (cs->irq == 0) - return 0; - - cs->card_ops = &amd7930_ops; - return 1; -} diff -urN linux-2.5.64-bk3/drivers/isdn/hisax/asuscom.c linux-2.5.64-bk4/drivers/isdn/hisax/asuscom.c --- linux-2.5.64-bk3/drivers/isdn/hisax/asuscom.c Tue Mar 4 19:29:55 2003 +++ linux-2.5.64-bk4/drivers/isdn/hisax/asuscom.c Mon Mar 31 12:25:45 2003 @@ -231,6 +231,51 @@ .irq_func = ipac_irq, }; +static int __init +asuscom_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + int rc; + u8 val; + + printk(KERN_INFO "ISDNLink: defined at %#lx IRQ %lu\n", + card->para[1], card->para[0]); + + cs->hw.asus.cfg_reg = card->para[1]; + cs->irq = card->para[0]; + + rc = -EBUSY; + if (!request_io(&cs->rs, cs->hw.asus.cfg_reg, 8, "asuscom isdn")) + goto err; + + rc = -ENODEV; + 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; + if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops)) + goto err; + } else { + cs->subtyp = ASUS_ISACHSCX; + cs->card_ops = &asuscom_ops; + cs->hw.asus.adr = cs->hw.asus.cfg_reg + ASUS_ADR; + cs->hw.asus.isac = cs->hw.asus.cfg_reg + ASUS_ISAC; + 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; + if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) + goto err; + } + printk(KERN_INFO "ISDNLink: resetting card\n"); + cs->card_ops->reset(cs); + return 0; + + err: + hisax_release_resources(cs); + return rc; +} + #ifdef __ISAPNP__ static struct isapnp_device_id asus_ids[] __initdata = { { ISAPNP_VENDOR('A', 'S', 'U'), ISAPNP_FUNCTION(0x1688), @@ -255,9 +300,6 @@ int __init setup_asuscom(struct IsdnCard *card) { - int bytecnt; - struct IsdnCardState *cs = card->cs; - u8 val; char tmp[64]; strcpy(tmp, Asuscom_revision); @@ -310,36 +352,7 @@ } } #endif - bytecnt = 8; - cs->hw.asus.cfg_reg = card->para[1]; - cs->irq = card->para[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->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; - if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops)) - goto err; - } else { - cs->subtyp = ASUS_ISACHSCX; - cs->card_ops = &asuscom_ops; - cs->hw.asus.adr = cs->hw.asus.cfg_reg + ASUS_ADR; - cs->hw.asus.isac = cs->hw.asus.cfg_reg + ASUS_ISAC; - 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; - if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) - goto err; - } - printk(KERN_INFO "ISDNLink: resetting card\n"); - cs->card_ops->reset(cs); + if (asuscom_probe(card->cs, card) < 0) + return 0; return 1; - err: - hisax_release_resources(cs); - return 0; } diff -urN linux-2.5.64-bk3/drivers/isdn/hisax/avm_a1.c linux-2.5.64-bk4/drivers/isdn/hisax/avm_a1.c --- linux-2.5.64-bk3/drivers/isdn/hisax/avm_a1.c Tue Mar 4 19:28:58 2003 +++ linux-2.5.64-bk4/drivers/isdn/hisax/avm_a1.c Mon Mar 31 12:25:45 2003 @@ -160,16 +160,16 @@ .irq_func = avm_a1_interrupt, }; -int __init -setup_avm_a1(struct IsdnCard *card) +static int __init +avm_a1_probe(struct IsdnCardState *cs, struct IsdnCard *card) { + int rc; u8 val; - struct IsdnCardState *cs = card->cs; - char tmp[64]; - strcpy(tmp, avm_revision); - printk(KERN_INFO "HiSax: AVM driver Rev. %s\n", HiSax_getrev(tmp)); + printk(KERN_INFO "AVM A1: defined at %#lx IRQ %lu\n", + card->para[1], card->para[0]); + rc = -EBUSY; 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"); @@ -216,23 +216,24 @@ printk(KERN_INFO "AVM A1: Byte at %x is %x\n", cs->hw.avm.cfg_reg, val); - printk(KERN_INFO - "HiSax: %s config irq:%d cfg:0x%X\n", - CardType[cs->typ], cs->irq, - cs->hw.avm.cfg_reg); - printk(KERN_INFO - "HiSax: isac:0x%X/0x%X\n", - cs->hw.avm.isac + 32, cs->hw.avm.isacfifo); - printk(KERN_INFO - "HiSax: hscx A:0x%X/0x%X hscx B:0x%X/0x%X\n", - cs->hw.avm.hscx[0] + 32, cs->hw.avm.hscxfifo[0], - cs->hw.avm.hscx[1] + 32, cs->hw.avm.hscxfifo[1]); - cs->card_ops = &avm_a1_ops; if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) goto err; - return 1; + return 0; err: hisax_release_resources(cs); - return 0; + return rc; +} + +int __init +setup_avm_a1(struct IsdnCard *card) +{ + char tmp[64]; + + strcpy(tmp, avm_revision); + printk(KERN_INFO "HiSax: AVM driver Rev. %s\n", HiSax_getrev(tmp)); + + if (avm_a1_probe(card->cs, card) < 0) + return 0; + return 1; } diff -urN linux-2.5.64-bk3/drivers/isdn/hisax/avm_a1p.c linux-2.5.64-bk4/drivers/isdn/hisax/avm_a1p.c --- linux-2.5.64-bk3/drivers/isdn/hisax/avm_a1p.c Tue Mar 4 19:29:56 2003 +++ linux-2.5.64-bk4/drivers/isdn/hisax/avm_a1p.c Mon Mar 31 12:25:45 2003 @@ -215,20 +215,13 @@ .irq_func = avm_a1p_interrupt, }; -int __devinit -setup_avm_a1_pcmcia(struct IsdnCard *card) +static int __init +avm_a1p_probe(struct IsdnCardState *cs, struct IsdnCard *card) { u8 model, vers; - struct IsdnCardState *cs = card->cs; - char tmp[64]; - - strcpy(tmp, avm_revision); - printk(KERN_INFO "HiSax: AVM A1 PCMCIA driver Rev. %s\n", - HiSax_getrev(tmp)); - cs->hw.avm.cfg_reg = card->para[1]; cs->irq = card->para[0]; - + cs->hw.avm.cfg_reg = card->para[1]; outb(cs->hw.avm.cfg_reg+ASL1_OFFSET, ASL1_W_ENABLE_S0); @@ -244,11 +237,26 @@ vers = bytein(cs->hw.avm.cfg_reg+VERREG_OFFSET); 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->hw.avm.cfg_reg, cs->irq, model, vers); cs->card_ops = &avm_a1p_ops; if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) - return 0; + goto err; + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + +int __devinit +setup_avm_a1_pcmcia(struct IsdnCard *card) +{ + char tmp[64]; + strcpy(tmp, avm_revision); + printk(KERN_INFO "HiSax: AVM A1 PCMCIA driver Rev. %s\n", + HiSax_getrev(tmp)); + if (avm_a1p_probe(card->cs, card)) + return 0; return 1; } diff -urN linux-2.5.64-bk3/drivers/isdn/hisax/avm_pci.c linux-2.5.64-bk4/drivers/isdn/hisax/avm_pci.c --- linux-2.5.64-bk3/drivers/isdn/hisax/avm_pci.c Tue Mar 4 19:29:15 2003 +++ linux-2.5.64-bk4/drivers/isdn/hisax/avm_pci.c Mon Mar 31 12:25:45 2003 @@ -497,7 +497,7 @@ .close = close_hdlcstate, }; -void __init +static void __init inithdlc(struct IsdnCardState *cs) { u_int val; @@ -596,6 +596,82 @@ .irq_func = avm_pcipnp_interrupt, }; +static int __init +avm_pcipnp_hw_init(struct IsdnCardState *cs) +{ + cs->bc_hw_ops = &hdlc_hw_ops; + cs->bc_l1_ops = &hdlc_l1_ops; + cs->card_ops = &avm_pci_ops; + avm_pcipnp_reset(cs); + return isac_setup(cs, &isac_ops); +} + +static int __init +avm_pci_probe(struct IsdnCardState *cs, struct pci_dev *pdev) +{ + int rc; + u32 val; + + printk(KERN_INFO "AVM PCI: defined at %#lx IRQ %u\n", + pci_resource_start(pdev, 1), pdev->irq); + + rc = -EBUSY; + if (pci_enable_device(pdev)) + goto err; + + cs->subtyp = AVM_FRITZ_PCI; + cs->irq = pdev->irq; + cs->irq_flags |= SA_SHIRQ; + cs->hw.avm.cfg_reg = pci_resource_start(pdev, 1); + cs->hw.avm.isac = cs->hw.avm.cfg_reg + 0x10; + if (!request_io(&cs->rs, cs->hw.avm.cfg_reg, 32, "avm PCI")) + goto err; + + val = inl(cs->hw.avm.cfg_reg); + printk(KERN_INFO "AVM PCI: stat %#x\n", val); + printk(KERN_INFO "AVM PCI: Class %X Rev %d\n", + val & 0xff, (val>>8) & 0xff); + + if (avm_pcipnp_hw_init(cs)) + goto err; + + return 0; + err: + hisax_release_resources(cs); + return rc; +} + +static int __init +avm_pnp_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + int rc; + u8 val, ver; + + printk(KERN_INFO "AVM PnP: defined at %#lx IRQ %lu\n", + card->para[1], card->para[0]); + + cs->subtyp = AVM_FRITZ_PNP; + cs->irq = card->para[0]; + cs->hw.avm.cfg_reg = card->para[1]; + cs->hw.avm.isac = cs->hw.avm.cfg_reg + 0x10; + + rc = -EBUSY; + if (!request_io(&cs->rs, cs->hw.avm.cfg_reg, 32, "avm PnP")) + goto err; + + val = inb(cs->hw.avm.cfg_reg); + ver = inb(cs->hw.avm.cfg_reg + 1); + printk(KERN_INFO "AVM PnP: Class %X Rev %d\n", val, ver); + + if (avm_pcipnp_hw_init(cs)) + goto err; + + return 0; + err: + hisax_release_resources(cs); + return rc; +} + static struct pci_dev *dev_avm __initdata = NULL; #ifdef __ISAPNP__ static struct pnp_card *card_avm __initdata = NULL; @@ -605,17 +681,15 @@ int __init setup_avm_pcipnp(struct IsdnCard *card) { - u_int val, ver; - struct IsdnCardState *cs = card->cs; char tmp[64]; strcpy(tmp, avm_pci_rev); printk(KERN_INFO "HiSax: AVM PCI driver Rev. %s\n", HiSax_getrev(tmp)); if (card->para[1]) { /* old manual method */ - cs->hw.avm.cfg_reg = card->para[1]; - cs->irq = card->para[0]; - cs->subtyp = AVM_FRITZ_PNP; + if (avm_pnp_probe(card->cs, card)) + return 0; + return 1; } else { #ifdef __ISAPNP__ if (isapnp_present()) { @@ -647,69 +721,24 @@ pnp_device_detach(pnp_avm); return(0); } - cs->hw.avm.cfg_reg = pnp_port_start(pnp_avm, 0); - cs->irq = pnp_irq(pnp_avm, 0); - cs->subtyp = AVM_FRITZ_PNP; - goto ready; + card->para[1] = pnp_port_start(pnp_avm, 0); + card->para[0] = pnp_irq(pnp_avm, 0); + if (avm_pnp_probe(card->cs, card)) + return 0; + return 1; } } - } else { - printk(KERN_INFO "FritzPnP: no ISA PnP present\n"); } #endif #if CONFIG_PCI if ((dev_avm = pci_find_device(PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_A1, dev_avm))) { - cs->irq = dev_avm->irq; - if (!cs->irq) { - printk(KERN_ERR "FritzPCI: No IRQ for PCI card found\n"); - return(0); - } - if (pci_enable_device(dev_avm)) - return(0); - cs->hw.avm.cfg_reg = pci_resource_start(dev_avm, 1); - if (!cs->hw.avm.cfg_reg) { - printk(KERN_ERR "FritzPCI: No IO-Adr for PCI card found\n"); - return(0); - } - cs->subtyp = AVM_FRITZ_PCI; - } else { - printk(KERN_WARNING "FritzPCI: No PCI card found\n"); - return(0); + if (avm_pci_probe(card->cs, dev_avm)) + return 0; + return 1; } - cs->irq_flags |= SA_SHIRQ; #endif /* CONFIG_PCI */ } -ready: - cs->hw.avm.isac = cs->hw.avm.cfg_reg + 0x10; - 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); - printk(KERN_INFO "AVM PCI: stat %#x\n", val); - printk(KERN_INFO "AVM PCI: Class %X Rev %d\n", - val & 0xff, (val>>8) & 0xff); - break; - case AVM_FRITZ_PNP: - val = inb(cs->hw.avm.cfg_reg); - ver = inb(cs->hw.avm.cfg_reg + 1); - printk(KERN_INFO "AVM PnP: Class %X Rev %d\n", val, ver); - avm_pcipnp_reset(cs); - break; - } - printk(KERN_INFO "HiSax: %s config irq:%d base:0x%X\n", - (cs->subtyp == AVM_FRITZ_PCI) ? "AVM Fritz!PCI" : "AVM Fritz!PnP", - cs->irq, cs->hw.avm.cfg_reg); - - cs->bc_hw_ops = &hdlc_hw_ops; - cs->bc_l1_ops = &hdlc_l1_ops; - cs->card_ops = &avm_pci_ops; - isac_setup(cs, &isac_ops); - return 1; - err: - hisax_release_resources(cs); + printk(KERN_WARNING "FritzPCI: No card found\n"); return 0; } diff -urN linux-2.5.64-bk3/drivers/isdn/hisax/bkm_a4t.c linux-2.5.64-bk4/drivers/isdn/hisax/bkm_a4t.c --- linux-2.5.64-bk3/drivers/isdn/hisax/bkm_a4t.c Tue Mar 4 19:29:16 2003 +++ linux-2.5.64-bk4/drivers/isdn/hisax/bkm_a4t.c Mon Mar 31 12:25:45 2003 @@ -21,11 +21,11 @@ #include "bkm_ax.h" extern const char *CardType[]; +// FIXME needs per card lock static spinlock_t bkm_a4t_lock = SPIN_LOCK_UNLOCKED; const char *bkm_a4t_revision = "$Revision: 1.13.6.6 $"; - static inline u8 readreg(unsigned int ale, unsigned long adr, u8 off) { @@ -249,15 +249,57 @@ .irq_func = bkm_interrupt, }; +static int __init +bkm_a4t_probe(struct IsdnCardState *cs, struct pci_dev *pdev) +{ + I20_REGISTER_FILE *pI20_Regs; + int rc; + + printk(KERN_INFO "BKM A4T: defined at %#lx IRQ %u\n", + pci_resource_start(pdev, 0), pdev->irq); + + rc = -EBUSY; + if (pci_enable_device(pdev)) + goto err; + + cs->irq = pdev->irq; + cs->irq_flags |= SA_SHIRQ; + cs->hw.avm.cfg_reg = pci_resource_start(pdev, 1); + + cs->hw.ax.base = (unsigned long)request_mmio(&cs->rs, pci_resource_start(pdev, 0), 4096, "Telekom A4T"); + if (!cs->hw.ax.base) + goto err; + + /* Check suspicious address */ + // FIXME needs to use read[bl] + pI20_Regs = (I20_REGISTER_FILE *) (cs->hw.ax.base); + if ((pI20_Regs->i20IntStatus & 0x8EFFFFFF) != 0) { + printk(KERN_WARNING "HiSax: address %lx suspicious\n", + cs->hw.ax.base); + goto err; + } + 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; + + reset_bkm(cs); + cs->card_ops = &bkm_a4t_ops; + isac_setup(cs, &isac_ops); + jade_setup(cs, &jade_ops); + return 0; + + err: + hisax_release_resources(cs); + return rc; +} + static struct pci_dev *dev_a4t __initdata = NULL; int __init setup_bkm_a4t(struct IsdnCard *card) { - struct IsdnCardState *cs = card->cs; char tmp[64]; - u_int pci_memaddr = 0, found = 0; - I20_REGISTER_FILE *pI20_Regs; strcpy(tmp, bkm_a4t_revision); printk(KERN_INFO "HiSax: T-Berkom driver Rev. %s\n", HiSax_getrev(tmp)); @@ -268,49 +310,13 @@ sub_vendor = dev_a4t->subsystem_vendor; sub_sys = dev_a4t->subsystem_device; - if ((sub_sys == PCI_DEVICE_ID_BERKOM_A4T) && (sub_vendor == PCI_VENDOR_ID_BERKOM)) { - if (pci_enable_device(dev_a4t)) - return(0); - found = 1; - pci_memaddr = pci_resource_start(dev_a4t, 0); - cs->irq = dev_a4t->irq; - break; + if (sub_sys == PCI_DEVICE_ID_BERKOM_A4T && + sub_vendor == PCI_VENDOR_ID_BERKOM) { + if (bkm_a4t_probe(card->cs, dev_a4t)) + return 0; + return 1; } } - if (!found) { - printk(KERN_WARNING "HiSax: %s: Card not found\n", CardType[card->typ]); - return (0); - } - if (!cs->irq) { /* IRQ range check ?? */ - printk(KERN_WARNING "HiSax: %s: No IRQ\n", CardType[card->typ]); - return (0); - } - 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); - } - - /* 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); - 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; - - 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->irq_flags |= SA_SHIRQ; - cs->card_ops = &bkm_a4t_ops; - isac_setup(cs, &isac_ops); - jade_setup(cs, &jade_ops); - return 1; + printk(KERN_WARNING "HiSax: %s: Card not found\n", CardType[card->typ]); + return 0; } diff -urN linux-2.5.64-bk3/drivers/isdn/hisax/config.c linux-2.5.64-bk4/drivers/isdn/hisax/config.c --- linux-2.5.64-bk3/drivers/isdn/hisax/config.c Tue Mar 4 19:29:34 2003 +++ linux-2.5.64-bk4/drivers/isdn/hisax/config.c Mon Mar 31 12:25:45 2003 @@ -490,125 +490,36 @@ __setup("hisax=", HiSax_setup); #endif /* MODULES */ -#if CARD_TELES0 extern int setup_teles0(struct IsdnCard *card); -#endif - -#if CARD_TELES3 extern int setup_teles3(struct IsdnCard *card); -#endif - -#if CARD_S0BOX extern int setup_s0box(struct IsdnCard *card); -#endif - -#if CARD_TELESPCI extern int setup_telespci(struct IsdnCard *card); -#endif - -#if CARD_AVM_A1 extern int setup_avm_a1(struct IsdnCard *card); -#endif - -#if CARD_AVM_A1_PCMCIA extern int setup_avm_a1_pcmcia(struct IsdnCard *card); -#endif - -#if CARD_FRITZPCI extern int setup_avm_pcipnp(struct IsdnCard *card); -#endif - -#if CARD_ELSA extern int setup_elsa(struct IsdnCard *card); -#endif - -#if CARD_IX1MICROR2 extern int setup_ix1micro(struct IsdnCard *card); -#endif - -#if CARD_DIEHLDIVA extern int setup_diva(struct IsdnCard *card); -#endif - -#if CARD_ASUSCOM extern int setup_asuscom(struct IsdnCard *card); -#endif - -#if CARD_TELEINT extern int setup_TeleInt(struct IsdnCard *card); -#endif - -#if CARD_SEDLBAUER extern int setup_sedlbauer(struct IsdnCard *card); -#endif - -#if CARD_SPORTSTER extern int setup_sportster(struct IsdnCard *card); -#endif - -#if CARD_MIC extern int setup_mic(struct IsdnCard *card); -#endif - -#if CARD_NETJET_S extern int setup_netjet_s(struct IsdnCard *card); -#endif - -#if CARD_HFCS extern int setup_hfcs(struct IsdnCard *card); -#endif - -#if CARD_HFC_PCI extern int setup_hfcpci(struct IsdnCard *card); -#endif - -#if CARD_HFC_SX extern int setup_hfcsx(struct IsdnCard *card); -#endif - -#if CARD_AMD7930 extern int setup_amd7930(struct IsdnCard *card); -#endif - -#if CARD_NICCY extern int setup_niccy(struct IsdnCard *card); -#endif - -#if CARD_ISURF extern int setup_isurf(struct IsdnCard *card); -#endif - -#if CARD_HSTSAPHIR extern int setup_saphir(struct IsdnCard *card); -#endif - -#if CARD_TESTEMU extern int setup_testemu(struct IsdnCard *card); -#endif - -#if CARD_BKM_A4T extern int setup_bkm_a4t(struct IsdnCard *card); -#endif - -#if CARD_SCT_QUADRO extern int setup_sct_quadro(struct IsdnCard *card); -#endif - -#if CARD_GAZEL extern int setup_gazel(struct IsdnCard *card); -#endif - -#if CARD_W6692 extern int setup_w6692(struct IsdnCard *card); -#endif - -#if CARD_NETJET_U extern int setup_netjet_u(struct IsdnCard *card); -#endif - -#if CARD_FN_ENTERNOW_PCI extern int setup_enternow_pci(struct IsdnCard *card); -#endif /* * Find card with given driverId @@ -703,16 +614,16 @@ return 8; } -static u8 tmpbuf[HISAX_STATUS_BUFSIZE]; +static char tmpbuf[HISAX_STATUS_BUFSIZE]; -void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, +void VHiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, va_list args) { /* if head == NULL the fmt contains the full info */ unsigned long flags; int count, i; - u8 *p; + char *p; isdn_ctrl ic; int len; @@ -727,7 +638,7 @@ len = p - tmpbuf; p = tmpbuf; } else { - p = fmt; + p = (char *) fmt; len = strlen(fmt); } if (!cs) { @@ -814,12 +725,6 @@ ic.command = ISDN_STAT_UNLOAD; ic.driver = cs->myid; cs->iif.statcallb(&ic); - if (cs->status_buf) - kfree(cs->status_buf); - cs->status_read = NULL; - cs->status_write = NULL; - cs->status_end = NULL; - kfree(cs->dlog); } static void closecard(int cardnr) @@ -893,59 +798,97 @@ return 3; } +static struct IsdnCardState * +alloc_IsdnCardState(void) +{ + struct IsdnCardState *cs; + + cs = kmalloc(sizeof(*cs), GFP_ATOMIC); // FIXME + if (!cs) + goto err; + + memset(cs, 0, sizeof(*cs)); + + cs->dlog = kmalloc(MAX_DLOG_SPACE, GFP_ATOMIC); + if (!cs->dlog) + goto err_cs; + + cs->status_buf = kmalloc(HISAX_STATUS_BUFSIZE, GFP_ATOMIC); + if (!cs->status_buf) + goto err_dlog; + + cs->rcvbuf = kmalloc(MAX_DFRAME_LEN_L1, GFP_ATOMIC); + if (!cs->rcvbuf) + goto err_status_buf; + + cs->chanlimit = 2; /* maximum B-channel number */ + cs->debug = L1_DEB_WARN; + cs->irq_flags = I4L_IRQ_FLAG; + cs->stlist = NULL; + cs->status_read = cs->status_buf; + cs->status_write = cs->status_buf; + cs->status_end = cs->status_buf + HISAX_STATUS_BUFSIZE - 1; + cs->rcvidx = 0; + cs->tx_skb = NULL; + cs->tx_cnt = 0; + cs->event = 0; + + skb_queue_head_init(&cs->rq); + skb_queue_head_init(&cs->sq); + + spin_lock_init(&cs->lock); + resources_init(&cs->rs); + return cs; + + err_status_buf: + kfree(cs->status_buf); + err_dlog: + kfree(cs->dlog); + err_cs: + kfree(cs); + err: + return NULL; +} + +static void +free_IsdnCardState(struct IsdnCardState *cs) +{ + kfree(cs->rcvbuf); + kfree(cs->status_buf); + kfree(cs->dlog); + kfree(cs); +} + static int __devinit checkcard(int cardnr, char *id, int *busy_flag) { int ret = 0; struct IsdnCard *card = cards + cardnr; struct IsdnCardState *cs; - cs = kmalloc(sizeof(struct IsdnCardState), GFP_ATOMIC); + cs = alloc_IsdnCardState(); if (!cs) { printk(KERN_WARNING "HiSax: No memory for IsdnCardState(card %d)\n", cardnr + 1); goto out; } - memset(cs, 0, sizeof(struct IsdnCardState)); card->cs = cs; - cs->chanlimit = 2; /* maximum B-channel number */ - cs->logecho = 0; /* No echo logging */ - cs->cardnr = cardnr; - cs->debug = L1_DEB_WARN; - cs->HW_Flags = 0; - cs->busy_flag = busy_flag; - cs->irq_flags = I4L_IRQ_FLAG; #if TEI_PER_CARD if (card->protocol == ISDN_PTYPE_NI1) test_and_set_bit(FLG_TWO_DCHAN, &cs->HW_Flags); #else test_and_set_bit(FLG_TWO_DCHAN, &cs->HW_Flags); #endif + cs->cardnr = cardnr; cs->protocol = card->protocol; + cs->typ = card->typ; + cs->busy_flag = busy_flag; if (card->typ <= 0 || card->typ > ISDN_CTYPE_COUNT) { printk(KERN_WARNING "HiSax: Card Type %d out of range\n", card->typ); goto outf_cs; } - if (!(cs->dlog = kmalloc(MAX_DLOG_SPACE, GFP_ATOMIC))) { - printk(KERN_WARNING - "HiSax: No memory for dlog(card %d)\n", cardnr + 1); - goto outf_cs; - } - if (!(cs->status_buf = kmalloc(HISAX_STATUS_BUFSIZE, GFP_ATOMIC))) { - printk(KERN_WARNING - "HiSax: No memory for status_buf(card %d)\n", - cardnr + 1); - goto outf_dlog; - } - cs->stlist = NULL; - cs->status_read = cs->status_buf; - cs->status_write = cs->status_buf; - 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; @@ -982,13 +925,13 @@ (card->protocol == ISDN_PTYPE_NI1) ? "NI1" : "NONE", cs->iif.id, cs->myid); switch (card->typ) { -#if CARD_TELES0 +#ifdef CONFIG_HISAX_16_0 case ISDN_CTYPE_16_0: case ISDN_CTYPE_8_0: ret = setup_teles0(card); break; #endif -#if CARD_TELES3 +#ifdef CONFIG_HISAX_16_3 case ISDN_CTYPE_16_3: case ISDN_CTYPE_PNP: case ISDN_CTYPE_TELESPCMCIA: @@ -996,32 +939,32 @@ ret = setup_teles3(card); break; #endif -#if CARD_S0BOX +#ifdef CONFIG_HISAX_S0BOX case ISDN_CTYPE_S0BOX: ret = setup_s0box(card); break; #endif -#if CARD_TELESPCI +#ifdef CONFIG_HISAX_TELESPCI case ISDN_CTYPE_TELESPCI: ret = setup_telespci(card); break; #endif -#if CARD_AVM_A1 +#ifdef CONFIG_HISAX_AVM_A1 case ISDN_CTYPE_A1: ret = setup_avm_a1(card); break; #endif -#if CARD_AVM_A1_PCMCIA +#ifdef CONFIG_HISAX_AVM_A1_PCMCIA case ISDN_CTYPE_A1_PCMCIA: ret = setup_avm_a1_pcmcia(card); break; #endif -#if CARD_FRITZPCI +#ifdef CONFIG_HISAX_FRITZPCI case ISDN_CTYPE_FRITZPCI: ret = setup_avm_pcipnp(card); break; #endif -#if CARD_ELSA +#ifdef CONFIG_HISAX_ELSA case ISDN_CTYPE_ELSA: case ISDN_CTYPE_ELSA_PNP: case ISDN_CTYPE_ELSA_PCMCIA: @@ -1029,115 +972,115 @@ ret = setup_elsa(card); break; #endif -#if CARD_IX1MICROR2 +#ifdef CONFIG_HISAX_IX1MICROR2 case ISDN_CTYPE_IX1MICROR2: ret = setup_ix1micro(card); break; #endif -#if CARD_DIEHLDIVA +#ifdef CONFIG_HISAX_DIEHLDIVA case ISDN_CTYPE_DIEHLDIVA: ret = setup_diva(card); break; #endif -#if CARD_ASUSCOM +#ifdef CONFIG_HISAX_ASUSCOM case ISDN_CTYPE_ASUSCOM: ret = setup_asuscom(card); break; #endif -#if CARD_TELEINT +#ifdef CONFIG_HISAX_TELEINT case ISDN_CTYPE_TELEINT: ret = setup_TeleInt(card); break; #endif -#if CARD_SEDLBAUER +#ifdef CONFIG_HISAX_SEDLBAUER case ISDN_CTYPE_SEDLBAUER: case ISDN_CTYPE_SEDLBAUER_PCMCIA: case ISDN_CTYPE_SEDLBAUER_FAX: ret = setup_sedlbauer(card); break; #endif -#if CARD_SPORTSTER +#ifdef CONFIG_HISAX_SPORTSTER case ISDN_CTYPE_SPORTSTER: ret = setup_sportster(card); break; #endif -#if CARD_MIC +#ifdef CONFIG_HISAX_MIC case ISDN_CTYPE_MIC: ret = setup_mic(card); break; #endif -#if CARD_NETJET_S +#ifdef CONFIG_HISAX_NETJET case ISDN_CTYPE_NETJET_S: ret = setup_netjet_s(card); break; #endif -#if CARD_HFCS +#ifdef CONFIG_HISAX_HFCS case ISDN_CTYPE_TELES3C: case ISDN_CTYPE_ACERP10: ret = setup_hfcs(card); break; #endif -#if CARD_HFC_PCI +#ifdef CONFIG_HISAX_HFC_PCI case ISDN_CTYPE_HFC_PCI: ret = setup_hfcpci(card); break; #endif -#if CARD_HFC_SX +#ifdef CONFIG_HISAX_HFC_SX case ISDN_CTYPE_HFC_SX: ret = setup_hfcsx(card); break; #endif -#if CARD_NICCY +#ifdef CONFIG_HISAX_NICCY case ISDN_CTYPE_NICCY: ret = setup_niccy(card); break; #endif -#if CARD_AMD7930 +#ifdef CONFIG_HISAX_AMD7930 case ISDN_CTYPE_AMD7930: ret = setup_amd7930(card); break; #endif -#if CARD_ISURF +#ifdef CONFIG_HISAX_ISURF case ISDN_CTYPE_ISURF: ret = setup_isurf(card); break; #endif -#if CARD_HSTSAPHIR +#ifdef CONFIG_HISAX_HSTSAPHIR case ISDN_CTYPE_HSTSAPHIR: ret = setup_saphir(card); break; #endif -#if CARD_TESTEMU +#ifdef CONFIG_HISAX_TESTEMU case ISDN_CTYPE_TESTEMU: ret = setup_testemu(card); break; #endif -#if CARD_BKM_A4T +#ifdef CONFIG_HISAX_BKM_A4T case ISDN_CTYPE_BKM_A4T: ret = setup_bkm_a4t(card); break; #endif -#if CARD_SCT_QUADRO +#ifdef CONFIG_HISAX_SCT_QUADRO case ISDN_CTYPE_SCT_QUADRO: ret = setup_sct_quadro(card); break; #endif -#if CARD_GAZEL +#ifdef CONFIG_HISAX_GAZEL case ISDN_CTYPE_GAZEL: ret = setup_gazel(card); break; #endif -#if CARD_W6692 +#ifdef CONFIG_HISAX_W6692 case ISDN_CTYPE_W6692: ret = setup_w6692(card); break; #endif -#if CARD_NETJET_U +#ifdef CONFIG_HISAX_NETJET_U case ISDN_CTYPE_NETJET_U: ret = setup_netjet_u(card); break; #endif -#if CARD_FN_ENTERNOW_PCI +#ifdef CONFIG_HISAX_ENTERNOW_PCI case ISDN_CTYPE_ENTERNOW: ret = setup_enternow_pci(card); break; @@ -1156,19 +1099,6 @@ ll_unload(cs); goto outf_cs; } - if (!(cs->rcvbuf = kmalloc(MAX_DFRAME_LEN_L1, GFP_ATOMIC))) { - printk(KERN_WARNING "HiSax: No memory for isac rcvbuf\n"); - ll_unload(cs); - goto outf_cs; - } - cs->rcvidx = 0; - cs->tx_skb = NULL; - cs->tx_cnt = 0; - cs->event = 0; - - skb_queue_head_init(&cs->rq); - skb_queue_head_init(&cs->sq); - init_bcstate(cs, 0); init_bcstate(cs, 1); @@ -1201,10 +1131,8 @@ ret = 1; goto out; - outf_dlog: - kfree(cs->dlog); outf_cs: - kfree(cs); + free_IsdnCardState(cs); card->cs = NULL; out: return ret; @@ -1253,8 +1181,8 @@ i++; } else { printk(KERN_WARNING - "HiSax: Card %s not installed !\n", - CardType[cards[i].typ]); + "HiSax: Card type %d not installed !\n", + cards[i].typ); HiSax_shiftcards(i); nrcards--; } diff -urN linux-2.5.64-bk3/drivers/isdn/hisax/diva.c linux-2.5.64-bk4/drivers/isdn/hisax/diva.c --- linux-2.5.64-bk3/drivers/isdn/hisax/diva.c Tue Mar 4 19:29:51 2003 +++ linux-2.5.64-bk4/drivers/isdn/hisax/diva.c Mon Mar 31 12:25:45 2003 @@ -362,7 +362,7 @@ static void diva_release(struct IsdnCardState *cs) { - del_timer(&cs->hw.diva.tl); + del_timer_sync(&cs->hw.diva.tl); if (cs->hw.diva.cfg_reg) byteout(cs->hw.diva.ctrl, 0); /* LED off, Reset */ @@ -515,6 +515,162 @@ .irq_func = diva_ipacx_pci_irq, }; +static int __init +diva_ipac_probe(struct IsdnCardState *cs) +{ + u8 val; + + // request_io + val = readreg(cs->hw.diva.cfg_reg + DIVA_IPAC_ADR, + cs->hw.diva.cfg_reg + DIVA_IPAC_DATA, IPAC_ID); + printk(KERN_INFO "Diva: IPAC version %x\n", val); + return (val == 1 || val == 2); +} + +static int __init +diva_ipac_isa_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + cs->subtyp = DIVA_IPAC_ISA; + cs->irq = card->para[0]; + cs->hw.diva.cfg_reg = card->para[1]; + cs->hw.diva.isac = card->para[1] + DIVA_IPAC_DATA; + cs->hw.diva.isac_adr = card->para[1] + DIVA_IPAC_ADR; + printk(KERN_INFO "Diva: %s card configured at %#lx IRQ %d\n", + "IPAC ISA", cs->hw.diva.cfg_reg, cs->irq); + if (!request_io(&cs->rs, cs->hw.diva.cfg_reg, 8, "diva isdn")) + goto err; + diva_ipac_isa_reset(cs); + cs->card_ops = &diva_ipac_isa_ops; + if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops)) + goto err; + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + +static int __init +diva_isac_isa_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + cs->subtyp = DIVA_ISA; + cs->irq = card->para[0]; + cs->hw.diva.cfg_reg = card->para[1]; + cs->hw.diva.ctrl = card->para[1] + DIVA_ISA_CTRL; + cs->hw.diva.isac = card->para[1] + DIVA_ISA_ISAC_DATA; + cs->hw.diva.hscx = card->para[1] + DIVA_HSCX_DATA; + cs->hw.diva.isac_adr = card->para[1] + DIVA_ISA_ISAC_ADR; + cs->hw.diva.hscx_adr = card->para[1] + DIVA_HSCX_ADR; + printk(KERN_INFO "Diva: %s card configured at %#lx IRQ %d\n", + "ISA", cs->hw.diva.cfg_reg, cs->irq); + if (!request_io(&cs->rs, cs->hw.diva.cfg_reg, 8, "diva isdn")) + goto err; + diva_reset(cs); + init_timer(&cs->hw.diva.tl); + cs->hw.diva.tl.function = (void *) diva_led_handler; + cs->hw.diva.tl.data = (long) cs; + cs->card_ops = &diva_ops; + if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) + goto err; + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + +static int __init +diva_isa_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + int is_ipac; + cs->hw.diva.cfg_reg = card->para[1]; + if (!request_io(&cs->rs, cs->hw.diva.cfg_reg, 8, "diva isdn")) + return -EBUSY; + + is_ipac = diva_ipac_probe(cs); + hisax_release_resources(cs); + + if (is_ipac) + return diva_ipac_isa_probe(cs, card); + else + return diva_isac_isa_probe(cs, card); +} + +static int __init +diva_pci_probe(struct IsdnCardState *cs, struct pci_dev *pdev) +{ + if (pci_enable_device(pdev)) + goto err; + + cs->subtyp = DIVA_PCI; + cs->irq = pdev->irq; + cs->irq_flags |= SA_SHIRQ; + cs->hw.diva.cfg_reg = pci_resource_start(pdev, 2); + cs->hw.diva.ctrl = cs->hw.diva.cfg_reg + DIVA_PCI_CTRL; + cs->hw.diva.isac = cs->hw.diva.cfg_reg + DIVA_PCI_ISAC_DATA; + cs->hw.diva.hscx = cs->hw.diva.cfg_reg + DIVA_HSCX_DATA; + cs->hw.diva.isac_adr = cs->hw.diva.cfg_reg + DIVA_PCI_ISAC_ADR; + cs->hw.diva.hscx_adr = cs->hw.diva.cfg_reg + DIVA_HSCX_ADR; + printk(KERN_INFO "Diva: %s card configured at %#lx IRQ %d\n", + "PCI", cs->hw.diva.cfg_reg, cs->irq); + printk(KERN_INFO "Diva: %s space at %#lx\n", + "PCI", cs->hw.diva.pci_cfg); + if (!request_io(&cs->rs, cs->hw.diva.cfg_reg, 32, "diva isdn")) + goto err; + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + +static int __init +diva_ipac_pci_probe(struct IsdnCardState *cs, struct pci_dev *pdev) +{ + if (pci_enable_device(pdev)) + goto err; + + cs->subtyp = DIVA_IPAC_PCI; + cs->irq = pdev->irq; + cs->irq_flags |= SA_SHIRQ; + cs->hw.diva.pci_cfg = (unsigned long)request_mmio( + &cs->rs, pci_resource_start(pdev, 0), 4096, "diva"); + cs->hw.diva.cfg_reg = (unsigned long)request_mmio( + &cs->rs, pci_resource_start(pdev, 1), 4096, "diva"); + printk(KERN_INFO "Diva: %s card configured at %#lx IRQ %d\n", + "IPAC PCI", cs->hw.diva.cfg_reg, cs->irq); + printk(KERN_INFO "Diva: %s space at %#lx\n", + "IPAC PCI", cs->hw.diva.pci_cfg); + diva_ipac_pci_reset(cs); + cs->card_ops = &diva_ipac_pci_ops; + if (ipac_setup(cs, &mem_ipac_dc_ops, &mem_ipac_bc_ops)) + goto err; + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + +static int __init +diva_ipacx_pci_probe(struct IsdnCardState *cs, struct pci_dev *pdev) +{ + if (pci_enable_device(pdev)) + goto err; + + cs->subtyp = DIVA_IPACX_PCI; + cs->irq = pdev->irq; + cs->irq_flags |= SA_SHIRQ; + printk(KERN_INFO "Diva: %s card configured at %#lx IRQ %d\n", + "IPACX PCI", cs->hw.diva.cfg_reg, cs->irq); + printk(KERN_INFO "Diva: %s space at %#lx\n", + "IPACX PCI", cs->hw.diva.pci_cfg); + diva_ipacx_pci_reset(cs); + cs->card_ops = &diva_ipacx_pci_ops; + if (ipacx_setup(cs, &ipacx_dc_ops, &ipacx_bc_ops)) + goto err; + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + static struct pci_dev *dev_diva __initdata = NULL; static struct pci_dev *dev_diva_u __initdata = NULL; static struct pci_dev *dev_diva201 __initdata = NULL; @@ -545,101 +701,60 @@ static struct pnp_card *pnp_c __devinitdata = NULL; #endif - int __init setup_diva(struct IsdnCard *card) { - int bytecnt = 8; - u8 val; - struct IsdnCardState *cs = card->cs; char tmp[64]; strcpy(tmp, Diva_revision); printk(KERN_INFO "HiSax: Eicon.Diehl Diva driver Rev. %s\n", HiSax_getrev(tmp)); if (card->para[1]) { - cs->hw.diva.ctrl_reg = 0; - cs->hw.diva.cfg_reg = card->para[1]; - val = readreg(cs->hw.diva.cfg_reg + DIVA_IPAC_ADR, - cs->hw.diva.cfg_reg + DIVA_IPAC_DATA, IPAC_ID); - printk(KERN_INFO "Diva: IPAC version %x\n", val); - if ((val == 1) || (val==2)) { - cs->subtyp = DIVA_IPAC_ISA; - cs->hw.diva.ctrl = 0; - cs->hw.diva.isac = card->para[1] + DIVA_IPAC_DATA; - cs->hw.diva.hscx = card->para[1] + DIVA_IPAC_DATA; - cs->hw.diva.isac_adr = card->para[1] + DIVA_IPAC_ADR; - cs->hw.diva.hscx_adr = card->para[1] + DIVA_IPAC_ADR; - } else { - cs->subtyp = DIVA_ISA; - cs->hw.diva.ctrl = card->para[1] + DIVA_ISA_CTRL; - cs->hw.diva.isac = card->para[1] + DIVA_ISA_ISAC_DATA; - cs->hw.diva.hscx = card->para[1] + DIVA_HSCX_DATA; - cs->hw.diva.isac_adr = card->para[1] + DIVA_ISA_ISAC_ADR; - cs->hw.diva.hscx_adr = card->para[1] + DIVA_HSCX_ADR; - } - cs->irq = card->para[0]; - } else { + if (diva_isa_probe(card->cs, card) < 0) + return 0; + return 1; + + } #ifdef __ISAPNP__ - if (isapnp_present()) { - struct pnp_card *pb; - struct pnp_dev *pd; - - while(pdev->card_vendor) { - if ((pb = pnp_find_card(pdev->card_vendor, - pdev->card_device, - pnp_c))) { - pnp_c = pb; - pd = NULL; - if ((pd = pnp_find_dev(pnp_c, - pdev->vendor, - pdev->function, - pd))) { - printk(KERN_INFO "HiSax: %s detected\n", - (char *)pdev->driver_data); - if (pnp_device_attach(pd) < 0) { - printk(KERN_ERR "Diva PnP: attach failed\n"); + if (isapnp_present()) { + struct pnp_card *pb; + struct pnp_dev *pd; + + while(pdev->card_vendor) { + if ((pb = pnp_find_card(pdev->card_vendor, + pdev->card_device, pnp_c))) { + pnp_c = pb; + pd = NULL; + if ((pd = pnp_find_dev(pnp_c, + pdev->vendor, + pdev->function, + pd))) { + printk(KERN_INFO "HiSax: %s detected\n", + (char *)pdev->driver_data); + if (pnp_device_attach(pd) < 0) { + printk(KERN_ERR "Diva PnP: attach failed\n"); + return 0; + } + if (pnp_activate_dev(pd) < 0) { + printk(KERN_ERR "Diva PnP: activate failed\n"); + pnp_device_detach(pd); + return 0; + } + if (!pnp_irq_valid(pd, 0) || !pnp_port_valid(pd, 0)) { + printk(KERN_ERR "Diva PnP:some resources are missing %ld/%lx\n", + pnp_irq(pd, 0), pnp_port_start(pd, 0)); + pnp_device_detach(pd); + return(0); + } + card->para[1] = pnp_port_start(pd, 0); + card->para[0] = pnp_irq(pd, 0); + if (pdev->function == ISAPNP_FUNCTION(0xA1)) { + if (diva_ipac_isa_probe(cs->card, cs)) return 0; - } - if (pnp_activate_dev(pd) < 0) { - printk(KERN_ERR "Diva PnP: activate failed\n"); - pnp_device_detach(pd); + return 1; + } else { + if (diva_isac_isa_probe(cs->card, cs)) return 0; - } - if (!pnp_irq_valid(pd, 0) || !pnp_port_valid(pd, 0)) { - printk(KERN_ERR "Diva PnP:some resources are missing %ld/%lx\n", - pnp_irq(pd, 0), pnp_port_start(pd, 0)); - pnp_device_detach(pd); - return(0); - } - card->para[1] = pnp_port_start(pd, 0); - card->para[0] = pnp_irq(pd, 0); - cs->hw.diva.cfg_reg = card->para[1]; - cs->irq = card->para[0]; - if (pdev->function == ISAPNP_FUNCTION(0xA1)) { - cs->subtyp = DIVA_IPAC_ISA; - cs->hw.diva.ctrl = 0; - cs->hw.diva.isac = - card->para[1] + DIVA_IPAC_DATA; - cs->hw.diva.hscx = - card->para[1] + DIVA_IPAC_DATA; - cs->hw.diva.isac_adr = - card->para[1] + DIVA_IPAC_ADR; - cs->hw.diva.hscx_adr = - card->para[1] + DIVA_IPAC_ADR; - } else { - cs->subtyp = DIVA_ISA; - cs->hw.diva.ctrl = - card->para[1] + DIVA_ISA_CTRL; - cs->hw.diva.isac = - card->para[1] + DIVA_ISA_ISAC_DATA; - cs->hw.diva.hscx = - card->para[1] + DIVA_HSCX_DATA; - cs->hw.diva.isac_adr = - card->para[1] + DIVA_ISA_ISAC_ADR; - cs->hw.diva.hscx_adr = - card->para[1] + DIVA_HSCX_ADR; - } - goto ready; + return 1; } else { printk(KERN_ERR "Diva PnP: PnP error card found, no device\n"); return(0); @@ -652,111 +767,29 @@ printk(KERN_INFO "Diva PnP: no ISAPnP card found\n"); } } + } #endif #if CONFIG_PCI - cs->subtyp = 0; - if ((dev_diva = pci_find_device(PCI_VENDOR_ID_EICON, - PCI_DEVICE_ID_EICON_DIVA20, dev_diva))) { - if (pci_enable_device(dev_diva)) - return(0); - cs->subtyp = DIVA_PCI; - cs->irq = dev_diva->irq; - cs->hw.diva.cfg_reg = pci_resource_start(dev_diva, 2); - } else if ((dev_diva_u = pci_find_device(PCI_VENDOR_ID_EICON, - PCI_DEVICE_ID_EICON_DIVA20_U, dev_diva_u))) { - if (pci_enable_device(dev_diva_u)) - return(0); - cs->subtyp = DIVA_PCI; - cs->irq = dev_diva_u->irq; - cs->hw.diva.cfg_reg = pci_resource_start(dev_diva_u, 2); - } else if ((dev_diva201 = pci_find_device(PCI_VENDOR_ID_EICON, - PCI_DEVICE_ID_EICON_DIVA201, dev_diva201))) { - if (pci_enable_device(dev_diva201)) - return(0); - cs->subtyp = DIVA_IPAC_PCI; - cs->irq = dev_diva201->irq; - 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); - } - - if (!cs->irq) { - printk(KERN_WARNING "Diva: No IRQ for PCI card found\n"); - goto err; - } - - if (!cs->hw.diva.cfg_reg) { - printk(KERN_WARNING "Diva: No IO-Adr for PCI card found\n"); - goto err; - } - cs->irq_flags |= SA_SHIRQ; -#endif /* CONFIG_PCI */ - if ((cs->subtyp == DIVA_IPAC_PCI) || - (cs->subtyp == DIVA_IPACX_PCI) ) { - cs->hw.diva.ctrl = 0; - cs->hw.diva.isac = 0; - cs->hw.diva.hscx = 0; - cs->hw.diva.isac_adr = 0; - cs->hw.diva.hscx_adr = 0; - bytecnt = 0; - } else { - cs->hw.diva.ctrl = cs->hw.diva.cfg_reg + DIVA_PCI_CTRL; - cs->hw.diva.isac = cs->hw.diva.cfg_reg + DIVA_PCI_ISAC_DATA; - cs->hw.diva.hscx = cs->hw.diva.cfg_reg + DIVA_HSCX_DATA; - cs->hw.diva.isac_adr = cs->hw.diva.cfg_reg + DIVA_PCI_ISAC_ADR; - cs->hw.diva.hscx_adr = cs->hw.diva.cfg_reg + DIVA_HSCX_ADR; - bytecnt = 32; - } - } -ready: - printk(KERN_INFO - "Diva: %s card configured at %#lx IRQ %d\n", - (cs->subtyp == DIVA_PCI) ? "PCI" : - (cs->subtyp == DIVA_ISA) ? "ISA" : - (cs->subtyp == DIVA_IPAC_ISA) ? "IPAC ISA" : - (cs->subtyp == DIVA_IPAC_PCI) ? "IPAC PCI" : "IPACX PCI", - cs->hw.diva.cfg_reg, cs->irq); - if ((cs->subtyp == DIVA_IPAC_PCI) || - (cs->subtyp == DIVA_IPACX_PCI) || - (cs->subtyp == DIVA_PCI) ) - printk(KERN_INFO "Diva: %s space at %#lx\n", - (cs->subtyp == DIVA_PCI) ? "PCI" : - (cs->subtyp == DIVA_IPAC_PCI) ? "IPAC PCI" : "IPACX PCI", - cs->hw.diva.pci_cfg); - if ((cs->subtyp != DIVA_IPAC_PCI) && - (cs->subtyp != DIVA_IPACX_PCI) ) { - if (!request_io(&cs->rs, cs->hw.diva.cfg_reg, bytecnt, "diva isdn")) + if ((dev_diva = pci_find_device(PCI_VENDOR_ID_EICON, + PCI_DEVICE_ID_EICON_DIVA20, + dev_diva))) { + if (diva_pci_probe(card->cs, dev_diva)) return 0; + return 1; + } else if ((dev_diva_u = pci_find_device(PCI_VENDOR_ID_EICON, + PCI_DEVICE_ID_EICON_DIVA20_U, + dev_diva_u))) { + if (diva_pci_probe(card->cs, dev_diva_u)) + return 0; + return 1; + } else if ((dev_diva201 = pci_find_device(PCI_VENDOR_ID_EICON, + PCI_DEVICE_ID_EICON_DIVA201, + dev_diva201))) { + if (diva_ipac_pci_probe(card->cs, dev_diva201)) + return 0; + return 1; } - if (cs->subtyp == DIVA_IPAC_ISA) { - diva_ipac_isa_reset(cs); - cs->card_ops = &diva_ipac_isa_ops; - 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->card_ops = &diva_ipac_pci_ops; - 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->card_ops = &diva_ipacx_pci_ops; - 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->card_ops = &diva_ops; - if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) - goto err; - } - return 1; - err: - diva_release(cs); + printk(KERN_WARNING "Diva: No PCI card found\n"); +#endif /* CONFIG_PCI */ return 0; - } diff -urN linux-2.5.64-bk3/drivers/isdn/hisax/elsa.c linux-2.5.64-bk4/drivers/isdn/hisax/elsa.c --- linux-2.5.64-bk3/drivers/isdn/hisax/elsa.c Tue Mar 4 19:29:00 2003 +++ linux-2.5.64-bk4/drivers/isdn/hisax/elsa.c Mon Mar 31 12:25:45 2003 @@ -690,7 +690,47 @@ .irq_func = elsa_interrupt_ipac, }; -static unsigned char +static void __init +elsa_arcofi_init(struct IsdnCardState *cs) +{ +#if ARCOFI_USE + init_arcofi(cs); +#endif +} + +static void __init +elsa_timer_init(struct IsdnCardState *cs) +{ + cs->hw.elsa.tl.function = (void *) elsa_led_handler; + cs->hw.elsa.tl.data = (long) cs; + init_timer(&cs->hw.elsa.tl); +} + +static int __init +elsa_timer_test(struct IsdnCardState *cs) +{ + /* test timer */ + byteout(cs->hw.elsa.trig, 0xff); + byteout(cs->hw.elsa.timer, 0); + if (!TimerRun(cs)) { + byteout(cs->hw.elsa.timer, 0); /* second attempt */ + if (!TimerRun(cs)) { + printk(KERN_WARNING "Elsa: timer does not start\n"); + goto err; + } + } + HZDELAY(10 * HZ / 1000); /* wait >=10 ms */ + if (TimerRun(cs)) { + printk(KERN_WARNING "Elsa: timer does not run\n"); + goto err; + } + printk(KERN_INFO "Elsa: timer OK; resetting card\n"); + return 0; + err: + return -EBUSY; +} + +static unsigned char __init probe_elsa_adr(unsigned int adr, int typ) { int i, in1, in2, p16_1 = 0, p16_2 = 0, p8_1 = 0, p8_2 = 0, pc_1 = 0, @@ -699,15 +739,13 @@ /* In case of the elsa pcmcia card, this region is in use, reserved for us by the card manager. So we do not check it here, it would fail. */ - if (typ != ISDN_CTYPE_ELSA_PCMCIA && check_region(adr, 8)) { - printk(KERN_WARNING - "Elsa: Probing Port 0x%x: already in use\n", - adr); - return (0); + if (typ != ISDN_CTYPE_ELSA_PCMCIA && !request_region(adr, 8, "elsa")) { + printk(KERN_WARNING "Elsa: probing port 0x%x: in use\n", adr); + return 0; } for (i = 0; i < 16; i++) { - in1 = inb(adr + ELSA_CONFIG); /* 'toggelt' bei */ - in2 = inb(adr + ELSA_CONFIG); /* jedem Zugriff */ + in1 = inb(adr + ELSA_CONFIG); /* 'toggels' at */ + in2 = inb(adr + ELSA_CONFIG); /* each access */ p16_1 += 0x04 & in1; p16_2 += 0x04 & in2; p8_1 += 0x02 & in1; @@ -717,6 +755,7 @@ pfp_1 += 0x40 & in1; pfp_2 += 0x40 & in2; } + release_region(adr, 8); printk(KERN_INFO "Elsa: Probing IO 0x%x", adr); if (65 == ++p16_1 * ++p16_2) { printk(" PCC-16/PCF found\n"); @@ -736,18 +775,227 @@ } } -static unsigned int -probe_elsa(struct IsdnCardState *cs) +static int __init +elsa_probe(struct IsdnCardState *cs, struct IsdnCard *card) { - int i; - unsigned int CARD_portlist[] = - {0x160, 0x170, 0x260, 0x360, 0}; - - for (i = 0; CARD_portlist[i]; i++) { - if ((cs->subtyp = probe_elsa_adr(CARD_portlist[i], cs->typ))) + u8 val; + int i, bytecnt = 8; + unsigned int CARD_portlist[] = {0x160, 0x170, 0x260, 0x360, 0}; + + cs->hw.elsa.base = card->para[0]; + printk(KERN_INFO "Elsa: Microlink IO probing\n"); + if (cs->hw.elsa.base) { + cs->subtyp = probe_elsa_adr(cs->hw.elsa.base, cs->typ); + if (!cs->subtyp) { + printk(KERN_WARNING "Elsa: no Microlink at %#lx\n", + cs->hw.elsa.base); + goto err; + } + } else { + for (i = 0; CARD_portlist[i]; i++) { + cs->subtyp = probe_elsa_adr(CARD_portlist[i], cs->typ); + if (cs->subtyp) + cs->hw.elsa.base = CARD_portlist[i]; break; + } + } + if (!cs->hw.elsa.base) + goto err; + + cs->hw.elsa.cfg = cs->hw.elsa.base + ELSA_CONFIG; + cs->hw.elsa.ctrl = cs->hw.elsa.base + ELSA_CONTROL; + cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE; + cs->hw.elsa.isac = cs->hw.elsa.base + ELSA_ISAC; + cs->hw.elsa.itac = cs->hw.elsa.base + ELSA_ITAC; + cs->hw.elsa.hscx = cs->hw.elsa.base + ELSA_HSCX; + cs->hw.elsa.trig = cs->hw.elsa.base + ELSA_TRIG_IRQ; + cs->hw.elsa.timer = cs->hw.elsa.base + ELSA_START_TIMER; + val = bytein(cs->hw.elsa.cfg); + if (cs->subtyp == ELSA_PC) { + const u8 CARD_IrqTab[8] = {7, 3, 5, 9, 0, 0, 0, 0}; + cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX_PC) >> 2]; + } else if (cs->subtyp == ELSA_PCC8) { + const u8 CARD_IrqTab[8] = {7, 3, 5, 9, 0, 0, 0, 0}; + cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX_PCC8) >> 4]; + } else { + const u8 CARD_IrqTab[8] = {15, 10, 15, 3, 11, 5, 11, 9}; + cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX) >> 3]; + } + val = bytein(cs->hw.elsa.ale) & ELSA_HW_RELEASE; + if (val < 3) + val |= 8; + val += 'A' - 3; + if (val == 'B' || val == 'C') + val ^= 1; + if ((cs->subtyp == ELSA_PCFPRO) && (val = 'G')) + val = 'C'; + printk(KERN_INFO "Elsa: %s found at %#lx Rev.:%c IRQ %d\n", + Elsa_Types[cs->subtyp], cs->hw.elsa.base, val, cs->irq); + val = bytein(cs->hw.elsa.ale) & ELSA_S0_POWER_BAD; + if (val) { + printk(KERN_WARNING "Elsa: Microlink S0 bus power bad\n"); + cs->hw.elsa.status |= ELSA_BAD_PWR; + } + switch (cs->subtyp) { + case ELSA_PCFPRO: bytecnt = 16; break; + } + if (!request_io(&cs->rs, cs->hw.elsa.base, bytecnt, "elsa isdn")) + goto err; + elsa_arcofi_init(cs); + elsa_timer_init(cs); + if (elsa_timer_test(cs)) + goto err; + elsa_reset(cs); + cs->card_ops = &elsa_ops; + if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) + goto err; + if (cs->subtyp == ELSA_PC) { + val = readitac(cs, ITAC_SYS); + printk(KERN_INFO "Elsa: ITAC version %s\n", ITACVer[val & 7]); + writeitac(cs, ITAC_ISEN, 0); + writeitac(cs, ITAC_RFIE, 0); + writeitac(cs, ITAC_XFIE, 0); + writeitac(cs, ITAC_SCIE, 0); + writeitac(cs, ITAC_STIE, 0); + } + return 0; + err: + elsa_release(cs); + return -EBUSY; +} + +static int __init +elsa_qs_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + int bytecnt = 8; + + cs->irq = card->para[0]; + cs->hw.elsa.base = card->para[1]; + cs->hw.elsa.cfg = cs->hw.elsa.base + ELSA_CONFIG; + cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE; + cs->hw.elsa.isac = cs->hw.elsa.base + ELSA_ISAC; + cs->hw.elsa.hscx = cs->hw.elsa.base + ELSA_HSCX; + cs->hw.elsa.trig = cs->hw.elsa.base + ELSA_TRIG_IRQ; + cs->hw.elsa.timer = cs->hw.elsa.base + ELSA_START_TIMER; + cs->hw.elsa.ctrl = cs->hw.elsa.base + ELSA_CONTROL; + printk(KERN_INFO "Elsa: %s defined at %#lx IRQ %d\n", + Elsa_Types[cs->subtyp], cs->hw.elsa.base, cs->irq); + switch (cs->subtyp) { + case ELSA_QS3000: bytecnt = 16; break; + } + if (!request_io(&cs->rs, cs->hw.elsa.base, bytecnt, "elsa isdn")) + goto err; + elsa_arcofi_init(cs); + elsa_timer_init(cs); + if (elsa_timer_test(cs)) + goto err; + elsa_reset(cs); + cs->card_ops = &elsa_ops; + if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) + goto err; + return 0; + err: + elsa_release(cs); + return -EBUSY; +} + +static int __init +elsa_qs1000_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + cs->subtyp = ELSA_QS1000; + return elsa_qs_probe(cs, card); +} + +static int __init +elsa_qs3000_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + cs->subtyp = ELSA_QS3000; + return elsa_qs_probe(cs, card); +} + +static int __init +elsa_pcmcia_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + u8 val; + + cs->irq = card->para[0]; + cs->hw.elsa.base = card->para[1]; + cs->hw.elsa.ale = cs->hw.elsa.base + 0; + val = readreg(cs, cs->hw.elsa.base + 2, IPAC_ID); + if ((val == 1) || (val == 2)) { /* IPAC version 1.1/1.2 */ + cs->subtyp = ELSA_PCMCIA_IPAC; + cs->hw.elsa.isac = cs->hw.elsa.base + 2; + } else { + cs->subtyp = ELSA_PCMCIA; + cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE_PCM; + cs->hw.elsa.isac = cs->hw.elsa.base + ELSA_ISAC_PCM; + cs->hw.elsa.hscx = cs->hw.elsa.base + ELSA_HSCX; + } + cs->hw.elsa.timer = 0; + cs->hw.elsa.trig = 0; + cs->hw.elsa.ctrl = 0; + printk(KERN_INFO "Elsa: %s defined at %#lx IRQ %d\n", + Elsa_Types[cs->subtyp], cs->hw.elsa.base, cs->irq); + elsa_arcofi_init(cs); + elsa_reset(cs); + if (cs->subtyp == ELSA_PCMCIA_IPAC) { + cs->card_ops = &elsa_ipac_ops; + if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops)) + goto err; + } else { + cs->card_ops = &elsa_ops; + if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) + goto err; } - return (CARD_portlist[i]); + return 0; + err: + elsa_release(cs); + return -EBUSY; +} + +static int __init +elsa_qs_pci_probe(struct IsdnCardState *cs, struct pci_dev *pdev, + int subtyp) +{ + int bytecnt = 2; + u8 pci_rev; + + if (pci_enable_device(pdev)) + goto err; + + cs->subtyp = subtyp; + cs->irq = pdev->irq; + cs->irq_flags |= SA_SHIRQ; + cs->hw.elsa.cfg = pci_resource_start(pdev, 1); + cs->hw.elsa.base = pci_resource_start(pdev, 3); + pci_read_config_byte(pdev, PCI_REVISION_ID, &pci_rev); + if (cs->hw.elsa.cfg & 0x80 && pci_rev == 1) { + printk(KERN_INFO "Elsa: PLX9050 rev1 workaround activated\n"); + __set_bit(FLG_BUGGY_PLX9050, &cs->HW_Flags); + } + cs->hw.elsa.ale = cs->hw.elsa.base; + cs->hw.elsa.isac = cs->hw.elsa.base +1; + cs->hw.elsa.hscx = cs->hw.elsa.base +1; + printk(KERN_INFO "Elsa: %s defined at %#lx/%#x IRQ %d\n", + Elsa_Types[cs->subtyp], cs->hw.elsa.base, cs->hw.elsa.cfg, + cs->irq); + switch (cs->subtyp) { + case ELSA_QS3000PCI: bytecnt = 16; break; + } + if (!request_io(&cs->rs, cs->hw.elsa.base, bytecnt, "elsa isdn")) + goto err; + if (!request_io(&cs->rs, cs->hw.elsa.cfg, 0x80, "elsa isdn pci")) + goto err; + elsa_arcofi_init(cs); + elsa_timer_init(cs); + elsa_reset(cs); + cs->card_ops = &elsa_ipac_ops; + if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops)) + goto err; + return 0; + err: + elsa_release(cs); + return -EBUSY; } static struct pci_dev *dev_qs1000 __devinitdata = NULL; @@ -771,83 +1019,21 @@ int __devinit setup_elsa(struct IsdnCard *card) { - int bytecnt; - u8 val, pci_rev; - struct IsdnCardState *cs = card->cs; char tmp[64]; strcpy(tmp, Elsa_revision); printk(KERN_INFO "HiSax: Elsa driver Rev. %s\n", HiSax_getrev(tmp)); - cs->hw.elsa.ctrl_reg = 0; - cs->hw.elsa.status = 0; - cs->hw.elsa.MFlag = 0; - cs->subtyp = 0; - if (cs->typ == ISDN_CTYPE_ELSA) { - cs->hw.elsa.base = card->para[0]; - printk(KERN_INFO "Elsa: Microlink IO probing\n"); - if (cs->hw.elsa.base) { - if (!(cs->subtyp = probe_elsa_adr(cs->hw.elsa.base, - cs->typ))) { - printk(KERN_WARNING - "Elsa: no Elsa Microlink at %#lx\n", - cs->hw.elsa.base); - return (0); - } - } else - cs->hw.elsa.base = probe_elsa(cs); - if (cs->hw.elsa.base) { - cs->hw.elsa.cfg = cs->hw.elsa.base + ELSA_CONFIG; - cs->hw.elsa.ctrl = cs->hw.elsa.base + ELSA_CONTROL; - cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE; - cs->hw.elsa.isac = cs->hw.elsa.base + ELSA_ISAC; - cs->hw.elsa.itac = cs->hw.elsa.base + ELSA_ITAC; - cs->hw.elsa.hscx = cs->hw.elsa.base + ELSA_HSCX; - cs->hw.elsa.trig = cs->hw.elsa.base + ELSA_TRIG_IRQ; - cs->hw.elsa.timer = cs->hw.elsa.base + ELSA_START_TIMER; - val = bytein(cs->hw.elsa.cfg); - if (cs->subtyp == ELSA_PC) { - const u8 CARD_IrqTab[8] = - {7, 3, 5, 9, 0, 0, 0, 0}; - cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX_PC) >> 2]; - } else if (cs->subtyp == ELSA_PCC8) { - const u8 CARD_IrqTab[8] = - {7, 3, 5, 9, 0, 0, 0, 0}; - cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX_PCC8) >> 4]; - } else { - const u8 CARD_IrqTab[8] = - {15, 10, 15, 3, 11, 5, 11, 9}; - cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX) >> 3]; - } - val = bytein(cs->hw.elsa.ale) & ELSA_HW_RELEASE; - if (val < 3) - val |= 8; - val += 'A' - 3; - if (val == 'B' || val == 'C') - val ^= 1; - if ((cs->subtyp == ELSA_PCFPRO) && (val = 'G')) - val = 'C'; - printk(KERN_INFO - "Elsa: %s found at %#lx Rev.:%c IRQ %d\n", - Elsa_Types[cs->subtyp], - cs->hw.elsa.base, - val, cs->irq); - val = bytein(cs->hw.elsa.ale) & ELSA_S0_POWER_BAD; - if (val) { - printk(KERN_WARNING - "Elsa: Microlink S0 bus power bad\n"); - cs->hw.elsa.status |= ELSA_BAD_PWR; - } - } else { - printk(KERN_WARNING - "No Elsa Microlink found\n"); - return (0); - } - } else if (cs->typ == ISDN_CTYPE_ELSA_PNP) { + + if (card->typ == ISDN_CTYPE_ELSA) { + if (elsa_probe(card->cs, card)) + return 0; + return 1; + } else if (card->typ == ISDN_CTYPE_ELSA_PNP) { #ifdef __ISAPNP__ if (!card->para[1] && isapnp_present()) { struct pnp_card *pb; struct pnp_dev *pd; - + while(pdev->card_vendor) { if ((pb = pnp_find_card(pdev->card_vendor, pdev->card_device, @@ -878,10 +1064,15 @@ } card->para[1] = pnp_port_start(pd, 0); card->para[0] = pnp_irq(pd, 0); - if (pdev->function == ISAPNP_FUNCTION(0x133)) - cs->subtyp = ELSA_QS1000; - else - cs->subtyp = ELSA_QS3000; + if (pdev->function == ISAPNP_FUNCTION(0x133)) { + if (elsa_qs1000_probe(card->cs, card)) + return 0; + return 1; + } else { + if (elsa_qs3000_probe(card->cs, card)) + return 0; + return 1; + } break; } else { printk(KERN_ERR "Elsa PnP: PnP error card found, no device\n"); @@ -897,184 +1088,33 @@ } } #endif - if (card->para[1] && card->para[0]) { - cs->hw.elsa.base = card->para[1]; - cs->irq = card->para[0]; - if (!cs->subtyp) - cs->subtyp = ELSA_QS1000; - } else { - printk(KERN_ERR "Elsa PnP: no parameter\n"); - } - cs->hw.elsa.cfg = cs->hw.elsa.base + ELSA_CONFIG; - cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE; - cs->hw.elsa.isac = cs->hw.elsa.base + ELSA_ISAC; - cs->hw.elsa.hscx = cs->hw.elsa.base + ELSA_HSCX; - cs->hw.elsa.trig = cs->hw.elsa.base + ELSA_TRIG_IRQ; - cs->hw.elsa.timer = cs->hw.elsa.base + ELSA_START_TIMER; - cs->hw.elsa.ctrl = cs->hw.elsa.base + ELSA_CONTROL; - printk(KERN_INFO - "Elsa: %s defined at %#lx IRQ %d\n", - Elsa_Types[cs->subtyp], - cs->hw.elsa.base, - cs->irq); - } else if (cs->typ == ISDN_CTYPE_ELSA_PCMCIA) { - cs->hw.elsa.base = card->para[1]; - cs->irq = card->para[0]; - cs->hw.elsa.ale = cs->hw.elsa.base + 0; - val = readreg(cs, cs->hw.elsa.base + 2, IPAC_ID); - if ((val == 1) || (val == 2)) { /* IPAC version 1.1/1.2 */ - cs->subtyp = ELSA_PCMCIA_IPAC; - cs->hw.elsa.isac = cs->hw.elsa.base + 2; - cs->hw.elsa.hscx = cs->hw.elsa.base + 2; - } else { - cs->subtyp = ELSA_PCMCIA; - cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE_PCM; - cs->hw.elsa.isac = cs->hw.elsa.base + ELSA_ISAC_PCM; - cs->hw.elsa.hscx = cs->hw.elsa.base + ELSA_HSCX; - } - cs->hw.elsa.timer = 0; - cs->hw.elsa.trig = 0; - cs->hw.elsa.ctrl = 0; - printk(KERN_INFO - "Elsa: %s defined at %#lx IRQ %d\n", - Elsa_Types[cs->subtyp], - cs->hw.elsa.base, - cs->irq); - } else if (cs->typ == ISDN_CTYPE_ELSA_PCI) { + if (elsa_qs1000_probe(card->cs, card)) + return 0; + return 1; + + } else if (card->typ == ISDN_CTYPE_ELSA_PCMCIA) { + if (elsa_pcmcia_probe(card->cs, card)) + return 0; + return 1; + } else if (card->typ == ISDN_CTYPE_ELSA_PCI) { #if CONFIG_PCI - cs->subtyp = 0; if ((dev_qs1000 = pci_find_device(PCI_VENDOR_ID_ELSA, PCI_DEVICE_ID_ELSA_MICROLINK, dev_qs1000))) { - if (pci_enable_device(dev_qs1000)) - return(0); - cs->subtyp = ELSA_QS1000PCI; - cs->irq = dev_qs1000->irq; - cs->hw.elsa.cfg = pci_resource_start(dev_qs1000, 1); - cs->hw.elsa.base = pci_resource_start(dev_qs1000, 3); - pci_read_config_byte(dev_qs1000, PCI_REVISION_ID, &pci_rev); + if (elsa_qs_pci_probe(card->cs, dev_qs1000, + ELSA_QS1000PCI)) + return 0; + return 1; } else if ((dev_qs3000 = pci_find_device(PCI_VENDOR_ID_ELSA, PCI_DEVICE_ID_ELSA_QS3000, dev_qs3000))) { - if (pci_enable_device(dev_qs3000)) - return(0); - cs->subtyp = ELSA_QS3000PCI; - cs->irq = dev_qs3000->irq; - cs->hw.elsa.cfg = pci_resource_start(dev_qs3000, 1); - cs->hw.elsa.base = pci_resource_start(dev_qs3000, 3); - pci_read_config_byte(dev_qs1000, PCI_REVISION_ID, &pci_rev); + if (elsa_qs_pci_probe(card->cs, dev_qs3000, + ELSA_QS3000PCI)) + return 0; + return 1; } else { printk(KERN_WARNING "Elsa: No PCI card found\n"); - return(0); + return 0; } - if (!cs->irq) { - printk(KERN_WARNING "Elsa: No IRQ for PCI card found\n"); - return(0); - } - - if (!(cs->hw.elsa.base && cs->hw.elsa.cfg)) { - printk(KERN_WARNING "Elsa: No IO-Adr for PCI card found\n"); - return(0); - } - if (cs->hw.elsa.cfg & 0x80 && pci_rev == 1) { - printk(KERN_INFO "Elsa: PLX9050 rev1 workaround activated\n"); - set_bit(FLG_BUGGY_PLX9050, &cs->HW_Flags); - } - cs->hw.elsa.ale = cs->hw.elsa.base; - cs->hw.elsa.isac = cs->hw.elsa.base +1; - cs->hw.elsa.hscx = cs->hw.elsa.base +1; - cs->hw.elsa.timer = 0; - cs->hw.elsa.trig = 0; - cs->irq_flags |= SA_SHIRQ; - printk(KERN_INFO - "Elsa: %s defined at %#lx/0x%x IRQ %d\n", - Elsa_Types[cs->subtyp], - cs->hw.elsa.base, - cs->hw.elsa.cfg, - cs->irq); #endif /* CONFIG_PCI */ - } else - return (0); - - switch (cs->subtyp) { - case ELSA_PC: - case ELSA_PCC8: - case ELSA_PCC16: - case ELSA_QS1000: - case ELSA_PCMCIA: - case ELSA_PCMCIA_IPAC: - bytecnt = 8; - break; - case ELSA_PCFPRO: - case ELSA_PCF: - case ELSA_QS3000: - case ELSA_QS3000PCI: - bytecnt = 16; - break; - case ELSA_QS1000PCI: - bytecnt = 2; - break; - default: - printk(KERN_WARNING - "Unknown ELSA subtype %d\n", cs->subtyp); - return (0); } - /* In case of the elsa pcmcia card, this region is in use, - 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_io(&cs->rs, cs->hw.elsa.base, bytecnt, "elsa isdn")) - goto err; - - 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); - /* Teste Timer */ - if (cs->hw.elsa.timer) { - byteout(cs->hw.elsa.trig, 0xff); - byteout(cs->hw.elsa.timer, 0); - if (!TimerRun(cs)) { - byteout(cs->hw.elsa.timer, 0); /* 2. Versuch */ - if (!TimerRun(cs)) { - printk(KERN_WARNING - "Elsa: timer do not start\n"); - goto err; - } - } - HZDELAY(1); /* wait >=10 ms */ - if (TimerRun(cs)) { - printk(KERN_WARNING "Elsa: timer do not run down\n"); - goto err; - } - printk(KERN_INFO "Elsa: timer OK; resetting card\n"); - } - elsa_reset(cs); - if ((cs->subtyp == ELSA_QS1000PCI) || (cs->subtyp == ELSA_QS3000PCI) || (cs->subtyp == ELSA_PCMCIA_IPAC)) { - cs->card_ops = &elsa_ipac_ops; - if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops)) - goto err; - } else { - cs->card_ops = &elsa_ops; - if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) - goto err; - } - if (cs->subtyp == ELSA_PC) { - val = readitac(cs, ITAC_SYS); - printk(KERN_INFO "Elsa: ITAC version %s\n", ITACVer[val & 7]); - writeitac(cs, ITAC_ISEN, 0); - writeitac(cs, ITAC_RFIE, 0); - writeitac(cs, ITAC_XFIE, 0); - writeitac(cs, ITAC_SCIE, 0); - writeitac(cs, ITAC_STIE, 0); - } - return 1; - err: - elsa_release(cs); return 0; } diff -urN linux-2.5.64-bk3/drivers/isdn/hisax/enternow_pci.c linux-2.5.64-bk4/drivers/isdn/hisax/enternow_pci.c --- linux-2.5.64-bk3/drivers/isdn/hisax/enternow_pci.c Tue Mar 4 19:29:32 2003 +++ linux-2.5.64-bk4/drivers/isdn/hisax/enternow_pci.c Mon Mar 31 12:25:45 2003 @@ -263,13 +263,65 @@ .irq_func = enpci_interrupt, }; +static int __init +enpci_probe(struct IsdnCardState *cs, struct pci_dev *pdev) +{ + if (pci_enable_device(pdev)) + goto err; + + cs->irq = pdev->irq; + cs->irq_flags |= SA_SHIRQ; + cs->hw.njet.base = pci_resource_start(pdev, 0); + if (!request_io(&cs->rs, cs->hw.njet.base, 0x100, "Fn_ISDN")) + goto err; + + cs->hw.njet.auxa = cs->hw.njet.base + NETJET_AUXDATA; + cs->hw.njet.isac = cs->hw.njet.base + 0xC0; // Fenster zum AMD + + /* Reset an */ + cs->hw.njet.ctrl_reg = 0x07; // geändert von 0xff + OutByte(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); + + set_current_state(TASK_UNINTERRUPTIBLE); + /* 50 ms Pause */ + schedule_timeout((50*HZ)/1000); + + cs->hw.njet.ctrl_reg = 0x30; /* Reset Off and status read clear */ + OutByte(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); + + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout((10*HZ)/1000); /* Timeout 10ms */ + + cs->hw.njet.auxd = 0x00; // war 0xc0 + cs->hw.njet.dmactrl = 0; + + OutByte(cs->hw.njet.base + NETJET_AUXCTRL, ~TJ_AMD_IRQ); + OutByte(cs->hw.njet.base + NETJET_IRQMASK1, TJ_AMD_IRQ); + OutByte(cs->hw.njet.auxa, cs->hw.njet.auxd); + + printk(KERN_INFO + "enter:now PCI: PCI card configured at 0x%lx IRQ %d\n", + cs->hw.njet.base, cs->irq); + reset_enpci(cs); + cs->hw.njet.last_is0 = 0; + cs->hw.njet.bc_activate = enpci_bc_activate; + cs->hw.njet.bc_deactivate = enpci_bc_deactivate; + amd7930_setup(cs, &amd7930_ops, &enpci_setIrqMask); + + cs->card_ops = &enpci_ops; + + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + static struct pci_dev *dev_netjet __initdata = NULL; /* called by config.c */ int __init setup_enternow_pci(struct IsdnCard *card) { - struct IsdnCardState *cs = card->cs; char tmp[64]; #ifdef __BIG_ENDIAN @@ -278,72 +330,22 @@ strcpy(tmp, enternow_pci_rev); printk(KERN_INFO "HiSax: Formula-n Europe AG enter:now ISDN PCI driver Rev. %s\n", HiSax_getrev(tmp)); - for ( ;; ) { - if ((dev_netjet = pci_find_device(PCI_VENDOR_ID_TIGERJET, - PCI_DEVICE_ID_TIGERJET_300, dev_netjet))) { - if (pci_enable_device(dev_netjet)) - return(0); - cs->irq = dev_netjet->irq; - if (!cs->irq) { - printk(KERN_WARNING "enter:now PCI: No IRQ for PCI card found\n"); - return(0); - } - cs->hw.njet.base = pci_resource_start(dev_netjet, 0); - if (!cs->hw.njet.base) { - printk(KERN_WARNING "enter:now PCI: No IO-Adr for PCI card found\n"); - return(0); - } - /* checks Sub-Vendor ID because system crashes with Traverse-Card */ - if ((dev_netjet->subsystem_vendor != 0x55) || - (dev_netjet->subsystem_device != 0x02)) { - printk(KERN_WARNING "enter:now: You tried to load this driver with an incompatible TigerJet-card\n"); - printk(KERN_WARNING "Use type=20 for Traverse NetJet PCI Card.\n"); - return(0); - } - } else { - printk(KERN_WARNING "enter:now PCI: No PCI card found\n"); - return(0); + dev_netjet = pci_find_device(PCI_VENDOR_ID_TIGERJET, + PCI_DEVICE_ID_TIGERJET_300, dev_netjet); + if (dev_netjet) { + if (dev_netjet->subsystem_vendor != 0x55 || + dev_netjet->subsystem_device != 0x02) { + printk(KERN_WARNING "enter:now: You tried to load " + "this driver with an incompatible " + "TigerJet-card\n"); + printk(KERN_WARNING "Use type=20 for Traverse " + "NetJet PCI Card.\n"); + return 0; } - - cs->hw.njet.auxa = cs->hw.njet.base + NETJET_AUXDATA; - cs->hw.njet.isac = cs->hw.njet.base + 0xC0; // Fenster zum AMD - - /* Reset an */ - cs->hw.njet.ctrl_reg = 0x07; // geändert von 0xff - OutByte(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); - - set_current_state(TASK_UNINTERRUPTIBLE); - /* 50 ms Pause */ - schedule_timeout((50*HZ)/1000); - - cs->hw.njet.ctrl_reg = 0x30; /* Reset Off and status read clear */ - OutByte(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); - - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout((10*HZ)/1000); /* Timeout 10ms */ - - cs->hw.njet.auxd = 0x00; // war 0xc0 - cs->hw.njet.dmactrl = 0; - - OutByte(cs->hw.njet.base + NETJET_AUXCTRL, ~TJ_AMD_IRQ); - OutByte(cs->hw.njet.base + NETJET_IRQMASK1, TJ_AMD_IRQ); - OutByte(cs->hw.njet.auxa, cs->hw.njet.auxd); - - break; - } - printk(KERN_INFO - "enter:now PCI: PCI card configured at 0x%lx IRQ %d\n", - cs->hw.njet.base, cs->irq); - if (!request_io(&cs->rs, cs->hw.njet.base, 0x100, "Fn_ISDN")) + if (enpci_probe(card->cs, dev_netjet)) + return 1; return 0; - reset_enpci(cs); - cs->hw.njet.last_is0 = 0; - cs->hw.njet.bc_activate = enpci_bc_activate; - cs->hw.njet.bc_deactivate = enpci_bc_deactivate; - amd7930_setup(cs, &amd7930_ops, &enpci_setIrqMask); - - cs->irq_flags |= SA_SHIRQ; - cs->card_ops = &enpci_ops; - - return 1; + } + printk(KERN_WARNING "enter:now PCI: No PCI card found\n"); + return 0; } diff -urN linux-2.5.64-bk3/drivers/isdn/hisax/gazel.c linux-2.5.64-bk4/drivers/isdn/hisax/gazel.c --- linux-2.5.64-bk3/drivers/isdn/hisax/gazel.c Tue Mar 4 19:29:20 2003 +++ linux-2.5.64-bk4/drivers/isdn/hisax/gazel.c Mon Mar 31 12:25:45 2003 @@ -294,60 +294,6 @@ inithscxisac(cs); } -static int -r647_reserve_regions(struct IsdnCardState *cs) -{ - int i, base = cs->hw.gazel.hscx[0]; - - 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; - err: - hisax_release_resources(cs); - return -EBUSY; -} - -static int -r685_reserve_regions(struct IsdnCardState *cs) -{ - 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; - err: - hisax_release_resources(cs); - return -EBUSY; -} - -static int -r742_reserve_regions(struct IsdnCardState *cs) -{ - if (!request_io(&cs->rs, cs->hw.gazel.ipac, 0x8, "gazel")) - goto err; - return 0; - err: - hisax_release_resources(cs); - return -EBUSY; -} - -static int -r753_reserve_regions(struct IsdnCardState *cs) -{ - 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; - err: - hisax_release_resources(cs); - return -EBUSY; -} - static struct card_ops r647_ops = { .init = gazel_init, .reset = r647_reset, @@ -377,194 +323,213 @@ }; static int __init -setup_gazelisa(struct IsdnCard *card, struct IsdnCardState *cs) +gazel647_probe(struct IsdnCardState *cs, struct IsdnCard *card) { - printk(KERN_INFO "Gazel: ISA PnP card automatic recognition\n"); - // we got an irq parameter, assume it is an ISA card - // R742 decodes address even in not started... - // R647 returns FF if not present or not started - // eventually needs improvment - cs->hw.gazel.ipac = card->para[1]; - if (ipac_read(cs, IPAC_ID) == 1) - cs->subtyp = R742; - else - cs->subtyp = R647; + int i, base; + cs->subtyp = R647; + cs->irq = card->para[0]; cs->hw.gazel.cfg_reg = card->para[1] + 0xC000; + + printk(KERN_INFO "Gazel: Card ISA R647/R648 found\n"); + cs->dc.isac.adf2 = 0x87; + printk(KERN_INFO "Gazel: config irq:%d isac:0x%X cfg:0x%X\n", + cs->irq, cs->hw.gazel.isac, cs->hw.gazel.cfg_reg); + printk(KERN_INFO + "Gazel: hscx A:0x%X hscx B:0x%X\n", + cs->hw.gazel.hscx[0], cs->hw.gazel.hscx[1]); + cs->hw.gazel.isac = card->para[1] + 0x8000; cs->hw.gazel.hscx[0] = card->para[1]; cs->hw.gazel.hscx[1] = card->para[1] + 0x4000; - cs->irq = card->para[0]; cs->hw.gazel.isacfifo = cs->hw.gazel.isac; cs->hw.gazel.hscxfifo[0] = cs->hw.gazel.hscx[0]; cs->hw.gazel.hscxfifo[1] = cs->hw.gazel.hscx[1]; - switch (cs->subtyp) { - case R647: - printk(KERN_INFO "Gazel: Card ISA R647/R648 found\n"); - cs->dc.isac.adf2 = 0x87; - printk(KERN_INFO - "Gazel: config irq:%d isac:0x%X cfg:0x%X\n", - cs->irq, cs->hw.gazel.isac, cs->hw.gazel.cfg_reg); - printk(KERN_INFO - "Gazel: hscx A:0x%X hscx B:0x%X\n", - cs->hw.gazel.hscx[0], cs->hw.gazel.hscx[1]); - - return r647_reserve_regions(cs); - case R742: - printk(KERN_INFO "Gazel: Card ISA R742 found\n"); - printk(KERN_INFO - "Gazel: config irq:%d ipac:0x%X\n", - cs->irq, cs->hw.gazel.ipac); - return r742_reserve_regions(cs); + base = cs->hw.gazel.hscx[0]; + for (i = 0; i < 0xc000; i += 0x1000) { + if (!request_io(&cs->rs, base + i, 16, "gazel")) + goto err; } + if (!request_io(&cs->rs, 0xc000 + base, 1, "gazel")) + goto err; + + cs->card_ops = &r647_ops; + if (hscxisac_setup(cs, &r647_isac_ops, &r647_hscx_ops)) + goto err; + + cs->card_ops->reset(cs); return 0; + err: + hisax_release_resources(cs); + return -EBUSY; } -static struct pci_dev *dev_tel __initdata = NULL; - static int __init -setup_gazelpci(struct IsdnCardState *cs) +gazel742_probe(struct IsdnCardState *cs, struct IsdnCard *card) { - u_int pci_ioaddr0 = 0, pci_ioaddr1 = 0; - u8 pci_irq = 0, found; - u_int nbseek, seekcard; - u8 pci_rev; + cs->subtyp = R742; + cs->irq = card->para[0]; + cs->hw.gazel.cfg_reg = card->para[1] + 0xC000; - printk(KERN_WARNING "Gazel: PCI card automatic recognition\n"); + printk(KERN_INFO "Gazel: Card ISA R742 found\n"); + printk(KERN_INFO "Gazel: config irq:%d ipac:0x%X\n", + cs->irq, cs->hw.gazel.ipac); - found = 0; - if (!pci_present()) { - printk(KERN_WARNING "Gazel: No PCI bus present\n"); - return 1; - } - seekcard = PCI_DEVICE_ID_PLX_R685; - for (nbseek = 0; nbseek < 3; nbseek++) { - if ((dev_tel = pci_find_device(PCI_VENDOR_ID_PLX, seekcard, dev_tel))) { - if (pci_enable_device(dev_tel)) - return 1; - pci_irq = dev_tel->irq; - pci_ioaddr0 = pci_resource_start(dev_tel, 1); - pci_ioaddr1 = pci_resource_start(dev_tel, 2); - found = 1; - } - if (found) - break; - else { - switch (seekcard) { - case PCI_DEVICE_ID_PLX_R685: - seekcard = PCI_DEVICE_ID_PLX_R753; - break; - case PCI_DEVICE_ID_PLX_R753: - seekcard = PCI_DEVICE_ID_PLX_DJINN_ITOO; - break; - } - } - } - if (!found) { - printk(KERN_WARNING "Gazel: No PCI card found\n"); - return -ENODEV; - } - if (!pci_irq) { - printk(KERN_WARNING "Gazel: No IRQ for PCI card found\n"); - return -ENODEV; - } - cs->hw.gazel.pciaddr[0] = pci_ioaddr0; - cs->hw.gazel.pciaddr[1] = pci_ioaddr1; + if (!request_io(&cs->rs, cs->hw.gazel.ipac, 0x8, "gazel")) + goto err; - pci_ioaddr1 &= 0xfffe; - cs->hw.gazel.cfg_reg = pci_ioaddr0 & 0xfffe; - cs->hw.gazel.ipac = pci_ioaddr1; - cs->hw.gazel.isac = pci_ioaddr1 + 0x80; - cs->hw.gazel.hscx[0] = pci_ioaddr1; - cs->hw.gazel.hscx[1] = pci_ioaddr1 + 0x40; - cs->hw.gazel.isacfifo = cs->hw.gazel.isac; + cs->card_ops = &r742_ops; + if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops)) + goto err; + + cs->card_ops->reset(cs); + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + +static int __init +gazel685_probe(struct IsdnCardState *cs, struct pci_dev *pdev) +{ + if (pci_enable_device(pdev)) + goto err; + + cs->subtyp = R685; + cs->irq = pdev->irq; + cs->irq_flags |= SA_SHIRQ; + cs->hw.gazel.cfg_reg = pci_resource_start(pdev, 1); + cs->hw.gazel.isac = pci_resource_start(pdev, 2) + 0x80; + cs->hw.gazel.hscx[0] = pci_resource_start(pdev, 2); + cs->hw.gazel.hscx[1] = pci_resource_start(pdev, 2) + 0x40; + cs->hw.gazel.isacfifo = cs->hw.gazel.isac; cs->hw.gazel.hscxfifo[0] = cs->hw.gazel.hscx[0]; cs->hw.gazel.hscxfifo[1] = cs->hw.gazel.hscx[1]; - cs->irq = pci_irq; - cs->irq_flags |= SA_SHIRQ; + cs->dc.isac.adf2 = 0x87; - switch (seekcard) { - case PCI_DEVICE_ID_PLX_R685: - printk(KERN_INFO "Gazel: Card PCI R685 found\n"); - cs->subtyp = R685; - cs->dc.isac.adf2 = 0x87; - printk(KERN_INFO - "Gazel: config irq:%d isac:0x%X cfg:0x%X\n", - cs->irq, cs->hw.gazel.isac, cs->hw.gazel.cfg_reg); - printk(KERN_INFO - "Gazel: hscx A:0x%X hscx B:0x%X\n", - cs->hw.gazel.hscx[0], cs->hw.gazel.hscx[1]); - return r685_reserve_regions(cs); - case PCI_DEVICE_ID_PLX_R753: - case PCI_DEVICE_ID_PLX_DJINN_ITOO: - printk(KERN_INFO "Gazel: Card PCI R753 found\n"); - cs->subtyp = R753; - printk(KERN_INFO - "Gazel: config irq:%d ipac:0x%X cfg:0x%X\n", - cs->irq, cs->hw.gazel.ipac, cs->hw.gazel.cfg_reg); - /* - * Erratum for PLX9050, revision 1: - * If bit 7 of BAR 0/1 is set, local config registers - * can not be read (write is okay) - */ - if (cs->hw.gazel.cfg_reg & 0x80) { - pci_read_config_byte(dev_tel, PCI_REVISION_ID, &pci_rev); - if (pci_rev == 1) { - printk(KERN_INFO "Gazel: PLX9050 rev1 workaround activated\n"); - set_bit(FLG_BUGGY_PLX9050, &cs->HW_Flags); - } + 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; + + printk(KERN_INFO "Gazel: Card PCI R685 found\n"); + printk(KERN_INFO "Gazel: config irq:%d isac:0x%X cfg:0x%X\n", + cs->irq, cs->hw.gazel.isac, cs->hw.gazel.cfg_reg); + printk(KERN_INFO "Gazel: hscx A:0x%X hscx B:0x%X\n", + cs->hw.gazel.hscx[0], cs->hw.gazel.hscx[1]); + + cs->card_ops = &r685_ops; + if (hscxisac_setup(cs, &r685_isac_ops, &r685_hscx_ops)) + goto err; + + cs->card_ops->reset(cs); + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + +static int __init +gazel753_probe(struct IsdnCardState *cs, struct pci_dev *pdev) +{ + u8 pci_rev; + + if (pci_enable_device(pdev)) + goto err; + + cs->subtyp = R753; + cs->irq = pdev->irq; + cs->irq_flags |= SA_SHIRQ; + cs->hw.gazel.cfg_reg = pci_resource_start(pdev, 1); + cs->hw.gazel.ipac = pci_resource_start(pdev, 2); + + 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; + + printk(KERN_INFO "Gazel: Card PCI R753 found\n"); + printk(KERN_INFO "Gazel: config irq:%d ipac:0x%X cfg:0x%X\n", + cs->irq, cs->hw.gazel.ipac, cs->hw.gazel.cfg_reg); + /* + * Erratum for PLX9050, revision 1: + * If bit 7 of BAR 0/1 is set, local config registers + * can not be read (write is okay) + */ + if (cs->hw.gazel.cfg_reg & 0x80) { + pci_read_config_byte(pdev, PCI_REVISION_ID, &pci_rev); + if (pci_rev == 1) { + printk(KERN_INFO "Gazel: PLX9050 rev1 workaround " + "activated\n"); + __set_bit(FLG_BUGGY_PLX9050, &cs->HW_Flags); } - return r753_reserve_regions(cs); } + cs->card_ops = &r753_ops; + if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops)) + goto err; + + cs->card_ops->reset(cs); return 0; + err: + hisax_release_resources(cs); + return -EBUSY; } +static struct pci_dev *dev_tel __initdata = NULL; +static u16 __initdata dev_id = PCI_DEVICE_ID_PLX_R685; + int __init setup_gazel(struct IsdnCard *card) { - struct IsdnCardState *cs = card->cs; char tmp[64]; strcpy(tmp, gazel_revision); printk(KERN_INFO "Gazel: Driver Revision %s\n", HiSax_getrev(tmp)); if (card->para[0]) { - if (setup_gazelisa(card, cs)) - return (0); - } else { - if (setup_gazelpci(cs)) - return (0); + printk(KERN_INFO "Gazel: ISA card automatic recognition\n"); + // we got an irq parameter, assume it is an ISA card + // R742 decodes address even in not started... + // R647 returns FF if not present or not started + // eventually needs improvment + card->cs->hw.gazel.ipac = card->para[1]; + if (ipac_read(card->cs, IPAC_ID) == 1) { + if (gazel742_probe(card->cs, card)) + return 0; + } else { + if (gazel647_probe(card->cs, card)) + return 0; + } + return 1; } - switch (cs->subtyp) { - case R647: - case R685: - if (cs->subtyp == R647) { - cs->card_ops = &r647_ops; - if (hscxisac_setup(cs, &r647_isac_ops, &r647_hscx_ops)) - goto err; - } else { - cs->card_ops = &r685_ops; - if (hscxisac_setup(cs, &r685_isac_ops, &r685_hscx_ops)) - goto err; + for (;;) { + dev_tel = pci_find_device(PCI_VENDOR_ID_PLX, dev_id, dev_tel); + if (dev_tel) { + switch (dev_id) { + case PCI_DEVICE_ID_PLX_R685: + if (gazel685_probe(card->cs, dev_tel)) + return 0; + return 1; + case PCI_DEVICE_ID_PLX_R753: + case PCI_DEVICE_ID_PLX_DJINN_ITOO: + if (gazel753_probe(card->cs, dev_tel)) + return 0; + return 1; + } } - cs->card_ops->reset(cs); - break; - case R742: - case R753: - if (cs->subtyp == R742) { - cs->card_ops = &r742_ops; - } else { - cs->card_ops = &r753_ops; + switch (dev_id) { + case PCI_DEVICE_ID_PLX_R685: + dev_id = PCI_DEVICE_ID_PLX_R753; + case PCI_DEVICE_ID_PLX_R753: + dev_id = PCI_DEVICE_ID_PLX_DJINN_ITOO; + default: + break; } - if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops)) - goto err; - cs->card_ops->reset(cs); - break; } - return 1; - err: - hisax_release_resources(cs); + printk(KERN_WARNING "Gazel: No PCI card found\n"); return 0; } + + diff -urN linux-2.5.64-bk3/drivers/isdn/hisax/hfc_pci.c linux-2.5.64-bk4/drivers/isdn/hisax/hfc_pci.c --- linux-2.5.64-bk3/drivers/isdn/hisax/hfc_pci.c Tue Mar 4 19:29:17 2003 +++ linux-2.5.64-bk4/drivers/isdn/hisax/hfc_pci.c Mon Mar 31 12:25:45 2003 @@ -1382,72 +1382,41 @@ }; -/* this variable is used as card index when more than one cards are present */ -static struct pci_dev *dev_hfcpci __initdata = NULL; - -int __init -setup_hfcpci(struct IsdnCard *card) +static int __init +niccy_pci_probe(struct IsdnCardState *cs, struct pci_dev *pdev, int i) { - struct IsdnCardState *cs = card->cs; - char tmp[64]; - int i; - struct pci_dev *tmp_hfcpci = NULL; + int rc; - strcpy(tmp, hfcpci_revision); - printk(KERN_INFO "HiSax: HFC-PCI driver Rev. %s\n", HiSax_getrev(tmp)); - cs->hw.hfcpci.int_s1 = 0; - cs->dc.hfcpci.ph_state = 0; - cs->hw.hfcpci.fifo = 255; + rc = -EBUSY; + if (pci_enable_device(pdev)) + goto err; - 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; - } - } + pci_set_master(pdev); + + cs->irq = pdev->irq; + cs->irq_flags |= SA_SHIRQ; + cs->hw.hfcpci.pdev = pdev; + + cs->hw.hfcpci.pci_io = request_mmio(&cs->rs, + pci_resource_start(pdev, 1), 128, + "hfc_pci"); + if (!cs->hw.hfcpci.pci_io) + goto err; - 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); - } - 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; - } + rc = -ENOMEM; + cs->hw.hfcpci.fifos = pci_alloc_consistent(pdev, 32768, + &cs->hw.hfcpci.fifos_dma); + if (!cs->hw.hfcpci.fifos) + goto err; + 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(KERN_INFO "HiSax: HFC-PCI card manufacturer: %s name: %s\n", + id_list[i].vendor_name, id_list[i].card_name); + printk(KERN_INFO "HFC-PCI: defined at mem %#x fifo %#x(%#x) IRQ %d\n", + (u_int) cs->hw.hfcpci.pci_io, (u_int) cs->hw.hfcpci.fifos, + (u_int) cs->hw.hfcpci.fifos_dma, cs->irq); 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; @@ -1456,17 +1425,46 @@ /* At this point the needed PCI config is done */ /* fifos are still not enabled */ - cs->irq_flags |= SA_SHIRQ; - + init_timer(&cs->hw.hfcpci.timer); cs->hw.hfcpci.timer.function = (void *) hfcpci_Timer; cs->hw.hfcpci.timer.data = (long) cs; - init_timer(&cs->hw.hfcpci.timer); hfcpci_reset(cs); cs->auxcmd = &hfcpci_auxcmd; cs->card_ops = &hfcpci_ops; - return 1; + return 0; err: hisax_release_resources(cs); + return -EBUSY; +} + +/* this variable is used as card index when more than one cards are present */ +static struct pci_dev *dev_hfcpci __initdata = NULL; + +int __init +setup_hfcpci(struct IsdnCard *card) +{ + struct IsdnCardState *cs = card->cs; + char tmp[64]; + int i; + struct pci_dev *tmp_hfcpci = NULL; + + strcpy(tmp, hfcpci_revision); + printk(KERN_INFO "HiSax: HFC-PCI driver Rev. %s\n", HiSax_getrev(tmp)); + cs->hw.hfcpci.int_s1 = 0; + cs->dc.hfcpci.ph_state = 0; + cs->hw.hfcpci.fifo = 255; + + for (i = 0; id_list[i].vendor_id; i++) { + tmp_hfcpci = pci_find_device(id_list[i].vendor_id, + id_list[i].device_id, + dev_hfcpci); + if (!tmp_hfcpci) + continue; + + if (niccy_pci_probe(card->cs, tmp_hfcpci, i) < 0) + return 0; + return 1; + } return 0; } diff -urN linux-2.5.64-bk3/drivers/isdn/hisax/hfc_sx.c linux-2.5.64-bk4/drivers/isdn/hisax/hfc_sx.c --- linux-2.5.64-bk3/drivers/isdn/hisax/hfc_sx.c Tue Mar 4 19:28:58 2003 +++ linux-2.5.64-bk4/drivers/isdn/hisax/hfc_sx.c Mon Mar 31 12:25:45 2003 @@ -1159,6 +1159,74 @@ .irq_func = hfcsx_interrupt, }; +static int __init +hfcsx_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + int rc; + char c; + + cs->irq = card->para[0]; + cs->hw.hfcsx.base = card->para[1] & 0xfffe; + + cs->hw.hfcsx.fifo = 255; + cs->hw.hfcsx.int_s1 = 0; + cs->dc.hfcsx.ph_state = 0; + + rc = -EBUSY; + if (!request_io(&cs->rs, cs->hw.hfcsx.base, 2, "HFCSX isdn")) + goto err; + + rc = -ENODEV; + 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: + c ='+'; + break; + case 9: + c ='P'; + break; + default: + printk(KERN_WARNING "HFC-SX: invalid chip id 0x%x\n", + cs->hw.hfcsx.chip >> 4); + goto err; + } + if (!ccd_sp_irqtab[cs->irq & 0xF]) { + printk(KERN_WARNING "HFC_SX: invalid irq %d specified\n", + cs->irq & 0xF); + goto err; + } + rc = -ENOMEM; + cs->hw.hfcsx.extra = kmalloc(sizeof(struct hfcsx_extra), GFP_ATOMIC); + if (!cs->hw.hfcsx.extra) { + printk(KERN_WARNING "HFC-SX: unable to allocate memory\n"); + goto err; + } + printk(KERN_INFO "HFC-S%c chip detected at base 0x%x IRQ %d\n", + c, (u_int) cs->hw.hfcsx.base, cs->irq); + + 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); + + init_timer(&cs->hw.hfcsx.timer); + cs->hw.hfcsx.timer.function = (void *) hfcsx_Timer; + cs->hw.hfcsx.timer.data = (long) cs; + cs->hw.hfcsx.b_fifo_size = 0; /* fifo size still unknown */ + cs->hw.hfcsx.cirm = ccd_sp_irqtab[cs->irq & 0xF]; /* RAM not eval. */ + + hfcsx_reset(cs); + cs->auxcmd = &hfcsx_auxcmd; + cs->card_ops = &hfcsx_ops; + return 0; + err: + hisax_release_resources(cs); + return rc; +} + #ifdef __ISAPNP__ static struct isapnp_device_id hfc_ids[] __initdata = { { ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x2620), @@ -1174,7 +1242,6 @@ int __devinit setup_hfcsx(struct IsdnCard *card) { - struct IsdnCardState *cs = card->cs; char tmp[64]; strcpy(tmp, hfcsx_revision); @@ -1227,62 +1294,7 @@ } } #endif - cs->hw.hfcsx.base = card->para[1] & 0xfffe; - cs->irq = card->para[0]; - cs->hw.hfcsx.int_s1 = 0; - cs->dc.hfcsx.ph_state = 0; - cs->hw.hfcsx.fifo = 255; - - 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); + if (hfcsx_probe(card->cs, card) < 0) 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; - cs->hw.hfcsx.b_fifo_size = 0; /* fifo size still unknown */ - cs->hw.hfcsx.cirm = ccd_sp_irqtab[cs->irq & 0xF]; /* RAM not evaluated */ - init_timer(&cs->hw.hfcsx.timer); - - hfcsx_reset(cs); - cs->auxcmd = &hfcsx_auxcmd; - cs->card_ops = &hfcsx_ops; return 1; } diff -urN linux-2.5.64-bk3/drivers/isdn/hisax/hfcscard.c linux-2.5.64-bk4/drivers/isdn/hisax/hfcscard.c --- linux-2.5.64-bk3/drivers/isdn/hisax/hfcscard.c Tue Mar 4 19:29:51 2003 +++ linux-2.5.64-bk4/drivers/isdn/hisax/hfcscard.c Mon Mar 31 12:25:45 2003 @@ -133,6 +133,50 @@ .irq_func = hfcs_interrupt, }; +static int __init +hfcs_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + cs->irq = card->para[0]; + cs->hw.hfcD.addr = card->para[1]; + + if (!request_io(&cs->rs, cs->hw.hfcD.addr, 2, "HFCS isdn")) + goto err; + + printk(KERN_INFO "HFCS: defined at 0x%x IRQ %d\n", + cs->hw.hfcD.addr, cs->irq); + + cs->hw.hfcD.cip = 0; + cs->hw.hfcD.int_s1 = 0; + cs->hw.hfcD.send = NULL; + cs->bcs[0].hw.hfc.send = NULL; + cs->bcs[1].hw.hfc.send = NULL; + cs->hw.hfcD.dfifosize = 512; + cs->dc.hfcd.ph_state = 0; + cs->hw.hfcD.fifo = 255; + + if (cs->typ == ISDN_CTYPE_TELES3C) { + cs->hw.hfcD.bfifosize = 1024 + 512; + /* Teles 16.3c IO ADR is 0x200 | YY0U (YY Bit 15/14 address) */ + outb(0x00, cs->hw.hfcD.addr); + outb(0x56, cs->hw.hfcD.addr | 1); + } else if (cs->typ == ISDN_CTYPE_ACERP10) { + cs->hw.hfcD.bfifosize = 7*1024 + 512; + /* Acer P10 IO ADR is 0x300 */ + outb(0x00, cs->hw.hfcD.addr); + outb(0x57, cs->hw.hfcD.addr | 1); + } + set_cs_func(cs); + init_timer(&cs->hw.hfcD.timer); + cs->hw.hfcD.timer.function = (void *) hfcs_Timer; + cs->hw.hfcD.timer.data = (long) cs; + hfcs_reset(cs); + cs->card_ops = &hfcs_ops; + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + #ifdef __ISAPNP__ static struct isapnp_device_id hfc_ids[] __initdata = { { ISAPNP_VENDOR('A', 'N', 'X'), ISAPNP_FUNCTION(0x1114), @@ -166,7 +210,6 @@ int __init setup_hfcs(struct IsdnCard *card) { - struct IsdnCardState *cs = card->cs; char tmp[64]; strcpy(tmp, hfcs_revision); @@ -220,42 +263,8 @@ } } #endif - cs->hw.hfcD.addr = card->para[1] & 0xfffe; - cs->irq = card->para[0]; - cs->hw.hfcD.cip = 0; - cs->hw.hfcD.int_s1 = 0; - cs->hw.hfcD.send = NULL; - cs->bcs[0].hw.hfc.send = NULL; - cs->bcs[1].hw.hfc.send = NULL; - cs->hw.hfcD.dfifosize = 512; - cs->dc.hfcd.ph_state = 0; - cs->hw.hfcD.fifo = 255; - if (cs->typ == ISDN_CTYPE_TELES3C) { - cs->hw.hfcD.bfifosize = 1024 + 512; - } else if (cs->typ == ISDN_CTYPE_ACERP10) { - cs->hw.hfcD.bfifosize = 7*1024 + 512; - } else - return (0); - if (!request_io(&cs->rs, cs->hw.hfcD.addr, 2, "HFCS isdn")) + if (hfcs_probe(card->cs, card) < 0) return 0; - printk(KERN_INFO - "HFCS: defined at 0x%x IRQ %d HZ %d\n", - cs->hw.hfcD.addr, - cs->irq, HZ); - if (cs->typ == ISDN_CTYPE_TELES3C) { - /* Teles 16.3c IO ADR is 0x200 | YY0U (YY Bit 15/14 address) */ - outb(0x00, cs->hw.hfcD.addr); - outb(0x56, cs->hw.hfcD.addr | 1); - } else if (cs->typ == ISDN_CTYPE_ACERP10) { - /* Acer P10 IO ADR is 0x300 */ - outb(0x00, cs->hw.hfcD.addr); - outb(0x57, cs->hw.hfcD.addr | 1); - } - set_cs_func(cs); - cs->hw.hfcD.timer.function = (void *) hfcs_Timer; - cs->hw.hfcD.timer.data = (long) cs; - init_timer(&cs->hw.hfcD.timer); - hfcs_reset(cs); - cs->card_ops = &hfcs_ops; - return (1); + return 1; + } diff -urN linux-2.5.64-bk3/drivers/isdn/hisax/hisax.h linux-2.5.64-bk4/drivers/isdn/hisax/hisax.h --- linux-2.5.64-bk3/drivers/isdn/hisax/hisax.h Tue Mar 4 19:29:30 2003 +++ linux-2.5.64-bk4/drivers/isdn/hisax/hisax.h Mon Mar 31 12:25:45 2003 @@ -782,7 +782,6 @@ struct gazel_hw { unsigned int cfg_reg; - unsigned int pciaddr[2]; signed int ipac; signed int isac; signed int hscx[2]; @@ -1073,264 +1072,17 @@ #define ISDN_CTYPE_COUNT 41 -#ifdef ISDN_CHIP_ISAC -#undef ISDN_CHIP_ISAC -#endif - -#ifdef CONFIG_HISAX_16_0 -#define CARD_TELES0 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_TELES0 0 -#endif - -#ifdef CONFIG_HISAX_16_3 -#define CARD_TELES3 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_TELES3 0 -#endif - -#ifdef CONFIG_HISAX_TELESPCI -#define CARD_TELESPCI 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_TELESPCI 0 -#endif - -#ifdef CONFIG_HISAX_AVM_A1 -#define CARD_AVM_A1 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_AVM_A1 0 -#endif - -#ifdef CONFIG_HISAX_AVM_A1_PCMCIA -#define CARD_AVM_A1_PCMCIA 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_AVM_A1_PCMCIA 0 -#endif - -#ifdef CONFIG_HISAX_FRITZPCI -#define CARD_FRITZPCI 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_FRITZPCI 0 -#endif - -#ifdef CONFIG_HISAX_ELSA -#define CARD_ELSA 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_ELSA 0 -#endif - -#ifdef CONFIG_HISAX_IX1MICROR2 -#define CARD_IX1MICROR2 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_IX1MICROR2 0 -#endif - -#ifdef CONFIG_HISAX_DIEHLDIVA -#define CARD_DIEHLDIVA 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_DIEHLDIVA 0 -#endif - -#ifdef CONFIG_HISAX_ASUSCOM -#define CARD_ASUSCOM 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_ASUSCOM 0 -#endif - -#ifdef CONFIG_HISAX_TELEINT -#define CARD_TELEINT 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_TELEINT 0 -#endif - -#ifdef CONFIG_HISAX_SEDLBAUER -#define CARD_SEDLBAUER 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_SEDLBAUER 0 -#endif - -#ifdef CONFIG_HISAX_SPORTSTER -#define CARD_SPORTSTER 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_SPORTSTER 0 -#endif - -#ifdef CONFIG_HISAX_MIC -#define CARD_MIC 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_MIC 0 -#endif - -#ifdef CONFIG_HISAX_NETJET -#define CARD_NETJET_S 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_NETJET_S 0 -#endif - -#ifdef CONFIG_HISAX_HFCS -#define CARD_HFCS 1 -#else -#define CARD_HFCS 0 -#endif - -#ifdef CONFIG_HISAX_HFC_PCI -#define CARD_HFC_PCI 1 -#else -#define CARD_HFC_PCI 0 -#endif - -#ifdef CONFIG_HISAX_HFC_SX -#define CARD_HFC_SX 1 -#else -#define CARD_HFC_SX 0 -#endif - -#ifdef CONFIG_HISAX_AMD7930 -#define CARD_AMD7930 1 -#else -#define CARD_AMD7930 0 -#endif - -#ifdef CONFIG_HISAX_NICCY -#define CARD_NICCY 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_NICCY 0 -#endif - -#ifdef CONFIG_HISAX_ISURF -#define CARD_ISURF 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_ISURF 0 -#endif - -#ifdef CONFIG_HISAX_S0BOX -#define CARD_S0BOX 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_S0BOX 0 -#endif - -#ifdef CONFIG_HISAX_HSTSAPHIR -#define CARD_HSTSAPHIR 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_HSTSAPHIR 0 -#endif - #ifdef CONFIG_HISAX_TESTEMU -#define CARD_TESTEMU 1 #define ISDN_CTYPE_TESTEMU 99 #undef ISDN_CTYPE_COUNT #define ISDN_CTYPE_COUNT ISDN_CTYPE_TESTEMU -#else -#define CARD_TESTEMU 0 -#endif - -#ifdef CONFIG_HISAX_BKM_A4T -#define CARD_BKM_A4T 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_BKM_A4T 0 -#endif - -#ifdef CONFIG_HISAX_SCT_QUADRO -#define CARD_SCT_QUADRO 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_SCT_QUADRO 0 -#endif - -#ifdef CONFIG_HISAX_GAZEL -#define CARD_GAZEL 1 -#ifndef ISDN_CHIP_ISAC -#define ISDN_CHIP_ISAC 1 -#endif -#else -#define CARD_GAZEL 0 -#endif - -#ifdef CONFIG_HISAX_W6692 -#define CARD_W6692 1 -#ifndef ISDN_CHIP_W6692 -#define ISDN_CHIP_W6692 1 -#endif -#else -#define CARD_W6692 0 #endif #ifdef CONFIG_HISAX_NETJET_U -#define CARD_NETJET_U 1 -#ifndef ISDN_CHIP_ICC -#define ISDN_CHIP_ICC 1 -#endif #ifndef HISAX_UINTERFACE #define HISAX_UINTERFACE 1 #endif #else -#define CARD_NETJET_U 0 -#endif - -#ifdef CONFIG_HISAX_ENTERNOW_PCI -#define CARD_FN_ENTERNOW_PCI 1 #endif #define TEI_PER_CARD 1 @@ -1402,7 +1154,7 @@ int HiSax_command(isdn_ctrl * ic); int HiSax_writebuf_skb(int id, int chan, int ack, struct sk_buff *skb); void HiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, ...); -void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, va_list args); +void VHiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, va_list args); void HiSax_reportcard(int cardnr, int sel); int QuickHex(char *txt, u8 * p, int cnt); void LogFrame(struct IsdnCardState *cs, u8 * p, int size); diff -urN linux-2.5.64-bk3/drivers/isdn/hisax/hisax_fcclassic.c linux-2.5.64-bk4/drivers/isdn/hisax/hisax_fcclassic.c --- linux-2.5.64-bk3/drivers/isdn/hisax/hisax_fcclassic.c Tue Mar 4 19:28:58 2003 +++ linux-2.5.64-bk4/drivers/isdn/hisax/hisax_fcclassic.c Mon Mar 31 12:25:45 2003 @@ -231,7 +231,7 @@ adapter->isac.write_isac = &fcclassic_write_isac; adapter->isac.read_isac_fifo = &fcclassic_read_isac_fifo; adapter->isac.write_isac_fifo = &fcclassic_write_isac_fifo; - isac_setup(&adapter->isac); + hisax_isac_setup(&adapter->isac); for (i = 0; i < 2; i++) { hscx_init(&adapter->hscx[i]); adapter->hscx[i].priv = adapter; diff -urN linux-2.5.64-bk3/drivers/isdn/hisax/hisax_fcpcipnp.c linux-2.5.64-bk4/drivers/isdn/hisax/hisax_fcpcipnp.c --- linux-2.5.64-bk3/drivers/isdn/hisax/hisax_fcpcipnp.c Tue Mar 4 19:29:32 2003 +++ linux-2.5.64-bk4/drivers/isdn/hisax/hisax_fcpcipnp.c Mon Mar 31 12:25:45 2003 @@ -46,24 +46,22 @@ MODULE_AUTHOR("Kai Germaschewski /Karsten Keil "); 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" }, - { PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_A1_V2, PCI_ANY_ID, PCI_ANY_ID, - 0, 0, (unsigned long) "Fritz!Card PCI v2" }, - { } + { .vendor = PCI_VENDOR_ID_AVM, + .device = PCI_DEVICE_ID_AVM_A1, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = (unsigned long) "Fritz!Card PCI", + }, + { .vendor = PCI_VENDOR_ID_AVM, + .device = PCI_DEVICE_ID_AVM_A1_V2, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = (unsigned long) "Fritz!Card PCI v2" }, + {} }; -MODULE_DEVICE_TABLE(pci, fcpci_ids); -static struct pnp_card_device_id fcpnp_ids[] __devinitdata = { - { .id = "AVM0900", - .driver_data = (unsigned long) "Fritz!Card PnP", - .devs = { { "AVM0900" } } } -}; -MODULE_DEVICE_TABLE(pnp_card, fcpnp_ids); +MODULE_DEVICE_TABLE(pci, fcpci_ids); static int protocol = 2; /* EURO-ISDN Default */ MODULE_PARM(protocol, "i"); @@ -782,7 +780,7 @@ case AVM_FRITZ_PCI: case AVM_FRITZ_PNP: fcpci_init(adapter); - isac_setup(&adapter->isac); + hisax_isac_setup(&adapter->isac); break; } val = adapter->read_hdlc_status(adapter, 0); @@ -908,10 +906,10 @@ .id_table = fcpci_ids, }; -#ifdef __ISAPNP__ +#ifdef CONFIG_PNP_CARD static int __devinit fcpnp_probe(struct pnp_card *card, - const struct pnp_card_device_id *card_id) + const struct pnp_card_id *card_id) { struct fritz_adapter *adapter; struct pnp_dev *pnp_dev; @@ -957,6 +955,14 @@ delete_adapter(adapter); } +static struct pnp_card_id fcpnp_ids[] __devinitdata = { + { .id = "AVM0900", + .driver_data = (unsigned long) "Fritz!Card PnP", + .devs = { { "AVM0900" } }, + }, + {} +}; + static struct pnpc_driver fcpnp_driver = { .name = "fcpnp", .probe = fcpnp_probe, @@ -968,7 +974,7 @@ static int __init hisax_fcpcipnp_init(void) { - int retval, pci_nr_found; + int retval = 0, pci_nr_found; printk(KERN_INFO "hisax_fcpcipnp: Fritz!Card PCI/PCIv2/PnP ISDN driver v0.0.1\n"); @@ -977,10 +983,8 @@ goto out; pci_nr_found = retval; -#ifdef __ISAPNP__ +#ifdef CONFIG_PNP_CARD retval = pnpc_register_driver(&fcpnp_driver); -#else - retval = 0; #endif if (retval < 0) goto out_unregister_pci; @@ -988,14 +992,14 @@ #if !defined(CONFIG_HOTPLUG) || defined(MODULE) if (pci_nr_found + retval == 0) { retval = -ENODEV; - goto out_unregister_isapnp; + goto out_unregister_pnp; } #endif return 0; #if !defined(CONFIG_HOTPLUG) || defined(MODULE) - out_unregister_isapnp: -#ifdef __ISAPNP__ + out_unregister_pnp: +#ifdef CONFIG_PNP_CARD pnpc_unregister_driver(&fcpnp_driver); #endif #endif @@ -1007,7 +1011,7 @@ static void __exit hisax_fcpcipnp_exit(void) { -#ifdef __ISAPNP__ +#ifdef CONFIG_PNP_CARD pnpc_unregister_driver(&fcpnp_driver); #endif pci_unregister_driver(&fcpci_driver); diff -urN linux-2.5.64-bk3/drivers/isdn/hisax/hisax_isac.c linux-2.5.64-bk4/drivers/isdn/hisax/hisax_isac.c --- linux-2.5.64-bk3/drivers/isdn/hisax/hisax_isac.c Tue Mar 4 19:28:57 2003 +++ linux-2.5.64-bk4/drivers/isdn/hisax/hisax_isac.c Mon Mar 31 12:25:45 2003 @@ -770,7 +770,7 @@ FsmInitTimer(&isac->l1m, &isac->timer); } -void isac_setup(struct isac *isac) +void hisax_isac_setup(struct isac *isac) { int val, eval; @@ -890,7 +890,7 @@ EXPORT_SYMBOL(isacsx_setup); EXPORT_SYMBOL(isacsx_irq); -EXPORT_SYMBOL(isac_setup); +EXPORT_SYMBOL(hisax_isac_setup); EXPORT_SYMBOL(isac_irq); module_init(hisax_isac_init); diff -urN linux-2.5.64-bk3/drivers/isdn/hisax/hisax_isac.h linux-2.5.64-bk4/drivers/isdn/hisax/hisax_isac.h --- linux-2.5.64-bk3/drivers/isdn/hisax/hisax_isac.h Tue Mar 4 19:29:31 2003 +++ linux-2.5.64-bk4/drivers/isdn/hisax/hisax_isac.h Mon Mar 31 12:25:45 2003 @@ -36,7 +36,7 @@ void isac_init(struct isac *isac); void isac_d_l2l1(struct hisax_if *hisax_d_if, int pr, void *arg); -void isac_setup(struct isac *isac); +void hisax_isac_setup(struct isac *isac); void isac_irq(struct isac *isac); void isacsx_setup(struct isac *isac); diff -urN linux-2.5.64-bk3/drivers/isdn/hisax/isdnl1.c linux-2.5.64-bk4/drivers/isdn/hisax/isdnl1.c --- linux-2.5.64-bk3/drivers/isdn/hisax/isdnl1.c Tue Mar 4 19:29:04 2003 +++ linux-2.5.64-bk4/drivers/isdn/hisax/isdnl1.c Mon Mar 31 12:25:45 2003 @@ -126,7 +126,7 @@ }; void -debugl1(struct IsdnCardState *cs, char *fmt, ...) +debugl1(struct IsdnCardState *cs, const char *fmt, ...) { va_list args; char tmp[8]; diff -urN linux-2.5.64-bk3/drivers/isdn/hisax/isdnl1.h linux-2.5.64-bk4/drivers/isdn/hisax/isdnl1.h --- linux-2.5.64-bk3/drivers/isdn/hisax/isdnl1.h Tue Mar 4 19:29:32 2003 +++ linux-2.5.64-bk4/drivers/isdn/hisax/isdnl1.h Mon Mar 31 12:25:45 2003 @@ -28,7 +28,7 @@ #define B_LL_CONNECT 9 #define B_LL_OK 10 -extern void debugl1(struct IsdnCardState *cs, char *fmt, ...); +extern void debugl1(struct IsdnCardState *cs, const char *fmt, ...); extern void DChannel_proc_xmt(struct IsdnCardState *cs); extern void DChannel_proc_rcv(struct IsdnCardState *cs); extern void l1_msg(struct IsdnCardState *cs, int pr, void *arg); diff -urN linux-2.5.64-bk3/drivers/isdn/hisax/isurf.c linux-2.5.64-bk4/drivers/isdn/hisax/isurf.c --- linux-2.5.64-bk3/drivers/isdn/hisax/isurf.c Tue Mar 4 19:29:20 2003 +++ linux-2.5.64-bk4/drivers/isdn/hisax/isurf.c Mon Mar 31 12:25:45 2003 @@ -187,95 +187,92 @@ static struct pnp_card *pnp_surf __devinitdata = NULL; #endif -int __init -setup_isurf(struct IsdnCard *card) +static int __init +isurf_probe(struct IsdnCardState *cs, struct IsdnCard *card) { - 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 (card->para[1] && card->para[2]) { - cs->hw.isurf.reset = card->para[1]; - phymem = card->para[2]; - cs->irq = card->para[0]; - } else { -#ifdef __ISAPNP__ - struct pnp_card *pb; - struct pnp_dev *pd; + phymem = card->para[2]; + cs->hw.isurf.reset = card->para[1]; + cs->irq = card->para[0]; - if (isapnp_present()) { - cs->subtyp = 0; - if ((pb = pnp_find_card( - ISAPNP_VENDOR('S', 'I', 'E'), - ISAPNP_FUNCTION(0x0010), pnp_surf))) { - pnp_surf = pb; - pd = NULL; - if (!(pd = pnp_find_dev(pnp_surf, - ISAPNP_VENDOR('S', 'I', 'E'), - ISAPNP_FUNCTION(0x0010), pd))) { - printk(KERN_ERR "ISurfPnP: PnP error card found, no device\n"); - return (0); - } - if (pnp_device_attach(pd) < 0) { - printk(KERN_ERR "ISurfPnP: attach failed\n"); - return 0; - } - if (pnp_activate_dev(pd) < 0) { - printk(KERN_ERR "ISurfPnP: activate failed\n"); - pnp_device_detach(pd); - return 0; - } - if (!pnp_irq_valid(pd, 0) || !pnp_port_valid(pd, 0) || !pnp_port_valid(pd, 1)) { - printk(KERN_ERR "ISurfPnP:some resources are missing %ld/%lx/%lx\n", - pnp_irq(pd, 0), pnp_port_start(pd, 0), pnp_port_start(pd, 1)); - pnp_device_detach(pd); - return(0); - } - cs->hw.isurf.reset = pnp_port_start(pd, 0); - phymem = pnp_port_start(pd, 1); - cs->irq = pnp_irq(pd, 0); - } else { - printk(KERN_INFO "ISurfPnP: no ISAPnP card found\n"); - return(0); - } - } else { - printk(KERN_INFO "ISurfPnP: no ISAPnP bus found\n"); - return(0); - } -#else - printk(KERN_WARNING "HiSax: %s port/mem not set\n", - CardType[card->typ]); - return (0); -#endif - } 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"); + + 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, - card->para[2], - cs->irq); + printk(KERN_INFO "ISurf: defined at 0x%x 0x%lx IRQ %d\n", + cs->hw.isurf.reset, phymem, cs->irq); cs->auxcmd = &isurf_auxcmd; cs->card_ops = &isurf_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); + __set_bit(HW_ISAR, &cs->HW_Flags); isac_setup(cs, &isac_ops); if (isar_setup(cs, &isar_ops)) goto err; - return 1; + return 0; err: hisax_release_resources(cs); - return 0; + return -EBUSY; +} + +int __init +setup_isurf(struct IsdnCard *card) +{ + char tmp[64]; + strcpy(tmp, ISurf_revision); + printk(KERN_INFO "HiSax: ISurf driver Rev. %s\n", HiSax_getrev(tmp)); + +#ifdef __ISAPNP__ + if (!card->para[1] || !card->para[2]) { + struct pnp_card *pb; + struct pnp_dev *pd; + + cs->subtyp = 0; + if ((pb = pnp_find_card( + ISAPNP_VENDOR('S', 'I', 'E'), + ISAPNP_FUNCTION(0x0010), pnp_surf))) { + pnp_surf = pb; + pd = NULL; + if (!(pd = pnp_find_dev(pnp_surf, + ISAPNP_VENDOR('S', 'I', 'E'), + ISAPNP_FUNCTION(0x0010), pd))) { + printk(KERN_ERR "ISurfPnP: PnP error card found, no device\n"); + return (0); + } + if (pnp_device_attach(pd) < 0) { + printk(KERN_ERR "ISurfPnP: attach failed\n"); + return 0; + } + if (pnp_activate_dev(pd) < 0) { + printk(KERN_ERR "ISurfPnP: activate failed\n"); + pnp_device_detach(pd); + return 0; + } + if (!pnp_irq_valid(pd, 0) || !pnp_port_valid(pd, 0) || !pnp_port_valid(pd, 1)) { + printk(KERN_ERR "ISurfPnP:some resources are missing %ld/%lx/%lx\n", + pnp_irq(pd, 0), pnp_port_start(pd, 0), pnp_port_start(pd, 1)); + pnp_device_detach(pd); + return(0); + } + card->para[1] = pnp_port_start(pd, 0); + card->para[2] = pnp_port_start(pd, 1); + card->para[0] = pnp_irq(pd, 0); + } else { + printk(KERN_INFO "ISurfPnP: no ISAPnP card found\n"); + return 0; + } + } +#endif + if (isurf_probe(card->cs, card) < 0) + return 0; + return 1; } diff -urN linux-2.5.64-bk3/drivers/isdn/hisax/ix1_micro.c linux-2.5.64-bk4/drivers/isdn/hisax/ix1_micro.c --- linux-2.5.64-bk3/drivers/isdn/hisax/ix1_micro.c Tue Mar 4 19:29:52 2003 +++ linux-2.5.64-bk4/drivers/isdn/hisax/ix1_micro.c Mon Mar 31 12:25:45 2003 @@ -162,6 +162,29 @@ .irq_func = hscxisac_irq, }; +static int __init +ix1_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + cs->irq = card->para[0]; + cs->hw.ix1.isac_ale = card->para[1] + ISAC_COMMAND_OFFSET; + cs->hw.ix1.isac = card->para[1] + ISAC_DATA_OFFSET; + cs->hw.ix1.hscx = card->para[1] + HSCX_DATA_OFFSET; + cs->hw.ix1.cfg_reg = card->para[1]; + 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->card_ops = &ix1_ops; + if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) + goto err; + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + #ifdef __ISAPNP__ static struct isapnp_device_id itk_ids[] __initdata = { { ISAPNP_VENDOR('I', 'T', 'K'), ISAPNP_FUNCTION(0x25), @@ -181,14 +204,18 @@ int __init setup_ix1micro(struct IsdnCard *card) { - struct IsdnCardState *cs = card->cs; char tmp[64]; strcpy(tmp, ix1_revision); printk(KERN_INFO "HiSax: ITK IX1 driver Rev. %s\n", HiSax_getrev(tmp)); + if (card->para[1]) { + if (ix1_probe(card->cs, card)) + return 0; + return 1; + } #ifdef __ISAPNP__ - if (!card->para[1] && isapnp_present()) { + if (isapnp_present()) { struct pnp_card *pb; struct pnp_dev *pd; @@ -221,7 +248,9 @@ } card->para[1] = pnp_port_start(pd, 0); card->para[0] = pnp_irq(pd, 0); - break; + if (ix1_probe(card->cs, card)) + return 0; + return 1; } else { printk(KERN_ERR "ITK PnP: PnP error card found, no device\n"); } @@ -231,27 +260,8 @@ } if (!idev->card_vendor) { printk(KERN_INFO "ITK PnP: no ISAPnP card found\n"); - return(0); } } #endif - /* IO-Ports */ - cs->hw.ix1.isac_ale = card->para[1] + ISAC_COMMAND_OFFSET; - cs->hw.ix1.isac = card->para[1] + ISAC_DATA_OFFSET; - cs->hw.ix1.hscx = card->para[1] + HSCX_DATA_OFFSET; - cs->hw.ix1.cfg_reg = card->para[1]; - cs->irq = card->para[0]; - 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->card_ops = &ix1_ops; - if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) - goto err; - return 1; - err: - hisax_release_resources(cs); return 0; } diff -urN linux-2.5.64-bk3/drivers/isdn/hisax/mic.c linux-2.5.64-bk4/drivers/isdn/hisax/mic.c --- linux-2.5.64-bk3/drivers/isdn/hisax/mic.c Tue Mar 4 19:29:32 2003 +++ linux-2.5.64-bk4/drivers/isdn/hisax/mic.c Mon Mar 31 12:25:45 2003 @@ -138,17 +138,11 @@ .irq_func = hscxisac_irq, }; -int __init -setup_mic(struct IsdnCard *card) +static int __init +mic_probe(struct IsdnCardState *cs, struct IsdnCard *card) { - struct IsdnCardState *cs = card->cs; - char tmp[64]; - - strcpy(tmp, mic_revision); - printk(KERN_INFO "HiSax: mic driver Rev. %s\n", HiSax_getrev(tmp)); - - cs->hw.mic.cfg_reg = card->para[1]; cs->irq = card->para[0]; + cs->hw.mic.cfg_reg = card->para[1]; 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; @@ -158,11 +152,25 @@ printk(KERN_INFO "mic: defined at 0x%x IRQ %d\n", cs->hw.mic.cfg_reg, cs->irq); + cs->card_ops = &mic_ops; if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) goto err; - return 1; + return 0; err: hisax_release_resources(cs); - return 0; + return -EBUSY; +} + +int __init +setup_mic(struct IsdnCard *card) +{ + char tmp[64]; + + strcpy(tmp, mic_revision); + printk(KERN_INFO "HiSax: mic driver Rev. %s\n", HiSax_getrev(tmp)); + + if (mic_probe(card->cs, card) < 0) + return 0; + return 1; } diff -urN linux-2.5.64-bk3/drivers/isdn/hisax/niccy.c linux-2.5.64-bk4/drivers/isdn/hisax/niccy.c --- linux-2.5.64-bk3/drivers/isdn/hisax/niccy.c Tue Mar 4 19:29:16 2003 +++ linux-2.5.64-bk4/drivers/isdn/hisax/niccy.c Mon Mar 31 12:25:45 2003 @@ -199,6 +199,70 @@ .irq_func = niccy_interrupt, }; +static int __init +niccy_probe(struct IsdnCardState *cs) +{ + 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->card_ops = &niccy_ops; + if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) + return -EBUSY; + return 0; +} + +static int __init +niccy_pnp_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + cs->subtyp = NICCY_PNP; + cs->irq = card->para[0]; + cs->hw.niccy.isac = card->para[1] + ISAC_PNP; + cs->hw.niccy.hscx = card->para[1] + HSCX_PNP; + cs->hw.niccy.isac_ale = card->para[2] + ISAC_PNP; + cs->hw.niccy.hscx_ale = card->para[2] + HSCX_PNP; + cs->hw.niccy.cfg_reg = 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; + if (niccy_probe(cs) < 0) + goto err; + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + +static int __init +niccy_pci_probe(struct IsdnCardState *cs, struct pci_dev *pdev) +{ + u32 pci_ioaddr; + + if (pci_enable_device(pdev)) + goto err; + + cs->subtyp = NICCY_PCI; + cs->irq = pdev->irq; + cs->irq_flags |= SA_SHIRQ; + cs->hw.niccy.cfg_reg = pci_resource_start(pdev, 0); + pci_ioaddr = pci_resource_start(pdev, 1); + cs->hw.niccy.isac = pci_ioaddr + ISAC_PCI_DATA; + 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_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; + if (niccy_probe(cs) < 0) + goto err; + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + static struct pci_dev *niccy_dev __initdata = NULL; #ifdef __ISAPNP__ static struct pnp_card *pnp_c __devinitdata = NULL; @@ -207,7 +271,6 @@ int __init setup_niccy(struct IsdnCard *card) { - struct IsdnCardState *cs = card->cs; char tmp[64]; strcpy(tmp, niccy_revision); @@ -252,66 +315,18 @@ } #endif if (card->para[1]) { - cs->hw.niccy.isac = card->para[1] + ISAC_PNP; - cs->hw.niccy.hscx = card->para[1] + HSCX_PNP; - cs->hw.niccy.isac_ale = card->para[2] + ISAC_PNP; - cs->hw.niccy.hscx_ale = card->para[2] + HSCX_PNP; - cs->hw.niccy.cfg_reg = 0; - cs->subtyp = NICCY_PNP; - cs->irq = card->para[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; + if (niccy_pnp_probe(card->cs, card) < 0) + return 0; + return 1; } else { #if CONFIG_PCI - u_int pci_ioaddr; - cs->subtyp = 0; if ((niccy_dev = pci_find_device(PCI_VENDOR_ID_SATSAGEM, PCI_DEVICE_ID_SATSAGEM_NICCY, niccy_dev))) { - if (pci_enable_device(niccy_dev)) - return(0); - /* get IRQ */ - if (!niccy_dev->irq) { - printk(KERN_WARNING "Niccy: No IRQ for PCI card found\n"); - return(0); - } - cs->irq = niccy_dev->irq; - cs->hw.niccy.cfg_reg = pci_resource_start(niccy_dev, 0); - if (!cs->hw.niccy.cfg_reg) { - printk(KERN_WARNING "Niccy: No IO-Adr for PCI cfg found\n"); - return(0); - } - pci_ioaddr = pci_resource_start(niccy_dev, 1); - if (!pci_ioaddr) { - printk(KERN_WARNING "Niccy: No IO-Adr for PCI card found\n"); - return(0); - } - cs->subtyp = NICCY_PCI; - } else { - printk(KERN_WARNING "Niccy: No PCI card found\n"); - return(0); + if (niccy_pci_probe(card->cs, niccy_dev) < 0) + return 0; + return 1; } - cs->irq_flags |= SA_SHIRQ; - cs->hw.niccy.isac = pci_ioaddr + ISAC_PCI_DATA; - 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_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", - CardType[cs->typ], (cs->subtyp==1) ? "PnP":"PCI", - cs->irq, cs->hw.niccy.isac, cs->hw.niccy.isac_ale); - cs->card_ops = &niccy_ops; - if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) - goto err; - return 1; - err: - niccy_release(cs); return 0; } diff -urN linux-2.5.64-bk3/drivers/isdn/hisax/nj_s.c linux-2.5.64-bk4/drivers/isdn/hisax/nj_s.c --- linux-2.5.64-bk3/drivers/isdn/hisax/nj_s.c Tue Mar 4 19:29:04 2003 +++ linux-2.5.64-bk4/drivers/isdn/hisax/nj_s.c Mon Mar 31 12:25:45 2003 @@ -106,96 +106,99 @@ .irq_func = nj_s_interrupt, }; +static int __init +nj_s_probe(struct IsdnCardState *cs, struct pci_dev *pdev) +{ + if (pci_enable_device(pdev)) + goto err; + + pci_set_master(pdev); + + cs->irq = pdev->irq; + cs->irq_flags |= SA_SHIRQ; + cs->hw.njet.pdev = pdev; + cs->hw.njet.base = pci_resource_start(pdev, 0); + if (!request_io(&cs->rs, cs->hw.njet.base, 0x100, "netjet-s isdn")) + return 0; + + cs->hw.njet.auxa = cs->hw.njet.base + NETJET_AUXDATA; + cs->hw.njet.isac = cs->hw.njet.base | NETJET_ISAC_OFF; + + cs->hw.njet.ctrl_reg = 0xff; /* Reset On */ + byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); + + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout((10*HZ)/1000); /* Timeout 10ms */ + + cs->hw.njet.ctrl_reg = 0x00; /* Reset Off and status read clear */ + byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); + + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout((10*HZ)/1000); /* Timeout 10ms */ + + cs->hw.njet.auxd = 0xC0; + cs->hw.njet.dmactrl = 0; + + byteout(cs->hw.njet.auxa, 0); + byteout(cs->hw.njet.base + NETJET_AUXCTRL, ~NETJET_ISACIRQ); + byteout(cs->hw.njet.base + NETJET_IRQMASK1, NETJET_ISACIRQ); + byteout(cs->hw.njet.auxa, cs->hw.njet.auxd); + + switch ((NETjet_ReadIC(cs, ISAC_RBCH) >> 5) & 3) { + case 0 : + break; + case 3 : + printk(KERN_WARNING "NETjet-S: NETspider-U PCI card found\n" ); + goto err; + default : + printk(KERN_WARNING "NETjet-S: No PCI card found\n" ); + goto err; + } + printk(KERN_INFO + "NETjet-S: PCI card configured at %#lx IRQ %d\n", + cs->hw.njet.base, cs->irq); + + nj_s_reset(cs); + cs->irq_flags |= SA_SHIRQ; + cs->card_ops = &nj_s_ops; + isac_setup(cs, &netjet_dc_ops); + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + static struct pci_dev *dev_netjet __initdata = NULL; int __init setup_netjet_s(struct IsdnCard *card) { - struct IsdnCardState *cs = card->cs; char tmp[64]; #ifdef __BIG_ENDIAN #error "not running on big endian machines now" #endif strcpy(tmp, NETjet_S_revision); - printk(KERN_INFO "HiSax: Traverse Tech. NETjet-S driver Rev. %s\n", HiSax_getrev(tmp)); + printk(KERN_INFO "HiSax: Traverse Tech. NETjet-S driver Rev. %s\n", + HiSax_getrev(tmp)); - for ( ;; ) { - if ((dev_netjet = pci_find_device(PCI_VENDOR_ID_TIGERJET, - PCI_DEVICE_ID_TIGERJET_300, dev_netjet))) { - if (pci_enable_device(dev_netjet)) - return(0); - pci_set_master(dev_netjet); - cs->irq = dev_netjet->irq; - if (!cs->irq) { - printk(KERN_WARNING "NETjet-S: No IRQ for PCI card found\n"); - return(0); - } - cs->hw.njet.base = pci_resource_start(dev_netjet, 0); - if (!cs->hw.njet.base) { - printk(KERN_WARNING "NETjet-S: No IO-Adr for PCI card found\n"); - return(0); - } - /* 2001/10/04 Christoph Ersfeld, Formula-n Europe AG www.formula-n.com */ - if ((dev_netjet->subsystem_vendor == 0x55) && - (dev_netjet->subsystem_device == 0x02)) { - printk(KERN_WARNING "Netjet: You tried to load this driver with an incompatible TigerJet-card\n"); - printk(KERN_WARNING "Use type=41 for Formula-n enter:now ISDN PCI and compatible\n"); - return(0); - } - /* end new code */ - cs->hw.njet.pdev = dev_netjet; - } else { - printk(KERN_WARNING "NETjet-S: No PCI card found\n"); - return(0); + dev_netjet = pci_find_device(PCI_VENDOR_ID_TIGERJET, + PCI_DEVICE_ID_TIGERJET_300, dev_netjet); + if (dev_netjet) { + /* 2001/10/04 Christoph Ersfeld, Formula-n Europe AG www.formula-n.com */ + if (dev_netjet->subsystem_vendor == 0x55 && + dev_netjet->subsystem_device == 0x02) { + printk(KERN_WARNING "Netjet: You tried to load this " + "driver with an incompatible TigerJet-card\n"); + printk(KERN_WARNING "Use type=41 for Formula-n " + "enter:now ISDN PCI and compatible\n"); + return 0; } - - cs->hw.njet.auxa = cs->hw.njet.base + NETJET_AUXDATA; - cs->hw.njet.isac = cs->hw.njet.base | NETJET_ISAC_OFF; - - cs->hw.njet.ctrl_reg = 0xff; /* Reset On */ - byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); - - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout((10*HZ)/1000); /* Timeout 10ms */ - - cs->hw.njet.ctrl_reg = 0x00; /* Reset Off and status read clear */ - byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); - - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout((10*HZ)/1000); /* Timeout 10ms */ - - cs->hw.njet.auxd = 0xC0; - cs->hw.njet.dmactrl = 0; - - byteout(cs->hw.njet.base + NETJET_AUXCTRL, ~NETJET_ISACIRQ); - byteout(cs->hw.njet.base + NETJET_IRQMASK1, NETJET_ISACIRQ); - byteout(cs->hw.njet.auxa, cs->hw.njet.auxd); - - switch ( ( ( NETjet_ReadIC( cs, ISAC_RBCH ) >> 5 ) & 3 ) ) - { - case 0 : - break; - - case 3 : - printk( KERN_WARNING "NETjet-S: NETspider-U PCI card found\n" ); - continue; - - default : - printk( KERN_WARNING "NETjet-S: No PCI card found\n" ); - return 0; - } - break; - } - printk(KERN_INFO - "NETjet-S: PCI card configured at %#lx IRQ %d\n", - cs->hw.njet.base, cs->irq); - if (!request_io(&cs->rs, cs->hw.njet.base, 0x100, "netjet-s isdn")) + if (nj_s_probe(card->cs, dev_netjet)) + return 1; return 0; - - nj_s_reset(cs); - cs->irq_flags |= SA_SHIRQ; - cs->card_ops = &nj_s_ops; - isac_setup(cs, &netjet_dc_ops); - return 1; + } + printk(KERN_WARNING "NETjet-S: No PCI card found\n"); + return 0; } + diff -urN linux-2.5.64-bk3/drivers/isdn/hisax/nj_u.c linux-2.5.64-bk4/drivers/isdn/hisax/nj_u.c --- linux-2.5.64-bk3/drivers/isdn/hisax/nj_u.c Tue Mar 4 19:29:03 2003 +++ linux-2.5.64-bk4/drivers/isdn/hisax/nj_u.c Mon Mar 31 12:25:45 2003 @@ -110,88 +110,85 @@ .irq_func = nj_u_interrupt, }; +static int __init +nj_u_probe(struct IsdnCardState *cs, struct pci_dev *pdev) +{ + if (pci_enable_device(pdev)) + goto err; + + pci_set_master(pdev); + + cs->irq = pdev->irq; + cs->irq_flags |= SA_SHIRQ; + cs->hw.njet.pdev = pdev; + cs->hw.njet.base = pci_resource_start(pdev, 0); + if (!request_io(&cs->rs, cs->hw.njet.base, 0x100, "netspider-u isdn")) + goto err; + + cs->hw.njet.auxa = cs->hw.njet.base + NETJET_AUXDATA; + cs->hw.njet.isac = cs->hw.njet.base | NETJET_ISAC_OFF; + + cs->hw.njet.ctrl_reg = 0xff; /* Reset On */ + byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); + + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout((10*HZ)/1000); /* Timeout 10ms */ + + cs->hw.njet.ctrl_reg = 0x00; /* Reset Off and status read clear */ + byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); + + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout((10*HZ)/1000); /* Timeout 10ms */ + + cs->hw.njet.auxd = 0xC0; + cs->hw.njet.dmactrl = 0; + + byteout(cs->hw.njet.base + NETJET_AUXCTRL, ~NETJET_ISACIRQ); + byteout(cs->hw.njet.base + NETJET_IRQMASK1, NETJET_ISACIRQ); + byteout(cs->hw.njet.auxa, cs->hw.njet.auxd); + + switch ((NETjet_ReadIC(cs, ICC_RBCH) >> 5) & 3) { + case 3: + break; + case 0: + printk(KERN_WARNING "NETspider-U: NETjet-S PCI card found\n" ); + goto err; + default: + printk(KERN_WARNING "NETspider-U: No PCI card found\n" ); + goto err; + } + printk(KERN_INFO "NETspider-U: PCI card configured at %#lx IRQ %d\n", + cs->hw.njet.base, cs->irq); + + nj_u_reset(cs); + cs->card_ops = &nj_u_ops; + icc_setup(cs, &netjet_dc_ops); + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + static struct pci_dev *dev_netjet __initdata = NULL; int __init setup_netjet_u(struct IsdnCard *card) { - struct IsdnCardState *cs = card->cs; char tmp[64]; #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)); - - for ( ;; ) { - if ((dev_netjet = pci_find_device(PCI_VENDOR_ID_TIGERJET, - PCI_DEVICE_ID_TIGERJET_300, dev_netjet))) { - if (pci_enable_device(dev_netjet)) - return(0); - pci_set_master(dev_netjet); - cs->irq = dev_netjet->irq; - if (!cs->irq) { - printk(KERN_WARNING "NETspider-U: No IRQ for PCI card found\n"); - return(0); - } - cs->hw.njet.base = pci_resource_start(dev_netjet, 0); - if (!cs->hw.njet.base) { - printk(KERN_WARNING "NETspider-U: No IO-Adr for PCI card found\n"); - return(0); - } - cs->hw.njet.pdev = dev_netjet; - } else { - printk(KERN_WARNING "NETspider-U: No PCI card found\n"); - return(0); - } - - cs->hw.njet.auxa = cs->hw.njet.base + NETJET_AUXDATA; - cs->hw.njet.isac = cs->hw.njet.base | NETJET_ISAC_OFF; - - cs->hw.njet.ctrl_reg = 0xff; /* Reset On */ - byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); - - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout((10*HZ)/1000); /* Timeout 10ms */ - - cs->hw.njet.ctrl_reg = 0x00; /* Reset Off and status read clear */ - byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); - - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout((10*HZ)/1000); /* Timeout 10ms */ - - cs->hw.njet.auxd = 0xC0; - cs->hw.njet.dmactrl = 0; - - byteout(cs->hw.njet.auxa, 0); - byteout(cs->hw.njet.base + NETJET_AUXCTRL, ~NETJET_ISACIRQ); - byteout(cs->hw.njet.base + NETJET_IRQMASK1, NETJET_ISACIRQ); - byteout(cs->hw.njet.auxa, cs->hw.njet.auxd); - - switch ( ( ( NETjet_ReadIC( cs, ICC_RBCH ) >> 5 ) & 3 ) ) - { - case 3 : - break; - - case 0 : - printk( KERN_WARNING "NETspider-U: NETjet-S PCI card found\n" ); - continue; - - default : - printk( KERN_WARNING "NETspider-U: No PCI card found\n" ); - return 0; - } - break; - } - printk(KERN_INFO - "NETspider-U: PCI card configured at %#lx IRQ %d\n", - cs->hw.njet.base, cs->irq); - if (!request_io(&cs->rs, cs->hw.njet.base, 0x100, "netjet-s isdn")) - return 0; + printk(KERN_INFO "HiSax: Traverse Tech. NETspider-U driver Rev. %s\n", + HiSax_getrev(tmp)); - nj_u_reset(cs); - cs->irq_flags |= SA_SHIRQ; - cs->card_ops = &nj_u_ops; - icc_setup(cs, &netjet_dc_ops); - return 1; + dev_netjet = pci_find_device(PCI_VENDOR_ID_TIGERJET, + PCI_DEVICE_ID_TIGERJET_300, dev_netjet); + if (dev_netjet) { + if (nj_u_probe(card->cs, dev_netjet)) + return 1; + return 0; + } + printk(KERN_WARNING "NETspider-U: No PCI card found\n"); + return 0; } diff -urN linux-2.5.64-bk3/drivers/isdn/hisax/s0box.c linux-2.5.64-bk4/drivers/isdn/hisax/s0box.c --- linux-2.5.64-bk3/drivers/isdn/hisax/s0box.c Tue Mar 4 19:28:58 2003 +++ linux-2.5.64-bk4/drivers/isdn/hisax/s0box.c Mon Mar 31 12:25:45 2003 @@ -172,14 +172,9 @@ .irq_func = hscxisac_irq, }; -int __init -setup_s0box(struct IsdnCard *card) +static int __init +s0box_probe(struct IsdnCardState *cs, struct IsdnCard *card) { - struct IsdnCardState *cs = card->cs; - char tmp[64]; - - strcpy(tmp, s0box_revision); - printk(KERN_INFO "HiSax: S0Box IO driver Rev. %s\n", HiSax_getrev(tmp)); cs->hw.teles3.cfg_reg = card->para[1]; cs->hw.teles3.hscx[0] = -0x20; cs->hw.teles3.hscx[1] = 0x0; @@ -200,8 +195,20 @@ cs->card_ops = &s0box_ops; if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) goto err; - return 1; + return 0; err: hisax_release_resources(cs); - return 0; + return -EBUSY; +} + +int __init +setup_s0box(struct IsdnCard *card) +{ + char tmp[64]; + + strcpy(tmp, s0box_revision); + printk(KERN_INFO "HiSax: S0Box IO driver Rev. %s\n", HiSax_getrev(tmp)); + if (s0box_probe(card->cs, card)) + return 0; + return 1; } diff -urN linux-2.5.64-bk3/drivers/isdn/hisax/saphir.c linux-2.5.64-bk4/drivers/isdn/hisax/saphir.c --- linux-2.5.64-bk3/drivers/isdn/hisax/saphir.c Tue Mar 4 19:28:53 2003 +++ linux-2.5.64-bk4/drivers/isdn/hisax/saphir.c Mon Mar 31 12:25:45 2003 @@ -201,36 +201,21 @@ .irq_func = saphir_interrupt, }; -int __init -setup_saphir(struct IsdnCard *card) +static int __init +saphir_probe(struct IsdnCardState *cs, struct IsdnCard *card) { - struct IsdnCardState *cs = card->cs; - char tmp[64]; - - strcpy(tmp, saphir_rev); - printk(KERN_INFO "HiSax: HST Saphir driver Rev. %s\n", HiSax_getrev(tmp)); - 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_io(&cs->rs, cs->hw.saphir.cfg_reg, 6, "saphir")) goto err; - printk(KERN_INFO - "HiSax: %s config irq:%d io:0x%X\n", - CardType[cs->typ], cs->irq, - cs->hw.saphir.cfg_reg); + printk(KERN_INFO "HiSax: %s config irq:%d io:0x%X\n", + CardType[cs->typ], cs->irq, cs->hw.saphir.cfg_reg); - cs->hw.saphir.timer.function = (void *) SaphirWatchDog; - cs->hw.saphir.timer.data = (long) cs; - cs->hw.saphir.timer.expires = jiffies + 4*HZ; - add_timer(&cs->hw.saphir.timer); if (saphir_reset(cs)) goto err; @@ -238,8 +223,27 @@ if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) goto err; - return 1; - err: - saphir_release(cs); + init_timer(&cs->hw.saphir.timer); + cs->hw.saphir.timer.function = (void *) SaphirWatchDog; + cs->hw.saphir.timer.data = (long) cs; + cs->hw.saphir.timer.expires = jiffies + 4*HZ; + add_timer(&cs->hw.saphir.timer); return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + +int __init +setup_saphir(struct IsdnCard *card) +{ + char tmp[64]; + + strcpy(tmp, saphir_rev); + printk(KERN_INFO "HiSax: HST Saphir driver Rev. %s\n", + HiSax_getrev(tmp)); + + if (saphir_probe(card->cs, card) < 0) + return 0; + return 1; } diff -urN linux-2.5.64-bk3/drivers/isdn/hisax/sedlbauer.c linux-2.5.64-bk4/drivers/isdn/hisax/sedlbauer.c --- linux-2.5.64-bk3/drivers/isdn/hisax/sedlbauer.c Tue Mar 4 19:29:53 2003 +++ linux-2.5.64-bk4/drivers/isdn/hisax/sedlbauer.c Mon Mar 31 12:25:45 2003 @@ -73,7 +73,6 @@ #define SEDL_SPEEDFAX_PYRAMID 7 #define SEDL_SPEEDFAX_PCI 8 -#define SEDL_CHIP_TEST 0 #define SEDL_CHIP_ISAC_HSCX 1 #define SEDL_CHIP_ISAC_ISAR 2 #define SEDL_CHIP_IPAC 3 @@ -452,6 +451,241 @@ .irq_func = sedlbauer_isar_interrupt, }; +static int __init +sedl_ipac_probe(struct IsdnCardState *cs) +{ + u8 val; + + cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_ADR; + val = readreg(cs, cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC, IPAC_ID); + printk(KERN_DEBUG "Sedlbauer: testing IPAC version %x\n", val); + return (val == 1 || val == 2); +} + +static int __init +sedl_ipac_init(struct IsdnCardState *cs) +{ + cs->card_ops = &sedlbauer_ipac_ops; + if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops)) + return -ENODEV; + sedlbauer_reset(cs); + return 0; +} + +static int __init +sedl_isac_isar_init(struct IsdnCardState *cs) +{ + cs->bcs[0].hw.isar.reg = &cs->hw.sedl.isar; + cs->bcs[1].hw.isar.reg = &cs->hw.sedl.isar; + __set_bit(HW_ISAR, &cs->HW_Flags); + cs->card_ops = &sedlbauer_isar_ops; + cs->auxcmd = &isar_auxcmd; + isac_setup(cs, &isac_ops); + return isar_setup(cs, &isar_ops); +} + +static int __init +sedl_isac_hscx_init(struct IsdnCardState *cs) +{ + cs->card_ops = &sedlbauer_ops; + if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) + return -ENODEV; + sedlbauer_reset(cs); + return 0; +} + +static int __init +sedl_card_win_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + cs->irq = card->para[0]; + cs->hw.sedl.cfg_reg = card->para[1]; + cs->hw.sedl.bus = SEDL_BUS_ISA; + if (!request_io(&cs->rs, cs->hw.sedl.cfg_reg, 8, "sedlbauer isdn")) + goto err; + + if (sedl_ipac_probe(cs)) { + cs->subtyp = SEDL_SPEED_WIN2_PC104; + cs->hw.sedl.chip = SEDL_CHIP_IPAC; + cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_ADR; + cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC; + if (sedl_ipac_init(cs)) + goto err; + } else { + cs->subtyp = SEDL_SPEED_CARD_WIN; + cs->hw.sedl.chip = SEDL_CHIP_ISAC_HSCX; + cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_ADR; + cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_ISAC; + cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_HSCX; + cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_RESET_ON; + cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_RESET_OFF; + if (sedl_isac_hscx_init(cs)) + goto err; + } + printk(KERN_INFO "Sedlbauer %s: defined at 0x%x-0x%x IRQ %d\n", + Sedlbauer_Types[cs->subtyp], + cs->hw.sedl.cfg_reg, cs->hw.sedl.cfg_reg + 8, cs->irq); + + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + +static int __init +sedl_star_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + cs->hw.sedl.bus = SEDL_BUS_PCMCIA; + if (sedl_ipac_probe(cs)) { + cs->subtyp = SEDL_SPEED_STAR2; + cs->hw.sedl.chip = SEDL_CHIP_IPAC; + cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_ADR; + cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC; + if (sedl_ipac_init(cs)) + goto err; + } else { + cs->subtyp = SEDL_SPEED_STAR; + cs->hw.sedl.chip = SEDL_CHIP_ISAC_HSCX; + cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_ADR; + cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_ISAC; + cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_HSCX; + cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_RESET; + cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_RESET; + if (sedl_isac_hscx_init(cs)) + goto err; + } + printk(KERN_INFO "Sedlbauer %s: defined at 0x%x-0x%x IRQ %d\n", + Sedlbauer_Types[cs->subtyp], + cs->hw.sedl.cfg_reg, cs->hw.sedl.cfg_reg + 8, cs->irq); + + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + +static int __init +sedl_fax_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + cs->subtyp = SEDL_SPEED_FAX; + cs->hw.sedl.bus = SEDL_BUS_ISA; + cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR; + if (!request_io(&cs->rs, cs->hw.sedl.cfg_reg, 16, "sedlbauer isdn")) + goto err; + + printk(KERN_INFO "Sedlbauer %s: defined at 0x%x-0x%x IRQ %d\n", + Sedlbauer_Types[cs->subtyp], + cs->hw.sedl.cfg_reg, cs->hw.sedl.cfg_reg + 16, cs->irq); + + cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_ISAR_ISA_ADR; + cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_ISAR_ISA_ISAC; + cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_ISAR_ISA_ISAR; + cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg + SEDL_ISAR_ISA_ISAR_RESET_ON; + cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg + SEDL_ISAR_ISA_ISAR_RESET_OFF; + if (sedl_isac_isar_init(cs)) + goto err; + + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + +static int __init +sedl_pci_init(struct IsdnCardState *cs, struct pci_dev *pdev) +{ + cs->irq = pdev->irq; + cs->irq_flags |= SA_SHIRQ; + cs->hw.sedl.cfg_reg = pci_resource_start(pdev, 0); + cs->hw.sedl.bus = SEDL_BUS_PCI; + + if (!request_io(&cs->rs, cs->hw.sedl.cfg_reg, 256, "sedlbauer isdn")) + return -EBUSY; + + printk(KERN_INFO "Sedlbauer %s: defined at 0x%x-0x%x IRQ %d\n", + Sedlbauer_Types[cs->subtyp], + cs->hw.sedl.cfg_reg, cs->hw.sedl.cfg_reg + 256, cs->irq); + + cs->hw.sedl.reset_on = SEDL_ISAR_PCI_ISAR_RESET_ON; + cs->hw.sedl.reset_off = SEDL_ISAR_PCI_ISAR_RESET_OFF; + byteout(cs->hw.sedl.cfg_reg, 0xff); + byteout(cs->hw.sedl.cfg_reg, 0x00); + byteout(cs->hw.sedl.cfg_reg+ 2, 0xdd); + byteout(cs->hw.sedl.cfg_reg+ 5, 0x02); + byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_on); + current->state = TASK_UNINTERRUPTIBLE; + schedule_timeout((10*HZ)/1000); + byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_off); + return 0; +} + +static int __init +sedl_fax_pyramid_probe(struct IsdnCardState *cs, struct pci_dev *pdev) +{ + if (pci_enable_device(pdev)) + goto err; + + cs->subtyp = SEDL_SPEEDFAX_PYRAMID; + cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR; + if (sedl_pci_init(cs, pdev)) + goto err; + + cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_ISAR_PCI_ADR; + cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_ISAR_PCI_ISAC; + cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_ISAR_PCI_ISAR; + if (sedl_isac_isar_init(cs)) + goto err; + + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + +static int __init +sedl_fax_pci_probe(struct IsdnCardState *cs, struct pci_dev *pdev) +{ + if (pci_enable_device(pdev)) + goto err; + + cs->subtyp = SEDL_SPEEDFAX_PCI; + cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR; + + if (sedl_pci_init(cs, pdev)) + goto err; + + cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_ISAR_PCI_ADR; + cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_ISAR_PCI_ISAC; + cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_ISAR_PCI_ISAR; + if (sedl_isac_isar_init(cs)) + goto err; + + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + +static int __init +sedl_pci_probe(struct IsdnCardState *cs, struct pci_dev *pdev) +{ + if (pci_enable_device(pdev)) + goto err; + + cs->subtyp = SEDL_SPEED_PCI; + cs->hw.sedl.chip = SEDL_CHIP_IPAC; + if (sedl_pci_init(cs, pdev)) + goto err; + + cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_ADR; + cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_IPAC; + if (sedl_ipac_init(cs)) + goto err; + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + static struct pci_dev *dev_sedl __devinitdata = NULL; #ifdef __ISAPNP__ @@ -472,265 +706,117 @@ int __devinit setup_sedlbauer(struct IsdnCard *card) { - int bytecnt, val; struct IsdnCardState *cs = card->cs; char tmp[64]; u16 sub_vendor_id, sub_id; strcpy(tmp, Sedlbauer_revision); - printk(KERN_INFO "HiSax: Sedlbauer driver Rev. %s\n", HiSax_getrev(tmp)); + printk(KERN_INFO "HiSax: Sedlbauer driver Rev. %s\n", + HiSax_getrev(tmp)); - if (cs->typ == ISDN_CTYPE_SEDLBAUER) { - cs->subtyp = SEDL_SPEED_CARD_WIN; - cs->hw.sedl.bus = SEDL_BUS_ISA; - cs->hw.sedl.chip = SEDL_CHIP_TEST; - } else if (cs->typ == ISDN_CTYPE_SEDLBAUER_PCMCIA) { - cs->subtyp = SEDL_SPEED_STAR; - cs->hw.sedl.bus = SEDL_BUS_PCMCIA; - cs->hw.sedl.chip = SEDL_CHIP_TEST; - } else if (cs->typ == ISDN_CTYPE_SEDLBAUER_FAX) { - cs->subtyp = SEDL_SPEED_FAX; - cs->hw.sedl.bus = SEDL_BUS_ISA; - cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR; - } else - return (0); - - bytecnt = 8; if (card->para[1]) { - cs->hw.sedl.cfg_reg = card->para[1]; - cs->irq = card->para[0]; - if (cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) { - bytecnt = 16; + if (cs->typ == ISDN_CTYPE_SEDLBAUER) { + if (sedl_card_win_probe(card->cs, card) < 0) + return 0; + return 1; + } else if (cs->typ == ISDN_CTYPE_SEDLBAUER_PCMCIA) { + if (sedl_star_probe(card->cs, card) < 0) + return 0; + return 1; + } else if (cs->typ == ISDN_CTYPE_SEDLBAUER_FAX) { + if (sedl_fax_probe(card->cs, card) < 0) + return 0; + return 1; } - } else { + } #ifdef __ISAPNP__ - if (isapnp_present()) { - struct pnp_card *pb; - struct pnp_dev *pd; - - while(pdev->card_vendor) { - if ((pb = pnp_find_card(pdev->card_vendor, - pdev->card_device, - pnp_c))) { - pnp_c = pb; - pd = NULL; - if ((pd = pnp_find_dev(pnp_c, - pdev->vendor, - pdev->function, - pd))) { - printk(KERN_INFO "HiSax: %s detected\n", - (char *)pdev->driver_data); - if (pnp_device_attach(pd) < 0) { - printk(KERN_ERR "Sedlbauer PnP: attach failed\n"); - return 0; - } - if (pnp_activate_dev(pd) < 0) { - printk(KERN_ERR "Sedlbauer PnP: activate failed\n"); - pnp_device_detach(pd); + if (isapnp_present()) { + struct pnp_card *pb; + struct pnp_dev *pd; + + while(pdev->card_vendor) { + if ((pb = pnp_find_card(pdev->card_vendor, + pdev->card_device, + pnp_c))) { + pnp_c = pb; + pd = NULL; + if ((pd = pnp_find_dev(pnp_c, + pdev->vendor, + pdev->function, + pd))) { + printk(KERN_INFO "HiSax: %s detected\n", + (char *)pdev->driver_data); + if (pnp_device_attach(pd) < 0) { + printk(KERN_ERR "Sedlbauer PnP: attach failed\n"); + return 0; + } + if (pnp_activate_dev(pd) < 0) { + printk(KERN_ERR "Sedlbauer PnP: activate failed\n"); + pnp_device_detach(pd); + return 0; + } + if (!pnp_irq_valid(pd, 0) || !pnp_port_valid(pd, 0)) { + 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); + goto err; + } + card->para[1] = pnp_port_start(pd, 0); + card->para[0] = pnp_irq(pd, 0); + cs->hw.sedl.cfg_reg = card->para[1]; + cs->irq = card->para[0]; + if (pdev->function == ISAPNP_FUNCTION(0x2)) { + if (sedl_fax_probe(card->cs, card)) return 0; - } - if (!pnp_irq_valid(pd, 0) || !pnp_port_valid(pd, 0)) { - 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); - goto err; - } - card->para[1] = pnp_port_start(pd, 0); - card->para[0] = pnp_irq(pd, 0); - cs->hw.sedl.cfg_reg = card->para[1]; - cs->irq = card->para[0]; - if (pdev->function == ISAPNP_FUNCTION(0x2)) { - cs->subtyp = SEDL_SPEED_FAX; - cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR; - bytecnt = 16; - } else { - cs->subtyp = SEDL_SPEED_CARD_WIN; - cs->hw.sedl.chip = SEDL_CHIP_TEST; - } - goto ready; + return 1; } else { - printk(KERN_ERR "Sedlbauer PnP: PnP error card found, no device\n"); - goto err; + if (sedl_card_win_probe(card->cs, card)) + return 0; + return 1; } + } else { + printk(KERN_ERR "Sedlbauer PnP: PnP error card found, no device\n"); + goto err; } - pdev++; - pnp_c=NULL; - } - if (!pdev->card_vendor) { - printk(KERN_INFO "Sedlbauer PnP: no ISAPnP card found\n"); } + pdev++; + pnp_c=NULL; + } + if (!pdev->card_vendor) { + printk(KERN_INFO "Sedlbauer PnP: no ISAPnP card found\n"); } + } #endif /* Probe for Sedlbauer speed pci */ #if CONFIG_PCI - if ((dev_sedl = pci_find_device(PCI_VENDOR_ID_TIGERJET, - PCI_DEVICE_ID_TIGERJET_100, dev_sedl))) { - if (pci_enable_device(dev_sedl)) - goto err; - cs->irq = dev_sedl->irq; - if (!cs->irq) { - printk(KERN_WARNING "Sedlbauer: No IRQ for PCI card found\n"); - goto err; - } - cs->hw.sedl.cfg_reg = pci_resource_start(dev_sedl, 0); - } else { - printk(KERN_WARNING "Sedlbauer: No PCI card found\n"); - goto err; - } - cs->irq_flags |= SA_SHIRQ; - cs->hw.sedl.bus = SEDL_BUS_PCI; + dev_sedl = pci_find_device(PCI_VENDOR_ID_TIGERJET, + PCI_DEVICE_ID_TIGERJET_100, dev_sedl); + if (dev_sedl) { sub_vendor_id = dev_sedl->subsystem_vendor; sub_id = dev_sedl->subsystem_device; printk(KERN_INFO "Sedlbauer: PCI subvendor:%x subid %x\n", - sub_vendor_id, sub_id); - printk(KERN_INFO "Sedlbauer: PCI base adr %#x\n", - cs->hw.sedl.cfg_reg); + sub_vendor_id, sub_id); if (sub_id != PCI_SUB_ID_SEDLBAUER) { printk(KERN_ERR "Sedlbauer: unknown sub id %#x\n", sub_id); - goto err; + return 0; } if (sub_vendor_id == PCI_SUBVENDOR_SPEEDFAX_PYRAMID) { - cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR; - cs->subtyp = SEDL_SPEEDFAX_PYRAMID; + if (sedl_fax_pyramid_probe(cs, dev_sedl)) + return 0; + return 1; } else if (sub_vendor_id == PCI_SUBVENDOR_SPEEDFAX_PCI) { - cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR; - cs->subtyp = SEDL_SPEEDFAX_PCI; + if (sedl_fax_pci_probe(cs, dev_sedl)) + return 0; + return 1; } else if (sub_vendor_id == PCI_SUBVENDOR_SEDLBAUER_PCI) { - cs->hw.sedl.chip = SEDL_CHIP_IPAC; - cs->subtyp = SEDL_SPEED_PCI; - } else { - printk(KERN_ERR "Sedlbauer: unknown sub vendor id %#x\n", - sub_vendor_id); - goto err; - } - bytecnt = 256; - cs->hw.sedl.reset_on = SEDL_ISAR_PCI_ISAR_RESET_ON; - cs->hw.sedl.reset_off = SEDL_ISAR_PCI_ISAR_RESET_OFF; - byteout(cs->hw.sedl.cfg_reg, 0xff); - byteout(cs->hw.sedl.cfg_reg, 0x00); - byteout(cs->hw.sedl.cfg_reg+ 2, 0xdd); - byteout(cs->hw.sedl.cfg_reg+ 5, 0x02); - byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_on); - current->state = TASK_UNINTERRUPTIBLE; - schedule_timeout((10*HZ)/1000); - byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_off); -#endif /* CONFIG_PCI */ - } -ready: - /* In case of the sedlbauer pcmcia card, this region is in use, - * 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) { - if (!request_io(&cs->rs, cs->hw.sedl.cfg_reg, bytecnt, "sedlbauer isdn")) - goto err; - } - - printk(KERN_INFO - "Sedlbauer: defined at 0x%x-0x%x IRQ %d\n", - cs->hw.sedl.cfg_reg, - cs->hw.sedl.cfg_reg + bytecnt, - cs->irq); - -/* - * testing ISA and PCMCIA Cards for IPAC, default is ISAC - * do not test for PCI card, because ports are different - * and PCI card uses only IPAC (for the moment) - */ - if (cs->hw.sedl.bus != SEDL_BUS_PCI) { - cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_ADR; - val = readreg(cs, cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC, - IPAC_ID); - printk(KERN_DEBUG "Sedlbauer: testing IPAC version %x\n", val); - if ((val == 1) || (val == 2)) { - /* IPAC */ - cs->subtyp = SEDL_SPEED_WIN2_PC104; - if (cs->hw.sedl.bus == SEDL_BUS_PCMCIA) { - cs->subtyp = SEDL_SPEED_STAR2; - } - cs->hw.sedl.chip = SEDL_CHIP_IPAC; - } else { - /* ISAC_HSCX oder ISAC_ISAR */ - if (cs->hw.sedl.chip == SEDL_CHIP_TEST) { - cs->hw.sedl.chip = SEDL_CHIP_ISAC_HSCX; - } - } - } - -/* - * hw.sedl.chip is now properly set - */ - printk(KERN_INFO "Sedlbauer: %s detected\n", - Sedlbauer_Types[cs->subtyp]); - - - if (cs->hw.sedl.chip == SEDL_CHIP_IPAC) { - if (cs->hw.sedl.bus == SEDL_BUS_PCI) { - cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_ADR; - cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_IPAC; - cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_IPAC; - } else { - cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_ADR; - 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->card_ops = &sedlbauer_ipac_ops; - if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops)) - goto err; - sedlbauer_reset(cs); - } else { - /* ISAC_HSCX oder ISAC_ISAR */ - 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 + - SEDL_ISAR_PCI_ADR; - cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + - SEDL_ISAR_PCI_ISAC; - cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + - SEDL_ISAR_PCI_ISAR; - } else { - cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + - SEDL_ISAR_ISA_ADR; - cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + - SEDL_ISAR_ISA_ISAC; - cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + - SEDL_ISAR_ISA_ISAR; - cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg + - SEDL_ISAR_ISA_ISAR_RESET_ON; - cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg + - SEDL_ISAR_ISA_ISAR_RESET_OFF; - } - cs->bcs[0].hw.isar.reg = &cs->hw.sedl.isar; - cs->bcs[1].hw.isar.reg = &cs->hw.sedl.isar; - test_and_set_bit(HW_ISAR, &cs->HW_Flags); - cs->card_ops = &sedlbauer_isar_ops; - cs->auxcmd = &isar_auxcmd; - 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; - cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_ISAC; - cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_HSCX; - cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_RESET; - cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_RESET; - } else { - cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_ADR; - cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_ISAC; - cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_HSCX; - cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_RESET_ON; - cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_RESET_OFF; - } - cs->card_ops = &sedlbauer_ops; - if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) - goto err; - - sedlbauer_reset(cs); + if (sedl_pci_probe(cs, dev_sedl)) + return 0; + return 1; } + printk(KERN_ERR "Sedlbauer: unknown sub vendor id %#x\n", + sub_vendor_id); + return 0; } - return 1; - err: - hisax_release_resources(cs); +#endif /* CONFIG_PCI */ return 0; } diff -urN linux-2.5.64-bk3/drivers/isdn/hisax/sportster.c linux-2.5.64-bk4/drivers/isdn/hisax/sportster.c --- linux-2.5.64-bk3/drivers/isdn/hisax/sportster.c Tue Mar 4 19:29:00 2003 +++ linux-2.5.64-bk4/drivers/isdn/hisax/sportster.c Mon Mar 31 12:25:45 2003 @@ -189,42 +189,29 @@ } return 0; } - -int __init -setup_sportster(struct IsdnCard *card) -{ - struct IsdnCardState *cs = card->cs; - char tmp[64]; - - strcpy(tmp, sportster_revision); - printk(KERN_INFO "HiSax: USR Sportster driver Rev. %s\n", HiSax_getrev(tmp)); - cs->hw.spt.cfg_reg = card->para[1]; +static int __init +sportster_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ cs->irq = card->para[0]; + cs->hw.spt.cfg_reg = card->para[1]; if (!get_io_range(cs)) - return (0); + return -EBUSY; cs->hw.spt.isac = cs->hw.spt.cfg_reg + SPORTSTER_ISAC; cs->hw.spt.hscx[0] = cs->hw.spt.cfg_reg + SPORTSTER_HSCXA; cs->hw.spt.hscx[1] = cs->hw.spt.cfg_reg + SPORTSTER_HSCXB; switch(cs->irq) { - case 5: cs->hw.spt.res_irq = 1; - break; - case 7: cs->hw.spt.res_irq = 2; - break; - case 10:cs->hw.spt.res_irq = 3; - break; - case 11:cs->hw.spt.res_irq = 4; - break; - case 12:cs->hw.spt.res_irq = 5; - break; - case 14:cs->hw.spt.res_irq = 6; - break; - case 15:cs->hw.spt.res_irq = 7; - break; - default:sportster_release(cs); - printk(KERN_WARNING "Sportster: wrong IRQ\n"); - return(0); + case 5: cs->hw.spt.res_irq = 1; break; + case 7: cs->hw.spt.res_irq = 2; break; + case 10:cs->hw.spt.res_irq = 3; break; + case 11:cs->hw.spt.res_irq = 4; break; + case 12:cs->hw.spt.res_irq = 5; break; + case 14:cs->hw.spt.res_irq = 6; break; + case 15:cs->hw.spt.res_irq = 7; break; + default: + printk(KERN_WARNING "Sportster: wrong IRQ\n"); + goto err; } sportster_reset(cs); printk(KERN_INFO "HiSax: %s config irq:%d cfg:0x%X\n", @@ -234,8 +221,22 @@ cs->card_ops = &sportster_ops; if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) goto err; - return 1; - err: - hisax_release_resources(cs); return 0; + err: + sportster_release(cs); + return -EBUSY; +} + +int __init +setup_sportster(struct IsdnCard *card) +{ + char tmp[64]; + + strcpy(tmp, sportster_revision); + printk(KERN_INFO "HiSax: USR Sportster driver Rev. %s\n", + HiSax_getrev(tmp)); + + if (sportster_probe(card->cs, card) < 0) + return 0; + return 1; } diff -urN linux-2.5.64-bk3/drivers/isdn/hisax/teleint.c linux-2.5.64-bk4/drivers/isdn/hisax/teleint.c --- linux-2.5.64-bk3/drivers/isdn/hisax/teleint.c Tue Mar 4 19:29:55 2003 +++ linux-2.5.64-bk4/drivers/isdn/hisax/teleint.c Mon Mar 31 12:25:45 2003 @@ -256,15 +256,9 @@ .irq_func = teleint_interrupt, }; -int __init -setup_TeleInt(struct IsdnCard *card) +static int __init +teleint_probe(struct IsdnCardState *cs, struct IsdnCard *card) { - struct IsdnCardState *cs = card->cs; - char tmp[64]; - - strcpy(tmp, TeleInt_revision); - printk(KERN_INFO "HiSax: TeleInt driver Rev. %s\n", HiSax_getrev(tmp)); - cs->hw.hfc.addr = card->para[1] & 0x3fe; cs->irq = card->para[0]; cs->hw.hfc.cirm = HFC_CIRM; @@ -284,42 +278,54 @@ byteout(cs->hw.hfc.addr, cs->hw.hfc.addr & 0xff); byteout(cs->hw.hfc.addr | 1, ((cs->hw.hfc.addr & 0x300) >> 8) | 0x54); switch (cs->irq) { - case 3: - cs->hw.hfc.cirm |= HFC_INTA; - break; - case 4: - cs->hw.hfc.cirm |= HFC_INTB; - break; - case 5: - cs->hw.hfc.cirm |= HFC_INTC; - break; - case 7: - cs->hw.hfc.cirm |= HFC_INTD; - break; - case 10: - cs->hw.hfc.cirm |= HFC_INTE; - break; - case 11: - cs->hw.hfc.cirm |= HFC_INTF; - break; - default: - printk(KERN_WARNING "TeleInt: wrong IRQ\n"); - goto err; + case 3: + cs->hw.hfc.cirm |= HFC_INTA; + break; + case 4: + cs->hw.hfc.cirm |= HFC_INTB; + break; + case 5: + cs->hw.hfc.cirm |= HFC_INTC; + break; + case 7: + cs->hw.hfc.cirm |= HFC_INTD; + break; + case 10: + cs->hw.hfc.cirm |= HFC_INTE; + break; + case 11: + cs->hw.hfc.cirm |= HFC_INTF; + break; + default: + printk(KERN_WARNING "TeleInt: wrong IRQ\n"); + goto err; } byteout(cs->hw.hfc.addr | 1, cs->hw.hfc.cirm); byteout(cs->hw.hfc.addr | 1, cs->hw.hfc.ctmt); - printk(KERN_INFO - "TeleInt: defined at 0x%x IRQ %d\n", - cs->hw.hfc.addr, - cs->irq); + printk(KERN_INFO "TeleInt: defined at 0x%x IRQ %d\n", + cs->hw.hfc.addr, cs->irq); cs->card_ops = &teleint_ops; teleint_reset(cs); isac_setup(cs, &isac_ops); hfc_setup(cs, &hfc_ops); - return 1; - err: - teleint_release(cs); return 0; + + err: + hisax_release_resources(cs); + return -EBUSY; +} + +int __init +setup_TeleInt(struct IsdnCard *card) +{ + char tmp[64]; + + strcpy(tmp, TeleInt_revision); + printk(KERN_INFO "HiSax: TeleInt driver Rev. %s\n", HiSax_getrev(tmp)); + + if (teleint_probe(card->cs, card) < 0) + return 0; + return 1; } diff -urN linux-2.5.64-bk3/drivers/isdn/hisax/teles0.c linux-2.5.64-bk4/drivers/isdn/hisax/teles0.c --- linux-2.5.64-bk3/drivers/isdn/hisax/teles0.c Tue Mar 4 19:29:19 2003 +++ linux-2.5.64-bk4/drivers/isdn/hisax/teles0.c Mon Mar 31 12:25:45 2003 @@ -165,72 +165,95 @@ .irq_func = hscxisac_irq, }; -int __init -setup_teles0(struct IsdnCard *card) +static int __init +teles0_probe(struct IsdnCardState *cs, struct IsdnCard *card) { - u8 val; - struct IsdnCardState *cs = card->cs; - char tmp[64]; - - 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->hw.teles0.cfg_reg = card->para[2]; - else /* 8.0 */ - cs->hw.teles0.cfg_reg = 0; - - if (card->para[1] < 0x10000) { - card->para[1] <<= 4; - printk(KERN_INFO - "Teles0: membase configured DOSish, assuming 0x%lx\n", - (unsigned long) card->para[1]); - } cs->irq = card->para[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); - 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); - goto err; - } - 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); - 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]; - cs->hw.teles0.membase = request_mmio(&cs->rs, cs->hw.teles0.phymem, TELES_IOMEM_SIZE, "teles iomem"); + cs->hw.teles0.membase = request_mmio(&cs->rs, cs->hw.teles0.phymem, + TELES_IOMEM_SIZE, "teles iomem"); if (!cs->hw.teles0.membase) - goto err; + return -EBUSY; - printk(KERN_INFO - "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"); - goto err; + return -EBUSY; } cs->card_ops = &teles0_ops; if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) - goto err; - return 1; + return -EBUSY; + + return 0; +} + +static int __init +teles16_0_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + u8 val; + + cs->hw.teles0.cfg_reg = card->para[2]; + 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); + 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); + goto err; + } + 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); + goto err; + } + if (teles0_probe(cs, card) < 0) + goto err; + return 0; err: hisax_release_resources(cs); + return -EBUSY; +} + +static int __init +teles8_0_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + cs->hw.teles0.cfg_reg = 0; + + if (teles0_probe(cs, card) < 0) + goto err; + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + +int __init +setup_teles0(struct IsdnCard *card) +{ + char tmp[64]; + + strcpy(tmp, teles0_revision); + printk(KERN_INFO "HiSax: Teles 8.0/16.0 driver Rev. %s\n", + HiSax_getrev(tmp)); + + if (card->cs->typ == ISDN_CTYPE_16_0) { + if (teles16_0_probe(card->cs, card) < 0) + return 0; + } else { + if (teles8_0_probe(card->cs, card) < 0) + return 0; + } + return 1; } diff -urN linux-2.5.64-bk3/drivers/isdn/hisax/teles3.c linux-2.5.64-bk4/drivers/isdn/hisax/teles3.c --- linux-2.5.64-bk3/drivers/isdn/hisax/teles3.c Tue Mar 4 19:29:54 2003 +++ linux-2.5.64-bk4/drivers/isdn/hisax/teles3.c Mon Mar 31 12:25:45 2003 @@ -176,6 +176,152 @@ .irq_func = hscxisac_irq, }; +static int +teles_hw_init(struct IsdnCardState *cs) +{ + + printk(KERN_INFO "HiSax: %s config irq:%d isac:0x%X cfg:0x%X\n", + CardType[cs->typ], cs->irq, + cs->hw.teles3.isac + 32, cs->hw.teles3.cfg_reg); + printk(KERN_INFO "HiSax: hscx A:0x%X hscx B:0x%X\n", + cs->hw.teles3.hscx[0] + 32, cs->hw.teles3.hscx[1] + 32); + + if (teles3_reset(cs)) { + printk(KERN_WARNING "Teles3: wrong IRQ\n"); + return -EBUSY; + } + cs->card_ops = &teles3_ops; + if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) + return -EBUSY; + return 0; +} + +static void __init +teles_setup_io(struct IsdnCardState *cs, struct IsdnCard *card) +{ + cs->irq = card->para[0]; + cs->hw.teles3.isacfifo = cs->hw.teles3.isac + 0x3e; + cs->hw.teles3.hscxfifo[0] = cs->hw.teles3.hscx[0] + 0x3e; + cs->hw.teles3.hscxfifo[1] = cs->hw.teles3.hscx[1] + 0x3e; +} + +static int __init +telespcmcia_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + cs->hw.teles3.cfg_reg = 0; + cs->hw.teles3.hscx[0] = card->para[1] - 0x20; + cs->hw.teles3.hscx[1] = card->para[1]; + cs->hw.teles3.isac = card->para[1] + 0x20; + teles_setup_io(cs, card); + if (!request_io(&cs->rs, cs->hw.teles3.hscx[1], 96, + "HiSax Teles PCMCIA")) + goto err; + if (teles_hw_init(cs) < 0) + goto err; + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + +static int __init +teles_request_io(struct IsdnCardState *cs) +{ + if (!request_io(&cs->rs, cs->hw.teles3.isac + 32, 32, "HiSax isac")) + return -EBUSY; + if (!request_io(&cs->rs, cs->hw.teles3.hscx[0]+32, 32, "HiSax hscx A")) + return -EBUSY; + if (!request_io(&cs->rs, cs->hw.teles3.hscx[1]+32, 32, "HiSax hscx B")) + return -EBUSY; + return 0; +} + +static int __init +teles16_3_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + u8 val; + + cs->hw.teles3.cfg_reg = card->para[1]; + switch (cs->hw.teles3.cfg_reg) { + case 0x180: + case 0x280: + case 0x380: + cs->hw.teles3.cfg_reg |= 0xc00; + break; + } + cs->hw.teles3.isac = cs->hw.teles3.cfg_reg - 0x420; + cs->hw.teles3.hscx[0] = cs->hw.teles3.cfg_reg - 0xc20; + cs->hw.teles3.hscx[1] = cs->hw.teles3.cfg_reg - 0x820; + teles_setup_io(cs, card); + if (!request_io(&cs->rs, cs->hw.teles3.cfg_reg, 8, "teles3 cfg")) + goto err; + if (teles_request_io(cs) < 0) + goto err; + 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); + 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); + goto err; + } + /* 0x1e without AB, 0x1f with AB, 0x1c 16.3 ???, + * 0x39 16.3 1.1, 0x38 16.3 1.3, 0x46 16.3 with AB + Video */ + val = bytein(cs->hw.teles3.cfg_reg + 2); + 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); + goto err; + } + if (teles_hw_init(cs) < 0) + goto err; + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + +static int __init +compaq_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + cs->hw.teles3.cfg_reg = card->para[3]; + cs->hw.teles3.isac = card->para[2] - 32; + cs->hw.teles3.hscx[0] = card->para[1] - 32; + cs->hw.teles3.hscx[1] = card->para[1]; + teles_setup_io(cs, card); + if (!request_io(&cs->rs, cs->hw.teles3.cfg_reg, 1, "teles3 cfg")) + goto err; + if (teles_request_io(cs) < 0) + goto err; + if (teles_hw_init(cs) < 0) + goto err; + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + +static int __init +telespnp_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + cs->hw.teles3.cfg_reg = 0; + cs->hw.teles3.isac = card->para[1] - 32; + cs->hw.teles3.hscx[0] = card->para[2] - 32; + cs->hw.teles3.hscx[1] = card->para[2]; + teles_setup_io(cs, card); + if (teles_request_io(cs) < 0) + goto err; + if (teles_hw_init(cs) < 0) + goto err; + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + #ifdef __ISAPNP__ static struct isapnp_device_id teles_ids[] __initdata = { { ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x2110), @@ -197,16 +343,10 @@ int __devinit setup_teles3(struct IsdnCard *card) { - u8 val; - struct IsdnCardState *cs = card->cs; char tmp[64]; strcpy(tmp, teles3_revision); printk(KERN_INFO "HiSax: Teles IO driver Rev. %s\n", HiSax_getrev(tmp)); - if ((cs->typ != ISDN_CTYPE_16_3) && (cs->typ != ISDN_CTYPE_PNP) - && (cs->typ != ISDN_CTYPE_TELESPCMCIA) && (cs->typ != ISDN_CTYPE_COMPAQ_ISA)) - return (0); - #ifdef __ISAPNP__ if (!card->para[1] && isapnp_present()) { struct pnp_card *pnp_card; @@ -258,100 +398,18 @@ } } #endif - if (cs->typ == ISDN_CTYPE_16_3) { - cs->hw.teles3.cfg_reg = card->para[1]; - switch (cs->hw.teles3.cfg_reg) { - case 0x180: - case 0x280: - case 0x380: - cs->hw.teles3.cfg_reg |= 0xc00; - break; - } - cs->hw.teles3.isac = cs->hw.teles3.cfg_reg - 0x420; - cs->hw.teles3.hscx[0] = cs->hw.teles3.cfg_reg - 0xc20; - cs->hw.teles3.hscx[1] = cs->hw.teles3.cfg_reg - 0x820; - } else if (cs->typ == ISDN_CTYPE_TELESPCMCIA) { - cs->hw.teles3.cfg_reg = 0; - cs->hw.teles3.hscx[0] = card->para[1] - 0x20; - cs->hw.teles3.hscx[1] = card->para[1]; - cs->hw.teles3.isac = card->para[1] + 0x20; - } else if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) { - cs->hw.teles3.cfg_reg = card->para[3]; - cs->hw.teles3.isac = card->para[2] - 32; - cs->hw.teles3.hscx[0] = card->para[1] - 32; - cs->hw.teles3.hscx[1] = card->para[1]; + if (card->cs->typ == ISDN_CTYPE_16_3) { + if (teles16_3_probe(card->cs, card) < 0) + return 0; + } else if (card->cs->typ == ISDN_CTYPE_TELESPCMCIA) { + if (telespcmcia_probe(card->cs, card) < 0) + return 0; + } else if (card->cs->typ == ISDN_CTYPE_COMPAQ_ISA) { + if (compaq_probe(card->cs, card) < 0) + return 0; } else { /* PNP */ - cs->hw.teles3.cfg_reg = 0; - cs->hw.teles3.isac = card->para[1] - 32; - cs->hw.teles3.hscx[0] = card->para[2] - 32; - cs->hw.teles3.hscx[1] = card->para[2]; + if (telespnp_probe(card->cs, card) < 0) + return 0; } - cs->irq = card->para[0]; - cs->hw.teles3.isacfifo = cs->hw.teles3.isac + 0x3e; - 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_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_io(&cs->rs, cs->hw.teles3.cfg_reg, 1, "teles3 cfg")) - goto err; - } else { - if (!request_io(&cs->rs, cs->hw.teles3.cfg_reg, 8, "teles3 cfg")) - goto err; - } - } - 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); - 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); - goto err; - } - val = bytein(cs->hw.teles3.cfg_reg + 2);/* 0x1e=without AB - * 0x1f=with AB - * 0x1c 16.3 ??? - * 0x39 16.3 1.1 - * 0x38 16.3 1.3 - * 0x46 16.3 with AB + Video (Teles-Vision) - */ - 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); - goto err; - } - } - printk(KERN_INFO - "HiSax: %s config irq:%d isac:0x%X cfg:0x%X\n", - CardType[cs->typ], cs->irq, - cs->hw.teles3.isac + 32, cs->hw.teles3.cfg_reg); - printk(KERN_INFO - "HiSax: hscx A:0x%X hscx B:0x%X\n", - cs->hw.teles3.hscx[0] + 32, cs->hw.teles3.hscx[1] + 32); - - if (teles3_reset(cs)) { - printk(KERN_WARNING "Teles3: wrong IRQ\n"); - goto err; - } - cs->card_ops = &teles3_ops; - if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) - goto err; return 1; - err: - hisax_release_resources(cs); - return 0; - } diff -urN linux-2.5.64-bk3/drivers/isdn/hisax/telespci.c linux-2.5.64-bk4/drivers/isdn/hisax/telespci.c --- linux-2.5.64-bk3/drivers/isdn/hisax/telespci.c Tue Mar 4 19:29:30 2003 +++ linux-2.5.64-bk4/drivers/isdn/hisax/telespci.c Mon Mar 31 12:25:45 2003 @@ -231,36 +231,23 @@ .irq_func = telespci_interrupt, }; -static struct pci_dev *dev_tel __initdata = NULL; - -int __init -setup_telespci(struct IsdnCard *card) +static int __init +telespci_probe(struct IsdnCardState *cs, struct pci_dev *pdev) { - struct IsdnCardState *cs = card->cs; - char tmp[64]; + int rc; -#ifdef __BIG_ENDIAN -#error "not running on big endian machines now" -#endif - strcpy(tmp, telespci_revision); - printk(KERN_INFO "HiSax: Teles/PCI driver Rev. %s\n", HiSax_getrev(tmp)); - 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); - cs->irq = dev_tel->irq; - if (!cs->irq) { - printk(KERN_WARNING "Teles: No IRQ for PCI card found\n"); - return(0); - } - 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); - } + printk(KERN_INFO "TelesPCI: defined at %#lx IRQ %d\n", + pci_resource_start(pdev, 0), pdev->irq); + + rc = -EBUSY; + if (pci_enable_device(pdev)) + goto err; + + cs->irq = pdev->irq; + cs->irq_flags |= SA_SHIRQ; + cs->hw.teles0.membase = request_mmio(&cs->rs, pci_resource_start(pdev, 0), 4096, "telespci"); + if (!cs->hw.teles0.membase) + goto err; /* Initialize Zoran PCI controller */ writel(0x00000000, cs->hw.teles0.membase + 0x28); @@ -270,17 +257,36 @@ 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:%p\n", - CardType[cs->typ], cs->irq, - cs->hw.teles0.membase); - cs->irq_flags |= SA_SHIRQ; cs->card_ops = &telespci_ops; if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) goto err; - return 1; + return 0; err: hisax_release_resources(cs); + return rc; +} + +static struct pci_dev *dev_tel __initdata = NULL; + +int __init +setup_telespci(struct IsdnCard *card) +{ + char tmp[64]; + +#ifdef __BIG_ENDIAN +#error "not running on big endian machines now" +#endif + strcpy(tmp, telespci_revision); + printk(KERN_INFO "HiSax: Teles/PCI driver Rev. %s\n", + HiSax_getrev(tmp)); + dev_tel = pci_find_device(PCI_VENDOR_ID_ZORAN, + PCI_DEVICE_ID_ZORAN_36120, dev_tel); + if (dev_tel) { + if (telespci_probe(card->cs, dev_tel) < 0) + return 0; + return 1; + } + printk(KERN_WARNING "TelesPCI: No PCI card found\n"); return 0; } diff -urN linux-2.5.64-bk3/drivers/isdn/hisax/w6692.c linux-2.5.64-bk4/drivers/isdn/hisax/w6692.c --- linux-2.5.64-bk3/drivers/isdn/hisax/w6692.c Tue Mar 4 19:29:34 2003 +++ linux-2.5.64-bk4/drivers/isdn/hisax/w6692.c Mon Mar 31 12:25:45 2003 @@ -669,11 +669,11 @@ 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) +w6692_hw_init(struct IsdnCardState *cs) { - cs->dc_hw_ops = dc_ops; - cs->bc_hw_ops = bc_ops; + cs->card_ops = &w6692_ops; + 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; W6692Version(cs, "W6692:"); @@ -685,14 +685,45 @@ return 0; } +static int __init +w6692_probe(struct IsdnCardState *cs, struct pci_dev *pdev) +{ + int rc; + + printk(KERN_INFO "W6692: %s %s at %#lx IRQ %d\n", + id_list[cs->subtyp].vendor_name, id_list[cs->subtyp].card_name, + pci_resource_start(pdev, 1), pdev->irq); + + rc = -EBUSY; + if (pci_enable_device(pdev)) + goto err; + + /* USR ISDN PCI card TA need some special handling */ + if (cs->subtyp == W6692_WINBOND) { + if (pdev->subsystem_vendor == W6692_SV_USR && + pdev->subsystem_device == W6692_SD_USR) { + cs->subtyp = W6692_USR; + } + } + cs->irq = pdev->irq; + cs->irq_flags |= SA_SHIRQ; + cs->hw.w6692.iobase = pci_resource_start(pdev, 1); + + if (!request_io(&cs->rs, cs->hw.w6692.iobase, 0x100, + id_list[cs->subtyp].card_name)) + goto err; + + w6692_hw_init(cs); + return 0; + err: + hisax_release_resources(cs); + return rc; +} + int __init setup_w6692(struct IsdnCard *card) { - struct IsdnCardState *cs = card->cs; char tmp[64]; - u8 found = 0; - u8 pci_irq = 0; - u_int pci_ioaddr = 0; #ifdef __BIG_ENDIAN #error "not running on big endian machines now" @@ -704,54 +735,13 @@ id_list[id_idx].device_id, dev_w6692); if (dev_w6692) { - if (pci_enable_device(dev_w6692)) - continue; - cs->subtyp = id_idx; - break; + card->cs->subtyp = id_idx; + if (w6692_probe(card->cs, dev_w6692) < 0) + return 0; + return 1; } id_idx++; } - if (dev_w6692) { - found = 1; - pci_irq = dev_w6692->irq; - /* I think address 0 is allways the configuration area */ - /* and address 1 is the real IO space KKe 03.09.99 */ - pci_ioaddr = pci_resource_start(dev_w6692, 1); - /* USR ISDN PCI card TA need some special handling */ - if (cs->subtyp == W6692_WINBOND) { - if ((W6692_SV_USR == dev_w6692->subsystem_vendor) && - (W6692_SD_USR == dev_w6692->subsystem_device)) { - cs->subtyp = W6692_USR; - } - } - } - if (!found) { - printk(KERN_WARNING "W6692: No PCI card found\n"); - return (0); - } - cs->irq = pci_irq; - if (!cs->irq) { - printk(KERN_WARNING "W6692: No IRQ for PCI card found\n"); - return (0); - } - if (!pci_ioaddr) { - printk(KERN_WARNING "W6692: NO I/O Base Address found\n"); - return (0); - } - cs->hw.w6692.iobase = pci_ioaddr; - 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_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->card_ops = &w6692_ops; - w6692_setup(cs, &w6692_dc_hw_ops, &w6692_bc_hw_ops); - cs->irq_flags |= SA_SHIRQ; - return (1); + printk(KERN_WARNING "W6692: No PCI card found\n"); + return 0; } diff -urN linux-2.5.64-bk3/drivers/isdn/i4l/Kconfig linux-2.5.64-bk4/drivers/isdn/i4l/Kconfig --- linux-2.5.64-bk3/drivers/isdn/i4l/Kconfig Tue Mar 4 19:29:15 2003 +++ linux-2.5.64-bk4/drivers/isdn/i4l/Kconfig Mon Mar 31 12:25:45 2003 @@ -85,7 +85,7 @@ config ISDN_X25 bool "X.25 PLP on top of ISDN" - depends on X25 + depends on X25 && BROKEN help This feature provides the X.25 protocol over ISDN connections. See for more information diff -urN linux-2.5.64-bk3/drivers/isdn/i4l/isdn_net_lib.c linux-2.5.64-bk4/drivers/isdn/i4l/isdn_net_lib.c --- linux-2.5.64-bk3/drivers/isdn/i4l/isdn_net_lib.c Tue Mar 4 19:28:56 2003 +++ linux-2.5.64-bk4/drivers/isdn/i4l/isdn_net_lib.c Mon Mar 31 12:25:45 2003 @@ -58,6 +58,7 @@ #include "isdn_net.h" #include "isdn_ppp.h" #include "isdn_ciscohdlck.h" +#include "isdn_concap.h" #define ISDN_NET_TX_TIMEOUT (20*HZ) diff -urN linux-2.5.64-bk3/drivers/isdn/i4l/isdn_ppp.c linux-2.5.64-bk4/drivers/isdn/i4l/isdn_ppp.c --- linux-2.5.64-bk3/drivers/isdn/i4l/isdn_ppp.c Tue Mar 4 19:29:30 2003 +++ linux-2.5.64-bk4/drivers/isdn/i4l/isdn_ppp.c Mon Mar 31 12:25:45 2003 @@ -867,7 +867,7 @@ skb_pull(skb, 1); } else { if (skb->len < 2) - return -1; + return -EINVAL; get_u16(skb->data, proto); skb_pull(skb, 2); } @@ -1037,7 +1037,7 @@ isdn_ppp_frame_log("xmit1", skb->data, skb->len, 32, ipppd->unit, -1); ippp_push_proto(ind_ppp, skb, proto); - ippp_mp_xmit(idev, skb, proto); + ippp_mp_xmit(idev, skb); return 0; drop: diff -urN linux-2.5.64-bk3/drivers/isdn/i4l/isdn_ppp_mp.c linux-2.5.64-bk4/drivers/isdn/i4l/isdn_ppp_mp.c --- linux-2.5.64-bk3/drivers/isdn/i4l/isdn_ppp_mp.c Tue Mar 4 19:28:58 2003 +++ linux-2.5.64-bk4/drivers/isdn/i4l/isdn_ppp_mp.c Mon Mar 31 12:25:45 2003 @@ -91,12 +91,13 @@ } void -ippp_mp_xmit(isdn_net_dev *idev, struct sk_buff *skb, u16 proto) +ippp_mp_xmit(isdn_net_dev *idev, struct sk_buff *skb) { struct ind_ppp *ind_ppp = idev->ind_priv; struct inl_ppp *inl_ppp = idev->mlp->inl_priv; unsigned char *p; - long txseq; + u32 txseq; + u16 proto; if (!(inl_ppp->mp_cfg & SC_MP_PROT)) { return ippp_xmit(idev, skb); diff -urN linux-2.5.64-bk3/drivers/isdn/i4l/isdn_ppp_mp.h linux-2.5.64-bk4/drivers/isdn/i4l/isdn_ppp_mp.h --- linux-2.5.64-bk3/drivers/isdn/i4l/isdn_ppp_mp.h Tue Mar 4 19:29:58 2003 +++ linux-2.5.64-bk4/drivers/isdn/i4l/isdn_ppp_mp.h Mon Mar 31 12:25:45 2003 @@ -19,7 +19,7 @@ int ippp_mp_bind(isdn_net_dev *idev); void ippp_mp_disconnected(isdn_net_dev *idev); int ippp_mp_bundle(isdn_net_dev *idev, int val); -void ippp_mp_xmit(isdn_net_dev *idev, struct sk_buff *skb, u16 proto); +void ippp_mp_xmit(isdn_net_dev *idev, struct sk_buff *skb); void ippp_mp_receive(isdn_net_dev *idev, struct sk_buff *skb, u16 proto); #else @@ -42,9 +42,9 @@ } static inline void -ippp_mp_xmit(isdn_net_dev *idev, struct sk_buff *skb, u16 proto) +ippp_mp_xmit(isdn_net_dev *idev, struct sk_buff *skb) { - ippp_xmit(idev, skb, proto); + ippp_xmit(idev, skb); } static inline void diff -urN linux-2.5.64-bk3/drivers/md/dm.c linux-2.5.64-bk4/drivers/md/dm.c --- linux-2.5.64-bk3/drivers/md/dm.c Tue Mar 4 19:29:33 2003 +++ linux-2.5.64-bk4/drivers/md/dm.c Mon Mar 31 12:25:45 2003 @@ -79,9 +79,8 @@ return -ENOMEM; _major = major; - r = register_blkdev(_major, _name, &dm_blk_dops); + r = register_blkdev(_major, _name); if (r < 0) { - DMERR("register_blkdev failed"); kmem_cache_destroy(_io_cache); return r; } diff -urN linux-2.5.64-bk3/drivers/md/md.c linux-2.5.64-bk4/drivers/md/md.c --- linux-2.5.64-bk3/drivers/md/md.c Tue Mar 4 19:29:04 2003 +++ linux-2.5.64-bk4/drivers/md/md.c Mon Mar 31 12:25:45 2003 @@ -2803,7 +2803,9 @@ idle = 1; ITERATE_RDEV(mddev,rdev,tmp) { struct gendisk *disk = rdev->bdev->bd_contains->bd_disk; - curr_events = disk->read_sectors + disk->write_sectors - disk->sync_io; + curr_events = disk_stat_read(disk, read_sectors) + + disk_stat_read(disk, write_sectors) - + disk->sync_io; if ((curr_events - rdev->last_events) > 32) { rdev->last_events = curr_events; idle = 0; @@ -3214,11 +3216,10 @@ MD_MAJOR_VERSION, MD_MINOR_VERSION, MD_PATCHLEVEL_VERSION, MAX_MD_DEVS, MD_SB_DISKS); - if (register_blkdev (MAJOR_NR, "md", &md_fops)) { - printk(KERN_ALERT "md: Unable to get major %d for md\n", MAJOR_NR); - return (-1); - } - devfs_mk_dir (NULL, "md", NULL); + if (register_blkdev(MAJOR_NR, "md")) + return -1; + + devfs_mk_dir(NULL, "md", NULL); blk_register_region(MKDEV(MAJOR_NR, 0), MAX_MD_DEVS, THIS_MODULE, md_probe, NULL, NULL); for (minor=0; minor < MAX_MD_DEVS; ++minor) { diff -urN linux-2.5.64-bk3/drivers/message/i2o/i2o_block.c linux-2.5.64-bk4/drivers/message/i2o/i2o_block.c --- linux-2.5.64-bk3/drivers/message/i2o/i2o_block.c Tue Mar 4 19:29:31 2003 +++ linux-2.5.64-bk4/drivers/message/i2o/i2o_block.c Mon Mar 31 12:25:46 2003 @@ -1608,12 +1608,8 @@ /* * Register the block device interfaces */ - - if (register_blkdev(MAJOR_NR, "i2o_block", &i2ob_fops)) { - printk(KERN_ERR "Unable to get major number %d for i2o_block\n", - MAJOR_NR); + if (register_blkdev(MAJOR_NR, "i2o_block")) return -EIO; - } for (i = 0; i < MAX_I2OB; i++) { struct gendisk *disk = alloc_disk(16); diff -urN linux-2.5.64-bk3/drivers/mtd/ftl.c linux-2.5.64-bk4/drivers/mtd/ftl.c --- linux-2.5.64-bk3/drivers/mtd/ftl.c Tue Mar 4 19:29:33 2003 +++ linux-2.5.64-bk4/drivers/mtd/ftl.c Mon Mar 31 12:25:46 2003 @@ -1281,11 +1281,9 @@ static spinlock_t lock = SPIN_LOCK_UNLOCKED; DEBUG(0, "$Id: ftl.c,v 1.39 2001/10/02 15:05:11 dwmw2 Exp $\n"); - if (register_blkdev(FTL_MAJOR, "ftl", &ftl_blk_fops)) { - printk(KERN_NOTICE "ftl_cs: unable to grab major " - "device number!\n"); + if (register_blkdev(FTL_MAJOR, "ftl")) return -EAGAIN; - } + blk_init_queue(&ftl_queue, &do_ftl_request, &lock); register_mtd_user(&ftl_notifier); return 0; diff -urN linux-2.5.64-bk3/drivers/mtd/mtdblock.c linux-2.5.64-bk4/drivers/mtd/mtdblock.c --- linux-2.5.64-bk3/drivers/mtd/mtdblock.c Tue Mar 4 19:29:16 2003 +++ linux-2.5.64-bk4/drivers/mtd/mtdblock.c Mon Mar 31 12:25:46 2003 @@ -570,11 +570,10 @@ int __init init_mtdblock(void) { spin_lock_init(&mtdblks_lock); - if (register_blkdev(MAJOR_NR,DEVICE_NAME,&mtd_fops)) { - printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n", - MTD_BLOCK_MAJOR); + + if (register_blkdev(MAJOR_NR, DEVICE_NAME)) return -EAGAIN; - } + #ifdef CONFIG_DEVFS_FS devfs_mk_dir(NULL, DEVICE_NAME, NULL); #endif diff -urN linux-2.5.64-bk3/drivers/mtd/mtdblock_ro.c linux-2.5.64-bk4/drivers/mtd/mtdblock_ro.c --- linux-2.5.64-bk3/drivers/mtd/mtdblock_ro.c Tue Mar 4 19:29:18 2003 +++ linux-2.5.64-bk4/drivers/mtd/mtdblock_ro.c Mon Mar 31 12:25:46 2003 @@ -240,20 +240,13 @@ int __init init_mtdblock(void) { - int err; - - if (register_blkdev(MAJOR_NR,DEVICE_NAME,&mtd_fops)) { - printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n", - MTD_BLOCK_MAJOR); - err = -EAGAIN; - goto out; - } + if (register_blkdev(MAJOR_NR, DEVICE_NAME)) + return -EAGAIN; blk_init_queue(&mtdro_queue, &mtdblock_request, &mtdro_lock); register_mtd_user(¬ifier); - err = 0; - out: - return err; + + return 0; } static void __exit cleanup_mtdblock(void) diff -urN linux-2.5.64-bk3/drivers/mtd/nftlcore.c linux-2.5.64-bk4/drivers/mtd/nftlcore.c --- linux-2.5.64-bk3/drivers/mtd/nftlcore.c Tue Mar 4 19:28:55 2003 +++ linux-2.5.64-bk4/drivers/mtd/nftlcore.c Mon Mar 31 12:25:46 2003 @@ -928,10 +928,8 @@ printk(KERN_INFO "NFTL driver: nftlcore.c $Revision: 1.82 $, nftlmount.c %s\n", nftlmountrev); #endif - if (register_blkdev(MAJOR_NR, "nftl", &nftl_fops)) { - printk("unable to register NFTL block device on major %d\n", MAJOR_NR); + if (register_blkdev(MAJOR_NR, "nftl")) return -EBUSY; - } blk_register_region(MKDEV(MAJOR_NR, 0), 256, THIS_MODULE, nftl_probe, NULL, NULL); diff -urN linux-2.5.64-bk3/drivers/net/bonding.c linux-2.5.64-bk4/drivers/net/bonding.c --- linux-2.5.64-bk3/drivers/net/bonding.c Tue Mar 4 19:29:38 2003 +++ linux-2.5.64-bk4/drivers/net/bonding.c Mon Mar 31 12:25:46 2003 @@ -2574,6 +2574,13 @@ return 0; } + if (bond->slave_cnt == 0) { + /* no slaves in the bond, frame not sent */ + dev_kfree_skb(skb); + read_unlock_irqrestore(&bond->lock, flags); + return 0; + } + slave_no = (data->h_dest[5]^slave->dev->dev_addr[5]) % bond->slave_cnt; while ( (slave_no > 0) && (slave != (slave_t *)bond) ) { diff -urN linux-2.5.64-bk3/drivers/net/eepro100.c linux-2.5.64-bk4/drivers/net/eepro100.c --- linux-2.5.64-bk3/drivers/net/eepro100.c Tue Mar 4 19:29:30 2003 +++ linux-2.5.64-bk4/drivers/net/eepro100.c Mon Mar 31 12:25:46 2003 @@ -529,8 +529,6 @@ static int eepro100_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); -static void eepro100_remove_one (struct pci_dev *pdev); - static int do_eeprom_cmd(long ioaddr, int cmd, int cmd_len); static int mdio_read(struct net_device *dev, int phy_id, int location); static void mdio_write(struct net_device *dev, int phy_id, int location, int value); @@ -843,6 +841,7 @@ sp->lstats = (struct speedo_stats *)(sp->tx_ring + TX_RING_SIZE); sp->lstats_dma = TX_RING_ELEM_DMA(sp, TX_RING_SIZE); init_timer(&sp->timer); /* used in ioctl() */ + spin_lock_init(&sp->lock); sp->mii_if.full_duplex = option >= 0 && (option & 0x10) ? 1 : 0; if (card_idx >= 0) { @@ -994,7 +993,6 @@ sp->dirty_tx = 0; sp->last_cmd = 0; sp->tx_full = 0; - spin_lock_init(&sp->lock); sp->in_interrupt = 0; /* .. we can safely take handler calls during init. */ diff -urN linux-2.5.64-bk3/drivers/s390/block/dasd_genhd.c linux-2.5.64-bk4/drivers/s390/block/dasd_genhd.c --- linux-2.5.64-bk3/drivers/s390/block/dasd_genhd.c Tue Mar 4 19:29:32 2003 +++ linux-2.5.64-bk4/drivers/s390/block/dasd_genhd.c Mon Mar 31 12:25:46 2003 @@ -60,11 +60,8 @@ } /* Register block device. */ - new_major = register_blkdev(major, "dasd", &dasd_device_operations); + new_major = register_blkdev(major, "dasd"); if (new_major < 0) { - MESSAGE(KERN_WARNING, - "Cannot register to major no %d, rc = %d", - major, new_major); kfree(mi); return new_major; } diff -urN linux-2.5.64-bk3/drivers/s390/block/xpram.c linux-2.5.64-bk4/drivers/s390/block/xpram.c --- linux-2.5.64-bk3/drivers/s390/block/xpram.c Tue Mar 4 19:29:32 2003 +++ linux-2.5.64-bk4/drivers/s390/block/xpram.c Mon Mar 31 12:25:46 2003 @@ -430,13 +430,11 @@ /* * Register xpram major. */ - rc = register_blkdev(XPRAM_MAJOR, XPRAM_NAME, &xpram_devops); - if (rc < 0) { - PRINT_ERR("Can't get xpram major %d\n", XPRAM_MAJOR); + rc = register_blkdev(XPRAM_MAJOR, XPRAM_NAME); + if (rc < 0) goto out; - } - devfs_mk_dir (NULL, "slram", NULL); + devfs_mk_dir(NULL, "slram", NULL); /* * Assign the other needed values: make request function, sizes and @@ -452,6 +450,7 @@ for (i = 0; i < xpram_devs; i++) { struct gendisk *disk = xpram_disks[i]; char name[16]; + xpram_devices[i].size = xpram_sizes[i] / 4; xpram_devices[i].offset = offset; offset += xpram_devices[i].size; diff -urN linux-2.5.64-bk3/drivers/s390/char/tape_block.c linux-2.5.64-bk4/drivers/s390/char/tape_block.c --- linux-2.5.64-bk3/drivers/s390/char/tape_block.c Tue Mar 4 19:29:32 2003 +++ linux-2.5.64-bk4/drivers/s390/char/tape_block.c Mon Mar 31 12:25:46 2003 @@ -333,12 +333,10 @@ int rc; /* Register the tape major number to the kernel */ - rc = register_blkdev(tapeblock_major, "tBLK", &tapeblock_fops); - if (rc < 0) { - PRINT_ERR("can't get major %d for block device\n", - tapeblock_major); + rc = register_blkdev(tapeblock_major, "tBLK"); + if (rc < 0) return rc; - } + if (tapeblock_major == 0) tapeblock_major = rc; PRINT_INFO("tape gets major %d for block device\n", tapeblock_major); diff -urN linux-2.5.64-bk3/drivers/sbus/char/jsflash.c linux-2.5.64-bk4/drivers/sbus/char/jsflash.c --- linux-2.5.64-bk3/drivers/sbus/char/jsflash.c Tue Mar 4 19:29:18 2003 +++ linux-2.5.64-bk4/drivers/sbus/char/jsflash.c Mon Mar 31 12:25:46 2003 @@ -570,9 +570,7 @@ jsfd_disk[i] = disk; } - if (register_blkdev(JSFD_MAJOR, "jsfd", &jsfd_fops)) { - printk("jsfd_init: unable to get major number %d\n", - JSFD_MAJOR); + if (register_blkdev(JSFD_MAJOR, "jsfd")) { err = -EIO; goto out; } diff -urN linux-2.5.64-bk3/drivers/scsi/sd.c linux-2.5.64-bk4/drivers/scsi/sd.c --- linux-2.5.64-bk3/drivers/scsi/sd.c Tue Mar 4 19:29:32 2003 +++ linux-2.5.64-bk4/drivers/scsi/sd.c Mon Mar 31 12:25:46 2003 @@ -1389,14 +1389,9 @@ SCSI_LOG_HLQUEUE(3, printk("init_sd: sd driver entry point\n")); - for (i = 0; i < SD_MAJORS; i++) { - if (register_blkdev(sd_major(i), "sd", &sd_fops)) - printk(KERN_NOTICE - "Unable to get major %d for SCSI disk\n", - sd_major(i)); - else + for (i = 0; i < SD_MAJORS; i++) + if (register_blkdev(sd_major(i), "sd") == 0) majors++; - } if (!majors) return -ENODEV; @@ -1409,7 +1404,7 @@ } /** - * exit_sd - exit point for this driver (when it is a module). + * exit_sd - exit point for this driver (when it is a module). * * Note: this function unregisters this driver from the scsi mid-level. **/ diff -urN linux-2.5.64-bk3/drivers/scsi/sr.c linux-2.5.64-bk4/drivers/scsi/sr.c --- linux-2.5.64-bk3/drivers/scsi/sr.c Tue Mar 4 19:29:03 2003 +++ linux-2.5.64-bk4/drivers/scsi/sr.c Mon Mar 31 12:25:46 2003 @@ -835,7 +835,7 @@ { int rc; - rc = register_blkdev(SCSI_CDROM_MAJOR, "sr", &sr_bdops); + rc = register_blkdev(SCSI_CDROM_MAJOR, "sr"); if (rc) return rc; return scsi_register_device(&sr_template); diff -urN linux-2.5.64-bk3/drivers/scsi/sym53c8xx_2/sym_hipd.c linux-2.5.64-bk4/drivers/scsi/sym53c8xx_2/sym_hipd.c --- linux-2.5.64-bk3/drivers/scsi/sym53c8xx_2/sym_hipd.c Tue Mar 4 19:28:53 2003 +++ linux-2.5.64-bk4/drivers/scsi/sym53c8xx_2/sym_hipd.c Mon Mar 31 12:25:46 2003 @@ -221,7 +221,7 @@ */ static void sym_soft_reset (hcb_p np) { - u_char istat; + u_char istat = 0; int i; if (!(np->features & FE_ISTAT1) || !(INB (nc_istat1) & SCRUN)) diff -urN linux-2.5.64-bk3/drivers/serial/8250.c linux-2.5.64-bk4/drivers/serial/8250.c --- linux-2.5.64-bk3/drivers/serial/8250.c Mon Mar 31 12:25:41 2003 +++ linux-2.5.64-bk4/drivers/serial/8250.c Mon Mar 31 12:25:46 2003 @@ -1982,10 +1982,11 @@ .index = -1, }; -static void __init serial8250_console_init(void) +static int __init serial8250_console_init(void) { serial8250_isa_init_ports(); register_console(&serial8250_console); + return 0; } console_initcall(serial8250_console_init); diff -urN linux-2.5.64-bk3/drivers/video/Makefile linux-2.5.64-bk4/drivers/video/Makefile --- linux-2.5.64-bk3/drivers/video/Makefile Tue Mar 4 19:28:58 2003 +++ linux-2.5.64-bk4/drivers/video/Makefile Mon Mar 31 12:25:47 2003 @@ -70,9 +70,6 @@ obj-$(CONFIG_FB_PVR2) += pvr2fb.o obj-$(CONFIG_FB_VOODOO1) += sstfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o -# One by one these are being converted over to the new APIs -#obj-$(CONFIG_FB_LEO) += leofb.o sbusfb.o - obj-$(CONFIG_FB_FFB) += ffb.o sbuslib.o cfbimgblt.o cfbcopyarea.o obj-$(CONFIG_FB_CG6) += cg6.o sbuslib.o cfbimgblt.o cfbcopyarea.o obj-$(CONFIG_FB_CG3) += cg3.o sbuslib.o cfbimgblt.o cfbcopyarea.o \ @@ -85,6 +82,8 @@ cfbfillrect.o obj-$(CONFIG_FB_TCX) += tcx.o sbuslib.o cfbimgblt.o cfbcopyarea.o \ cfbfillrect.o +obj-$(CONFIG_FB_LEO) += leo.o sbuslib.o cfbimgblt.o cfbcopyarea.o \ + cfbfillrect.o # Files generated that shall be removed upon make clean clean-files := promcon_tbl.c diff -urN linux-2.5.64-bk3/drivers/video/fbmem.c linux-2.5.64-bk4/drivers/video/fbmem.c --- linux-2.5.64-bk3/drivers/video/fbmem.c Tue Mar 4 19:28:52 2003 +++ linux-2.5.64-bk4/drivers/video/fbmem.c Mon Mar 31 12:25:47 2003 @@ -158,6 +158,8 @@ extern int p9100_setup(char*); extern int tcx_init(void); extern int tcx_setup(char*); +extern int leo_init(void); +extern int leo_setup(char*); static struct { const char *name; @@ -270,6 +272,9 @@ #ifdef CONFIG_FB_TCX { "tcx", tcx_init, tcx_setup }, #endif +#ifdef CONFIG_FB_LEO + { "leo", leo_init, leo_setup }, +#endif /* * Generic drivers that are used as fallbacks diff -urN linux-2.5.64-bk3/drivers/video/leo.c linux-2.5.64-bk4/drivers/video/leo.c --- linux-2.5.64-bk3/drivers/video/leo.c Wed Dec 31 16:00:00 1969 +++ linux-2.5.64-bk4/drivers/video/leo.c Mon Mar 31 12:25:47 2003 @@ -0,0 +1,587 @@ +/* leo.c: LEO frame buffer driver + * + * Copyright (C) 2003 David S. Miller (davem@redhat.com) + * Copyright (C) 1996-1999 Jakub Jelinek (jj@ultra.linux.cz) + * Copyright (C) 1997 Michal Rehacek (Michal.Rehacek@st.mff.cuni.cz) + * + * Driver layout based loosely on tgafb.c, see that file for credits. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "sbuslib.h" + +/* + * Local functions. + */ + +static int leo_setcolreg(unsigned, unsigned, unsigned, unsigned, + unsigned, struct fb_info *); +static int leo_blank(int, struct fb_info *); + +static int leo_mmap(struct fb_info *, struct file *, struct vm_area_struct *); +static int leo_ioctl(struct inode *, struct file *, unsigned int, + unsigned long, struct fb_info *); + +/* + * Frame buffer operations + */ + +static struct fb_ops leo_ops = { + .owner = THIS_MODULE, + .fb_setcolreg = leo_setcolreg, + .fb_blank = leo_blank, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, + .fb_mmap = leo_mmap, + .fb_ioctl = leo_ioctl, + .fb_cursor = soft_cursor, +}; + +#define LEO_OFF_LC_SS0_KRN 0x00200000UL +#define LEO_OFF_LC_SS0_USR 0x00201000UL +#define LEO_OFF_LC_SS1_KRN 0x01200000UL +#define LEO_OFF_LC_SS1_USR 0x01201000UL +#define LEO_OFF_LD_SS0 0x00400000UL +#define LEO_OFF_LD_SS1 0x01400000UL +#define LEO_OFF_LD_GBL 0x00401000UL +#define LEO_OFF_LX_KRN 0x00600000UL +#define LEO_OFF_LX_CURSOR 0x00601000UL +#define LEO_OFF_SS0 0x00800000UL +#define LEO_OFF_SS1 0x01800000UL +#define LEO_OFF_UNK 0x00602000UL +#define LEO_OFF_UNK2 0x00000000UL + +#define LEO_CUR_ENABLE 0x00000080 +#define LEO_CUR_UPDATE 0x00000030 +#define LEO_CUR_PROGRESS 0x00000006 +#define LEO_CUR_UPDATECMAP 0x00000003 + +#define LEO_CUR_TYPE_MASK 0x00000000 +#define LEO_CUR_TYPE_IMAGE 0x00000020 +#define LEO_CUR_TYPE_CMAP 0x00000050 + +struct leo_cursor { + u8 xxx0[16]; + volatile u32 cur_type; + volatile u32 cur_misc; + volatile u32 cur_cursxy; + volatile u32 cur_data; +}; + +#define LEO_KRN_TYPE_CLUT0 0x00001000 +#define LEO_KRN_TYPE_CLUT1 0x00001001 +#define LEO_KRN_TYPE_CLUT2 0x00001002 +#define LEO_KRN_TYPE_WID 0x00001003 +#define LEO_KRN_TYPE_UNK 0x00001006 +#define LEO_KRN_TYPE_VIDEO 0x00002003 +#define LEO_KRN_TYPE_CLUTDATA 0x00004000 +#define LEO_KRN_CSR_ENABLE 0x00000008 +#define LEO_KRN_CSR_PROGRESS 0x00000004 +#define LEO_KRN_CSR_UNK 0x00000002 +#define LEO_KRN_CSR_UNK2 0x00000001 + +struct leo_lx_krn { + volatile u32 krn_type; + volatile u32 krn_csr; + volatile u32 krn_value; +}; + +struct leo_lc_ss0_krn { + volatile u32 misc; + u8 xxx0[0x800-4]; + volatile u32 rev; +}; + +struct leo_lc_ss0_usr { + volatile u32 csr; + volatile u32 addrspace; + volatile u32 fontmsk; + volatile u32 fontt; + volatile u32 extent; + volatile u32 src; + u32 dst; + volatile u32 copy; + volatile u32 fill; +}; + +struct leo_lc_ss1_krn { + u8 unknown; +}; + +struct leo_lc_ss1_usr { + u8 unknown; +}; + +struct leo_ld { + u8 xxx0[0xe00]; + volatile u32 csr; + volatile u32 wid; + volatile u32 wmask; + volatile u32 widclip; + volatile u32 vclipmin; + volatile u32 vclipmax; + volatile u32 pickmin; /* SS1 only */ + volatile u32 pickmax; /* SS1 only */ + volatile u32 fg; + volatile u32 bg; + volatile u32 src; /* Copy/Scroll (SS0 only) */ + volatile u32 dst; /* Copy/Scroll/Fill (SS0 only) */ + volatile u32 extent; /* Copy/Scroll/Fill size (SS0 only) */ + u32 xxx1[3]; + volatile u32 setsem; /* SS1 only */ + volatile u32 clrsem; /* SS1 only */ + volatile u32 clrpick; /* SS1 only */ + volatile u32 clrdat; /* SS1 only */ + volatile u32 alpha; /* SS1 only */ + u8 xxx2[0x2c]; + volatile u32 winbg; + volatile u32 planemask; + volatile u32 rop; + volatile u32 z; + volatile u32 dczf; /* SS1 only */ + volatile u32 dczb; /* SS1 only */ + volatile u32 dcs; /* SS1 only */ + volatile u32 dczs; /* SS1 only */ + volatile u32 pickfb; /* SS1 only */ + volatile u32 pickbb; /* SS1 only */ + volatile u32 dcfc; /* SS1 only */ + volatile u32 forcecol; /* SS1 only */ + volatile u32 door[8]; /* SS1 only */ + volatile u32 pick[5]; /* SS1 only */ +}; + +#define LEO_SS1_MISC_ENABLE 0x00000001 +#define LEO_SS1_MISC_STEREO 0x00000002 +struct leo_ld_ss1 { + u8 xxx0[0xef4]; + volatile u32 ss1_misc; +}; + +struct leo_ld_gbl { + u8 unknown; +}; + +struct leo_par { + spinlock_t lock; + struct leo_lx_krn *lx_krn; + struct leo_lc_ss0_usr *lc_ss0_usr; + struct leo_ld_ss0 *ld_ss0; + struct leo_ld_ss1 *ld_ss1; + struct leo_cursor *cursor; + u32 extent; + u32 clut_data[256]; + + u32 flags; +#define LEO_FLAG_BLANKED 0x00000001 + + unsigned long physbase; + unsigned long fbsize; + + struct sbus_dev *sdev; + struct list_head list; +}; + +static void leo_wait(struct leo_lx_krn *lx_krn) +{ + int i; + + for (i = 0; + (sbus_readl(&lx_krn->krn_csr) & LEO_KRN_CSR_PROGRESS) && i < 300000; + i++) + udelay (1); /* Busy wait at most 0.3 sec */ + return; +} + +/** + * leo_setcolreg - Optional function. Sets a color register. + * @regno: boolean, 0 copy local, 1 get_user() function + * @red: frame buffer colormap structure + * @green: The green value which can be up to 16 bits wide + * @blue: The blue value which can be up to 16 bits wide. + * @transp: If supported the alpha value which can be up to 16 bits wide. + * @info: frame buffer info structure + */ +static int leo_setcolreg(unsigned regno, + unsigned red, unsigned green, unsigned blue, + unsigned transp, struct fb_info *info) +{ + struct leo_par *par = (struct leo_par *) info->par; + struct leo_lx_krn *lx_krn = par->lx_krn; + unsigned long flags; + u32 val; + int i; + + if (regno >= 256) + return 1; + + red >>= 8; + green >>= 8; + blue >>= 8; + + par->clut_data[regno] = red | (green << 8) | (blue << 16); + + spin_lock_irqsave(&par->lock, flags); + + leo_wait(lx_krn); + + sbus_writel(LEO_KRN_TYPE_CLUTDATA, &lx_krn->krn_type); + for (i = 0; i < 256; i++) + sbus_writel(par->clut_data[i], &lx_krn->krn_value); + sbus_writel(LEO_KRN_TYPE_CLUT0, &lx_krn->krn_type); + + val = sbus_readl(&lx_krn->krn_csr); + val |= (LEO_KRN_CSR_UNK | LEO_KRN_CSR_UNK2); + sbus_writel(val, &lx_krn->krn_csr); + + spin_unlock_irqrestore(&par->lock, flags); + + return 0; +} + +/** + * leo_blank - Optional function. Blanks the display. + * @blank_mode: the blank mode we want. + * @info: frame buffer structure that represents a single frame buffer + */ +static int leo_blank(int blank, struct fb_info *info) +{ + struct leo_par *par = (struct leo_par *) info->par; + struct leo_lx_krn *lx_krn = par->lx_krn; + unsigned long flags; + u32 val; + + spin_lock_irqsave(&par->lock, flags); + + switch (blank) { + case 0: /* Unblanking */ + val = sbus_readl(&lx_krn->krn_csr); + val |= LEO_KRN_CSR_ENABLE; + sbus_writel(val, &lx_krn->krn_csr); + par->flags &= ~LEO_FLAG_BLANKED; + break; + + case 1: /* Normal blanking */ + case 2: /* VESA blank (vsync off) */ + case 3: /* VESA blank (hsync off) */ + case 4: /* Poweroff */ + val = sbus_readl(&lx_krn->krn_csr); + val &= ~LEO_KRN_CSR_ENABLE; + sbus_writel(val, &lx_krn->krn_csr); + par->flags |= LEO_FLAG_BLANKED; + break; + } + + spin_unlock_irqrestore(&par->lock, flags); + + return 0; +} + +static struct sbus_mmap_map leo_mmap_map[] = { + { LEO_SS0_MAP, LEO_OFF_SS0, 0x800000 }, + { LEO_LC_SS0_USR_MAP, LEO_OFF_LC_SS0_USR, 0x1000 }, + { LEO_LD_SS0_MAP, LEO_OFF_LD_SS0, 0x1000 }, + { LEO_LX_CURSOR_MAP, LEO_OFF_LX_CURSOR, 0x1000 }, + { LEO_SS1_MAP, LEO_OFF_SS1, 0x800000 }, + { LEO_LC_SS1_USR_MAP, LEO_OFF_LC_SS1_USR, 0x1000 }, + { LEO_LD_SS1_MAP, LEO_OFF_LD_SS1, 0x1000 }, + { LEO_UNK_MAP, LEO_OFF_UNK, 0x1000 }, + { LEO_LX_KRN_MAP, LEO_OFF_LX_KRN, 0x1000 }, + { LEO_LC_SS0_KRN_MAP, LEO_OFF_LC_SS0_KRN, 0x1000 }, + { LEO_LC_SS1_KRN_MAP, LEO_OFF_LC_SS1_KRN, 0x1000 }, + { LEO_LD_GBL_MAP, LEO_OFF_LD_GBL, 0x1000 }, + { LEO_UNK2_MAP, LEO_OFF_UNK2, 0x100000 }, + { 0, 0, 0 } +}; + +static int leo_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma) +{ + struct leo_par *par = (struct leo_par *)info->par; + + return sbusfb_mmap_helper(leo_mmap_map, + par->physbase, par->fbsize, + par->sdev->reg_addrs[0].which_io, + vma); +} + +static int leo_ioctl(struct inode *inode, struct file *file, unsigned int cmd, + unsigned long arg, struct fb_info *info) +{ + struct leo_par *par = (struct leo_par *) info->par; + + return sbusfb_ioctl_helper(cmd, arg, info, + FBTYPE_SUNLEO, 32, par->fbsize); +} + +/* + * Initialisation + */ + +static void +leo_init_fix(struct fb_info *info) +{ + struct leo_par *par = (struct leo_par *)info->par; + + strncpy(info->fix.id, par->sdev->prom_name, sizeof(info->fix.id) - 1); + info->fix.id[sizeof(info->fix.id)-1] = 0; + + info->fix.type = FB_TYPE_PACKED_PIXELS; + info->fix.visual = FB_VISUAL_TRUECOLOR; + + info->fix.line_length = 8192; + + info->fix.accel = FB_ACCEL_SUN_LEO; +} + +static void leo_wid_put(struct fb_info *info, struct fb_wid_list *wl) +{ + struct leo_par *par = (struct leo_par *) info->par; + struct leo_lx_krn *lx_krn = par->lx_krn; + struct fb_wid_item *wi; + unsigned long flags; + u32 val; + int i, j; + + spin_lock_irqsave(&par->lock, flags); + + leo_wait(lx_krn); + + for (i = 0, wi = wl->wl_list; i < wl->wl_count; i++, wi++) { + switch(wi->wi_type) { + case FB_WID_DBL_8: + j = (wi->wi_index & 0xf) + 0x40; + break; + + case FB_WID_DBL_24: + j = wi->wi_index & 0x3f; + break; + + default: + continue; + }; + sbus_writel(0x5800 + j, &lx_krn->krn_type); + sbus_writel(wi->wi_values[0], &lx_krn->krn_value); + } + sbus_writel(LEO_KRN_TYPE_WID, &lx_krn->krn_type); + + val = sbus_readl(&lx_krn->krn_csr); + val |= (LEO_KRN_CSR_UNK | LEO_KRN_CSR_UNK2); + sbus_writel(val, &lx_krn->krn_csr); + + spin_unlock_irqrestore(&par->lock, flags); +} + +static void leo_init_wids(struct fb_info *info) +{ + struct fb_wid_item wi; + struct fb_wid_list wl; + + wl.wl_count = 1; + wl.wl_list = &wi; + wi.wi_type = FB_WID_DBL_8; + wi.wi_index = 0; + wi.wi_values [0] = 0x2c0; + leo_wid_put(info, &wl); + wi.wi_index = 1; + wi.wi_values [0] = 0x30; + leo_wid_put(info, &wl); + wi.wi_index = 2; + wi.wi_values [0] = 0x20; + leo_wid_put(info, &wl); + wi.wi_type = FB_WID_DBL_24; + wi.wi_index = 1; + wi.wi_values [0] = 0x30; + leo_wid_put(info, &wl); + +} + +static void leo_init_hw(struct fb_info *info) +{ + struct leo_par *par = (struct leo_par *) info->par; + struct leo_ld *ss = (struct leo_ld *) par->ld_ss0; + u32 val; + + val = sbus_readl(&par->ld_ss1->ss1_misc); + val |= LEO_SS1_MISC_ENABLE; + sbus_writel(val, &par->ld_ss1->ss1_misc); + + par->extent = ((info->var.xres - 1) | + ((info->var.yres - 1) << 16)); + + sbus_writel(0xffffffff, &ss->wid); + sbus_writel(0xffff, &ss->wmask); + sbus_writel(0, &ss->vclipmin); + sbus_writel(par->extent, &ss->vclipmax); + sbus_writel(0, &ss->fg); + sbus_writel(0xff000000, &ss->planemask); + sbus_writel(0x310850, &ss->rop); + sbus_writel(0, &ss->widclip); + sbus_writel((info->var.xres-1) | ((info->var.yres-1) << 11), + &par->lc_ss0_usr->extent); + sbus_writel(4, &par->lc_ss0_usr->addrspace); + sbus_writel(0x80000000, &par->lc_ss0_usr->fill); + sbus_writel(0, &par->lc_ss0_usr->fontt); + do { + val = sbus_readl(&par->lc_ss0_usr->csr); + } while (val & 0x20000000); +} + +static void leo_fixup_var_rgb(struct fb_var_screeninfo *var) +{ + var->red.offset = 0; + var->red.length = 8; + var->green.offset = 8; + var->green.length = 8; + var->blue.offset = 16; + var->blue.length = 8; + var->transp.offset = 0; + var->transp.length = 0; +} + +struct all_info { + struct fb_info info; + struct leo_par par; + struct list_head list; +}; +static LIST_HEAD(leo_list); + +static void leo_init_one(struct sbus_dev *sdev) +{ + struct all_info *all; + int linebytes; + + all = kmalloc(sizeof(*all), GFP_KERNEL); + if (!all) { + printk(KERN_ERR "leo: Cannot allocate memory.\n"); + return; + } + memset(all, 0, sizeof(*all)); + + INIT_LIST_HEAD(&all->list); + + spin_lock_init(&all->par.lock); + all->par.sdev = sdev; + + all->par.physbase = sdev->reg_addrs[0].phys_addr; + + sbusfb_fill_var(&all->info.var, sdev->prom_node, 32); + leo_fixup_var_rgb(&all->info.var); + + linebytes = prom_getintdefault(sdev->prom_node, "linebytes", + all->info.var.xres); + all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); + +#ifdef CONFIG_SPARC32 + all->info.screen_base = (char *) + prom_getintdefault(sdev->prom_node, "address", 0); +#endif + if (!all->info.screen_base) + all->info.screen_base = (char *) + sbus_ioremap(&sdev->resource[0], LEO_OFF_SS0, + 0x800000, "leo ram"); + + all->par.lc_ss0_usr = (struct leo_lc_ss0_usr *) + sbus_ioremap(&sdev->resource[0], LEO_OFF_LC_SS0_USR, + 0x1000, "leolc ss0usr"); + all->par.ld_ss0 = (struct leo_ld_ss0 *) + sbus_ioremap(&sdev->resource[0], LEO_OFF_LD_SS0, + 0x1000, "leold ss0"); + all->par.ld_ss1 = (struct leo_ld_ss1 *) + sbus_ioremap(&sdev->resource[0], LEO_OFF_LD_SS1, + 0x1000, "leold ss1"); + all->par.lx_krn = (struct leo_lx_krn *) + sbus_ioremap(&sdev->resource[0], LEO_OFF_LX_KRN, + 0x1000, "leolx krn"); + all->par.cursor = (struct leo_cursor *) + sbus_ioremap(&sdev->resource[0], LEO_OFF_LX_CURSOR, + sizeof(struct leo_cursor), "leolx cursor"); + + all->info.node = NODEV; + all->info.flags = FBINFO_FLAG_DEFAULT; + all->info.fbops = &leo_ops; + all->info.currcon = -1; + all->info.par = &all->par; + + leo_init_wids(&all->info); + leo_init_hw(&all->info); + + leo_blank(0, &all->info); + + if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { + printk(KERN_ERR "leo: Could not allocate color map.\n"); + kfree(all); + return; + } + + leo_init_fix(&all->info); + + if (register_framebuffer(&all->info) < 0) { + printk(KERN_ERR "leo: Could not register framebuffer.\n"); + fb_dealloc_cmap(&all->info.cmap); + kfree(all); + return; + } + + list_add(&all->list, &leo_list); + + printk("leo: %s at %lx:%lx\n", + sdev->prom_name, + (long) sdev->reg_addrs[0].which_io, + (long) sdev->reg_addrs[0].phys_addr); +} + +int __init leo_init(void) +{ + struct sbus_bus *sbus; + struct sbus_dev *sdev; + + for_all_sbusdev(sdev, sbus) { + if (!strcmp(sdev->prom_name, "leo")) + leo_init_one(sdev); + } + + return 0; +} + +void __exit leo_exit(void) +{ + struct list_head *pos, *tmp; + + list_for_each_safe(pos, tmp, &leo_list) { + struct all_info *all = list_entry(pos, typeof(*all), list); + + unregister_framebuffer(&all->info); + fb_dealloc_cmap(&all->info.cmap); + kfree(all); + } +} + +int __init +leo_setup(char *arg) +{ + /* No cmdline options yet... */ + return 0; +} + +#ifdef MODULE +module_init(leo_init); +module_exit(leo_exit); +#endif + +MODULE_DESCRIPTION("framebuffer driver for LEO chipsets"); +MODULE_AUTHOR("David S. Miller "); +MODULE_LICENSE("GPL"); diff -urN linux-2.5.64-bk3/drivers/video/leofb.c linux-2.5.64-bk4/drivers/video/leofb.c --- linux-2.5.64-bk3/drivers/video/leofb.c Tue Mar 4 19:29:56 2003 +++ linux-2.5.64-bk4/drivers/video/leofb.c Wed Dec 31 16:00:00 1969 @@ -1,764 +0,0 @@ -/* $Id: leofb.c,v 1.14 2001/10/16 05:44:44 davem Exp $ - * leofb.c: Leo (ZX) 24/8bit frame buffer driver - * - * Copyright (C) 1996-1999 Jakub Jelinek (jj@ultra.linux.cz) - * Copyright (C) 1997 Michal Rehacek (Michal.Rehacek@st.mff.cuni.cz) - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include